Arduino code help?
I'm really new to the arduino and I'm struggling to get this code working. I'm trying to have a servo continuously go back and forth until I change its state, which result on the servo to stop at its current position. However, it gets stuck on that for loop and i can't change its state. I assume this is caused by the delay, but I am not sure how to make it so it works without delays, unless there is another way.My code is right here:
{edited}
const int Button = 2; //This is interrupt 0
int Pos;
const int button2=14;
volatile int sweep = HIGH; //Our state variable, initialise so we always sweep
#include <Servo.h>
Servo servo1;
int buttoncount=1;
int lastbuttonstate=0;
const int led_1=7;
void setup()
{
servo1.attach(10);
pinMode(Button, INPUT);
pinMode(button2,INPUT);
pinMode(led_1,OUTPUT);
Serial.begin(9600);
attachInterrupt(0, Isweep, CHANGE);
}
void loop()
{
Serial.println(buttoncount);
switch(buttoncount){
case 1:
servo1.write(0);
digitalWrite(led_1, LOW);
break;
case 2:
Pos=0;
while (Pos<180 & sweep==true)
{servo1.write (Pos);
Pos++;
delay(10);
}
while (Pos>0 & sweep==true)
{servo1.write(Pos);
Pos--;
delay(10);
}
break;
case 3:
digitalWrite(led_1,HIGH);
break;
default:
Serial.println("error");
}
//both these whiles will terminate and not do anything if sweep is true.
}
void Isweep() //Interrupt routine
{
int buttonstate=digitalRead(Button);
if (buttonstate !=lastbuttonstate){
if (buttonstate==HIGH){
buttoncount++;
}
}
lastbuttonstate=buttonstate;
if (buttoncount==4){
buttoncount=1;
}
sweep = !sweep;
while (digitalRead(Button)==true); //change state only once when button is pressed
}
Discussions
Best Answer 6 years ago
What's the point of buttoncount ?
Answer 6 years ago
I need to change the switch case with a button, and the way i know it involves making a button counter.
Answer 6 years ago
The state is either sweeping or fixed. If the button has been pressed, its fixed. What stops the servo being fixed ? Another press ?
Answer 6 years ago
if it worked, that is what I want it to do. I tried using breaks on the for loop and using a if(digitalRead(button)==HIGH){break;}
but that ended up being buggy and weird.
Answer 6 years ago
Breaks are to be avoided. The for loop is not really the right
structure for this.You just need a simple loop, but put the button in an
interrupt routine.
I don't know which arduino you have, but you can try putting something like this - just check which pins can interrupt you.
int Button = 13; //This is interrupt 0
volatile int sweep = HIGH; //Our state variable, initialise so we always sweep
void setup()
{
servo1.attach(10);
pinMode(Button, INPUT);
Serial.begin(9600);
attachInterrupt(0, Isweep, CHANGE);
}
void loop()
{ Pos=0;
while (pos<180) & (sweep==true) {servo.write (pos);pos++;delay(10)};
while (Pos>0) & (sweep==true) (servo.write(pos);pos--;delay(10)};
//both these whiles will terminate and not do anything if sweep is true.
}
void Isweep() //Interrupt routine
{
sweep = !sweep;
while digitalread(button)==TRUE; //change state only once when button is pressed
}
Answer 6 years ago
Thanks! it works, but how do I make it so I can do this in a switch case where it will have an initial position, then make it so it it goes back and forth until i hit the button again, and it will go on another case to do something else like start an led. But otherwise that, this is exactly what I need.
Answer 6 years ago
When asking a question, give a full description of the problem, the answer would be different to the one I've given.
Answer 6 years ago
I'm very sorry to bother you again, but I really have no idea how to get this working. I uploaded the new code. I'm basically having the same issue again, except this time i have to hold the button to make the servo to go back and forth. Sometimes when i hit the button again, it will go to case 3, which is good, except for the part that it is really random. I tried using another button, but it seems to not work. If you can see what I clearly did wrong feel free to correct me.
Answer 6 years ago
Post the new code !
Answer 6 years ago
If you are wondering what I'm doing, I'm trying to make some soccer arcade game where it has a servo to make it go back and forth, and then once it stops, led lights will turn on in a sequence and you hit the button and, and if all led or most are on it kicks the ball with a motor.
That is why I'm trying to use a switch case for this.
Answer 6 years ago
Add a counter IN THE INTERRUPT, and use that number in an external switch. enum a series of states, sweep, flash_leds, kick, and transition between the states depending on the value of the counter.
Don't forget to vote the best answer.
Answer 6 years ago
one last question. I'm kind of stupid, but when you mean add a counter in the interrupt, you mean the void Isweep() or is it something else?
Answer 6 years ago
Yes, that's right, in lsweep
Answer 6 years ago
Thanks again for the help! I will try this out. I'm really new to this, so hopefully I can do this haha
6 years ago
Forget the switch statement. It doesn't need breaks in it anyway, but "if" statements are much clearer.
Should be
attachInterrupt(0, Isweep, FALLING);//assumes button input is tied high
Lsweep
{ //button has been pressed, it must be LOW to trigger the interrupt, so increment the counter
buttoncount++;
if (buttoncount>=4) buttoncount=0; //never use "==", it might fail
while (digitalRead(Button)==true); //change state only once when button is pressed
}
void loop()
{
if (buttoncount==1)
{servo1.write(0);
digitalWrite(led_1, LOW);
}
if (buttoncount==2)
{Pos=0;
while (Pos<180 & sweep==true)
{servo1.write (Pos);
Pos++;
delay(10);
}
while (Pos>0 & sweep==true)
{servo1.write(Pos);
Pos--;
delay(10);
}
if (buttoncount==3) digitalWrite(led_1,HIGH);
}
Answer 6 years ago
There are better ways, but this section should be as below.
if (buttoncount==2)
{Pos=0;
while ((Pos<180) & (buttoncount==2))
{servo1.write (Pos);
Pos++;
delay(10);
}
while ((Pos>0) & (buttoncount==2))
{servo1.write(Pos);
Pos--;
delay(10);
}
Delete the "sweep" variable
Answer 6 years ago
sweet, it almost works, I'm not sure, but i think the button count jumps, should I add some sort of debounce code?
Answer 6 years ago
put a few msec delay in the interrupt routine