Recently I have been working on a project where the main goal is to move a servo on a model rocket to deploy a parachute. I want to make is so that 10 seconds after I press the button the parachute is released. I have some code for this already but It is not working, as it stops the code completely. Does anyone know how to fix this?
#include <Servo.h>
// constants won't change
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int SERVO_PIN = 9; // Arduino pin connected to servo motor's pin
Servo servo; // create servo object to control a servo
// variables will change:
int angle = 0; // the current angle of servo motor
int lastButtonState; // the previous state of button
int currentButtonState; // the current state of button
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
servo.attach(SERVO_PIN); // attaches the servo on pin 9 to the servo object
servo.write(angle);
currentButtonState = digitalRead(BUTTON_PIN);
}
void loop() {
lastButtonState = currentButtonState; // save the last state
currentButtonState = digitalRead(BUTTON_PIN); // read new state
if(lastButtonState == HIGH && currentButtonState == LOW) {
Serial.println("The button is pressed");
time.delay(10000)
// change angle of servo motor
if(angle == 0)
angle = 90;
else
if(angle == 90)
angle = 0;
// control servo motor arccoding to the angle
servo.write(angle);
}
}
In Arduino, a delay is usually done with delay(10000); (for 10 seconds). I've never seen or heard of the time.delay() function, so that might be the issue. Otherwise the code looks like it should work as you want.
It also might depend on the board you're running it on. I remember having issues using delay() for long periods on an ESP8266 although I'm pretty sure that it is fine for tens of seconds.
Related
My goal is to create a small switch panel for my Windows 10 PC. I'm using an Arduino Micro to run my program. I want to use a digital rotary encoder to control Joystick inputs. I want to control volume by pressing volume up when I turn the encoder clockwise, and volume down when I turn it counterclockwise
#include <Joystick.h>
#define outputA 2
#define outputB 3
int counter = 0;
int aState;
int aLastState;
void setup() {
Joystick.begin();
pinMode(2, INPUT);
pinMode(3, INPUT);
}
void loop() {
aState = digitalRead(outputA);
if (aState != aLastState) {
if (digitalRead(outputB) != aState) { // Clockwise
Joystick.pressButton(1);
delay(10);
Joystick.releaseButton(1);
counter ++;
} else { // Counterclockwise
Joystick.pressButton(2);
delay(10);
Joystick.releaseButton(2);
counter --;
}
Serial.print("Counter: ");
Serial.println(counter);
}
aLastState = aState;
}
This should press a button (button 1) every time the pins are pushed clockwise, and press button 2 when they are moving counterclockwise. I have tried to make the counter value print out to the serial monitor to see what it was doing, but the monitor changes at random moments and doesn't recognize the rotary encoder. I can clarify any points of this, but I was wondering what I could fix.
It turns out that this was just an interference issue. Using pullup resistors fixed the problem.
I saw many many videos on pwn and servo motor coding but can't understand how exactly the servo motor code works in arduino.
my main confusion is what is the exact purpose of delay in the below code.
when we say servo.write(180); doesn't it mean go to 180 degrees?
what is the use of the delay here?
some milliseconds cause the servo to work properly or jitter or vibrate not move or incorrect rotations etc.
include
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
The code attempts to get the servo to move relatively slowly from 0 to 180 degrees. 10 ms times 181 steps equals 1.81 seconds.
Most if not all servos are significantly faster than that if you just move straight from 0 to 180 in one go.
One problem with this code is that you don't know what the servo's initial position is. For instance, if the initial position is 180, it will quickly jump to 0 and then slowly move back to 180.
Also note that most servos are controlled with a signal every 20 ms or so, so changing the signal more often than that could lead to problems (like jitter/vibrations/noise/...).
I'm a newbie to Arduino. The goal is to write a program that can stop a hypothetical conveyor belt (read a servo motor) if too many objects are stacked on a belt, that is detected by HC-S04 sensor. If the the distance exceeds the minimum threshold value (1000), then the motor can freely spin. If not, it should stop. With the code below, I get a servo motor to spin regardless of whether an object is in front of it or not.
Tried taking out and changing the delay. It just was spinning faster or slower, but still ignored obstacle distance. Tried commenting sensorValue = map(sensorValue, 0, 255, 0, 4000); but it didn't affect the result.
#include <Servo.h>
#include <Wire.h>
Servo servo;
const int trigPin= 9;
const int echoPin= 10;
const int threshold = 1000;
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin,INPUT);
Serial.begin(9600);
servo.attach(8);
}
void loop() {
int sensorValue = digitalRead(echoPin);
sensorValue = map(sensorValue, 0, 255, 0, 4000);
if (sensorValue >= threshold) {
digitalWrite(8,HIGH);
delay(10);
}
else {
digitalWrite(8,LOW);
delay(10);
}
}
Debug by outputting your sensorValue contents - this will allow you to check which branch is triggered.
(can't post as a comment because my rep is not high enough).
You can use the debugging values to check, configure and calibrate your sensor.
I'm back with another non-homework related question. I'm playing with an arduino with my brother, and we're trying to attach a button so that when its pressed, his sensor stays on and does what it has to do. When its pressed again it'll do nothing and turn off. Right now when the button is held down it stays on, but when its unpressed it stays off. We're trying to make something that'll continuously take pictures when its thrown off a building. It'll stop with the ultra-sonic sensor reads <= 5. I can't throw myself off the roof top while holding the button XD It's a 2 pin button. Here's the code of what we have right now:
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
const int buzzer = 11;
const int ledPin = 13;
const int buttonPin = 2;
// defines variables
long duration;
int distance;
int safetyDistance;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
pinMode(echoPin, INPUT);// Sets the echoPin as an Input
pinMode(buttonPin, INPUT);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(buzzer, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // Starts the serial communication
myservo.attach(8); // attaches the servo on pin 9 to the servo object
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(buttonPin, HIGH);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
safetyDistance = distance;
if (digitalRead(buttonPin) == HIGH)
{
if (safetyDistance <= 5){
digitalWrite(buzzer, HIGH);
digitalWrite(ledPin, HIGH);
}
else{
digitalWrite(buzzer, LOW);
digitalWrite(ledPin, LOW);
for(pos = 0; pos <= 180; pos += 20) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=0; pos-=2) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
}
}
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
}
Now, what we're having trouble with is, I understand that there has to be states for the button. But as we were scouring the internet for help we came across terms like debouncing and we just don't understand what that means. We're so close to finally finishing our mini project. The servo is moving fine, the ultrasonic sensor works well. We just need help figuring out this button. Any advice and help would be appreciated as we're both scratching our heads on this one. Thank you!!
--Zane
Normal buttons, like they are used in most project, are doing nothing else but pressing two electrical contacts together, when it is pressed. But - because it's a mechanical action with limited velocity - the level on the pin doesn't simply rise from LOW to HIGH (or vice versa). Instead it changes it's level in the moment the button gets pressed a few times, until the final level is reached. This variation is to fast for a human to see (for example with an attached LED), but slow enough for a microcontroller like the arduino taking notice. So often you have to make sure, that it's really only one button press, even if the level changes a few times in a row. Mostly it is sufficient to add a small timeout, where the button presses aren't recognized by your code (for example 50 ms), or checking a second time for the state of the button after this period. You can check the corresponding Arduino page for an official example of debouncing.
In your code you are only checking directly the state of the button, which is why it turns off, when you release the button. I would try something like this:
boolean program_state = false;
unsigned long debounce_time = 50;
unsigned long debounce_time_stamp=0;
void loop(){
// ultasound measuring code
if(digitalRead(buttonPin) && debounce_time_stamp - millis() > debounce_time){
program_state=!program_state;
debounce_time_stamp = millis();
}
if(program_state){
// distance checking and servo code
}
}
This check - when the button is pressed - if enough time has been bygone since the last recognized press (the amount of time can be adjusted with the variable debounce_time). When a valid press is recognized, the program_state variable is toggled to change the state between the two modes (On and Off).
Notice that with this the code is unresponsive for the time the servo needs to finish one sequence. If you want to have code, that is more responsive, you should consider using the button as an external interrupt (for this look at the examples on the correspondig Arduino page).
I want to use Arduino to control a stepper motor and catch the feedback. After my upper computer catch the feedback there is other work to do after the stepper motor has rotated. The code is as below:
int x;
void setup() {
Serial.begin(9600);
pinMode(5,OUTPUT); // Step
pinMode(4,OUTPUT); // Dir
}
void loop() {
digitalWrite(4,LOW);
for(x = 0; x < 3200; x++) // Loop 3200 times
{
digitalWrite(5,HIGH); // Output high
delayMicroseconds(400);
digitalWrite(5,LOW); // Output low
delayMicroseconds(400);
}
Serial.println("ok");
delay(1000);
}
But before the stepper motor rotate, the upper computer has already received the feedback of "ok". How can I improve my code.