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
}

sort by: active | newest | oldest

What's the point of buttoncount ?


cmasuo (author)  steveastrouk3 years ago
I need to change the switch case with a button, and the way i know it involves making a button counter.

The state is either sweeping or fixed. If the button has been pressed, its fixed. What stops the servo being fixed ? Another press ?

cmasuo (author)  steveastrouk3 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.

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
}

cmasuo (author)  steveastrouk3 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.

When asking a question, give a full description of the problem, the answer would be different to the one I've given.

cmasuo (author)  steveastrouk3 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.

Post the new code !

cmasuo (author)  cmasuo3 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.

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.

cmasuo (author)  steveastrouk3 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?

Yes, that's right, in lsweep

cmasuo (author)  steveastrouk3 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

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);

}

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

cmasuo (author)  steveastrouk3 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?

put a few msec delay in the interrupt routine