I want to move my robot a set number of steps and then have it stop. However the loop just seems to run on infinitely. Is there a mistake in the way that I am using void loop() or perhaps in the way that I have written my 'for' loop?
// walkerForward.pde - Two servo walker. Forward.
// (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
// updated - Joe Saavedra, 2010
#include <Servo.h>
Servo frontServo;
Servo rearServo;
int centerPos = 90;
int frontRightUp = 75;
int frontLeftUp = 120;
int backRightForward = 45;
int backLeftForward = 135;
void moveForward(int steps)
{
for (int x = steps; steps > 0; steps--) {
frontServo.write(centerPos);
rearServo.write(centerPos);
delay(100);
frontServo.write(frontRightUp);
rearServo.write(backLeftForward);
delay(100);
frontServo.write(centerPos);
rearServo.write(centerPos);
delay(100);
frontServo.write(frontLeftUp);
rearServo.write(backRightForward);
delay(100);
}
}
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
}
void loop()
{
moveForward(5);
}
the loop() function is executed within an infinite loop (if you check the main cpp file that ships with the Arduino IDE, you'll see something like this:
int main()
{
setup();
for (;;) {
loop();
}
return 0;
}
So either put the call to your moveForward() function to setup() and make loop() an empty function, or call exit(0); from within loop() after moveForward(). The first approach looks like this:
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
moveForward(5);
}
void loop()
{
}
And the second one looks like this:
void setup()
{
frontServo.attach(2);
rearServo.attach(3);
}
void loop()
{
moveForward(5);
exit(0);
}
Since you probably will want to eventually do more than move the robot just 5 steps, I'd suggest using a variable flag to hold the robot state. It only executes the movement routine when the flag has been set to true.
If you are using serial, when a move command is received (and the number of steps, direction perhaps?) you set the flag to true and then issue the move command. If you are using sensors or buttons, the same logic applies.
You will need some logic to handle an incoming movement command while a movement is occurring (though with your tight movement loop you actually won't be able to respond to incoming commands unless you use interrupts - but you want to consider this sort of thing if you are planning to build out a full movement bit of firmware).
boolean shouldMove;
void setup()
{
shouldMove = true;//set the flag
}
void loop()
{
if (shouldMove){
moveForward(5);
}
}
void moveForward(int steps)
{
shouldMove = false; //clear the flag
for (int x = steps; steps > 0; steps--) {
// tight loop controlling movement
}
}
}
Related
I'm doing a code where the timer gets triggered by a pushbutton. The problem is that nothing happens, the serial monitor doesn't show anything. I've checked all of the connections and there is no errors in the electronic components. I'm not sure what is wrong.
Thankyou
Here's the code:
int timer;
const int starttrigger = 2;
const int endtrigger = 4;
void setup() {
pinMode(starttrigger, INPUT);
pinMode(endtrigger, INPUT);
pinMode(redled, OUTPUT);
pinMode(greenled, OUTPUT);
}
void loop() {
int start_button_state = digitalRead(starttrigger);
int end_button_state = digitalRead(endtrigger);
if (start_button_state == HIGH) {
while (end_button_state == LOW){
for(timer = 0; end_button_state == HIGH; timer ++) {
Serial.println(timer);
}
}
}
}
You do not see anything in the serial monitor because you have not activating Serial communication in the first place. It needs to be done in the void setup() function.
Please add this line to your void setup function
Serial.begin(9600);
I'm in a pickle regarding concepts relating to timers. How can I can I operate a "delay" inside a timer? This is the best way I can frame the question knowing full well what I'm trying to do is nonsense. The objective is: I wish to test the pinState condition 2 times (once initially and then 4 seconds later) but this all needs to happen periodically (hence a timer).
The platform is NodeMCU running a WiFi (ESP8266 chip) and coding done inside Arduino IDE.
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;
char auth[] = "x"; //Auth code sent via Email
char ssid[] = "x"; //Wifi name
char pass[] = "x"; //Wifi Password
int flag=0;
void notifyOnFire()
{
int pinState = digitalRead(D1);
if (pinState==0 && flag==0) {
delay(4000);
int pinStateAgain = digitalRead(D1);
if (pinStateAgain==0) {
Serial.println("Alarm has gone off");
Blynk.notify("House Alarm!!!");
flag=1;
}
}
else if (pinState==1)
{
flag=0;
}
}
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
pinMode(D1,INPUT_PULLUP);
timer.setInterval(1000L,notifyOnFire);
}
void loop()
{
//Serial.println(WiFi.localIP());
Blynk.run();
timer.run();
}
an easy fix would be to set the periodicity of the timer to be 4000L timer.setInterval(4000L,notifyOnFire); and in notifyOnFire use a static variable and toggle its value whenever notifyOnFire is called
void notifyOnFire()
{
static char state = 0;
if( state == 0)
{
/* Write here the code you need to be executed before the 4 sec delay */
state = 1;
}
else
{
/* Write here the code you need to be executed after the 4 sec delay */
state = 0;
}
}
The nice thing about static variables is that they are initialized only once at compile time and they retain their values after the scope of code changes (In this case function notifyOnFire exits).
I am using Arduino Uno, I try to run servo constantly from 0 to 45 degrees when the interrupt button is pressed it should go to -30 degree and wait here. When the same button is pressed again, it should resume the constant action, which is swiping 0 to 45 degrees without <servo.h> library.
I tried to run like this:
const int servo = 11;
const int led = 13;
const int buttonPin = 2;
volatile int buttonState = 1;
void setup() {
Serial.begin(57600);
pinMode(led, OUTPUT);
pinMode(servo, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin),Button,CHANGE);
}
void loop() {
digitalWrite(led,HIGH);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1500);
digitalWrite(servo,LOW);
delayMicroseconds(18500);
}
delay(2000);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1000);
digitalWrite(servo,LOW);
delayMicroseconds(19000);
}
delay(2000);
}
void Button()
{
digitalWrite(led,LOW);
for(int i=0;i<30;i++)
{
digitalWrite(servo,HIGH);
delayMicroseconds(1833);
digitalWrite(servo,LOW);
delayMicroseconds(18167);
}
}
I have no problem coding my own PWM for each case but it turns out, the problem is a bit complicated than I was expecting because when we try to resume, I need to disable the interrupt function when pressing the same an interrupt button somehow.
Is it possible in this way or is there a better way to implement it?
const int buttonPin = 2;
int buttonState = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
Serial.println("1");
buttonState=LOW;
delay(20000);
while(0);
}
}
Basically the code works like this:
the number of the pushbutton pin
variable for reading the pushbutton status
initialize the pushbutton pin as an input:
read the state of the pushbutton value:
check if the pushbutton is pressed. If it is, the buttonState is HIGH:
send char 1 via Bluetooth:
I have an Arduino, HC 06 bluetooth module, a button and an app that makes a phonecall when the button is pressed (HC 06 send a byte, 1, to the app)
My question is, what's the while (0); for?
----ORIGINAL CODE----
const int PirSensor = 2;
int motionState = 0;
void setup() {
Serial.begin(9600);
pinMode(PirSensor, INPUT);
}
void loop() {
motionState = digitalRead(PirSensor);
if (motionState == HIGH) {
Serial.println("1");
motionState = LOW;
delay(20000);
// while(0);
}
}
Well if I am not mistaken in this case nothing.
In most computer programming languages, a while loop is a control flow statement that allows code to be executed repeatedly based on a given Boolean condition. The while loop can be thought of as a repeating if statement.
Note that if you do have a condition, a while loop must have an exit option, like this:
const int buttonPin = 2;
int buttonState = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
Serial.println("1");
buttonState=LOW;
delay(20000);
int a =0;
while(a==0){
if (something)
a=1;
}
}
}
Then on your chosen condition you will exit the loop.
while(0) is most commonly used in macro definitions, specifically in those which are meant to be used like void functions or other instructions, like
#define inc(x) do { x = ((x)+1); } while (0)
The reason to use it is simply to make the use of the macro look like an invocation of a function by forcing the user to append a ; to the macro invocation. In the above example,
inc(a)
a = a*2;
would cause a compile error due to the missing ; after the while(0) the macro expands to, so you have to write
inc(a);
a = a*2;
which makes the code look more like inc was a function. Also, embedding the macro's code in a loop like this helps in preventing accidental use of the macro as an expression, akin to a void function. ( a = ((a)+1) is a valid expression, so b = inc(a) would be valid too (expands to b = a = ((a)+1)) if the macro did not contain the (semantically irrelevant) while loop.)
I need some help with my arduino ramp motor code.
I am making a remote control robot. The remote has one button.
If the button is high: The motor should gradually increase its speed using pwm (Starting with pwm=0).The time period from standstill speed to maximum speed should be 1 second. Once it has reached maximum speed it should maintain the maximum speed (pwm=255).
The moment the button is released the motor should gradually decrease from the current speed to a complete standstill.
So far I have managed to write the ramp up and maintain speed part of the code; the code doesn't include the button part.
int motor;
int motorpwm=11;
int x=1;
int i;
void setup()
{
pinMode(11,OUTPUT);
Serial.begin(9600);
}
void loop()
{
for(int i=0;i<256;i=i+x)
{
analogWrite(motorpwm,i);
Serial.println(i);
if(i==255)
{
x=0;
Serial.println("PWM is maximum");
}
}
}
Please include the complete code including the button control part of the code.
I do not assure you if this is bug-free but you can try this and post your restults here, so that I can debug it for you. Here you go:
int motor;
int motorpwm = 11;
int x = 1;
int i;
int pwmValue;
void setup()
{
pinMode(11, OUTPUT);
pinMode(2, INPUT); //Button connected to Vcc and pulled down using a 10k resistor.
Serial.begin(9600);
}
void loop()
{
if (digitalRead(2)) //if button is pressed it will read High signal
{
if (pwmValue <= 255)
{
analogWrite(motorpwm, pwmValue++);
Serial.print("Going Up with value: ");
Serial.println(pwmValue);
}
else
{
Serial.println("PWM is maximum");
}
}
else
{
if (motorpwm > 0)
{
analogWrite(motorpwm, pwmValue--);
Serial.print("Going down with value: ");
Serial.print(pwmValue);
}
else
{
Serial.println("PWM is minimum");
}
}
}