Go Down

Topic: An Alternative to a Hypothetical Delay in Interrupt (Read 1 time) previous topic - next topic

Erasermaster

I have written a code that is supposed to work with a 360 servo but I have ran into some issues. When I run the code the servo just jitters and my override button doesn't work either. I can't seem to find anything conceptually wrong but I may have made a silly syntax error. Could anybody pick it out?

Code: [Select]
#include <Arduino.h>
#include <Servo.h>

Servo servo;
int OVERRIDE = 2;
int rightButton = 12;
int leftButton = 13;
int servoPos;
static unsigned long prevTime = 0;
void manualControl();
bool manualTrigger = false;
bool autoLoopStart = true;
bool loopStart = false;
static unsigned long servoTime;
enum states{AUTO, MANUAL};

void setup(){
servo.attach(5);
pinMode(rightButton, INPUT);
pinMode(leftButton, INPUT);
pinMode(OVERRIDE, INPUT);
servo.write(93);
}

void loop(){
states state = AUTO;
prevTime = millis();
if(digitalRead(OVERRIDE) == HIGH){
state = MANUAL;
}
switch(state){
case AUTO:
do{
servoTime = millis();
autoLoopStart = false;
}while(autoLoopStart == true);
if(millis() - servoTime <= 3000){
servoPos = 93;
servo.write(servoPos);
}
case MANUAL:
manualControl();
break;
}
}

void manualControl(){
while(1){
if(digitalRead(leftButton == 1)){
servoPos = 91;
servo.write(servoPos);
}else{
servoPos = 90;
}
if(digitalRead(rightButton == 1)){
servoPos = 89;
servo.write(servoPos);
}else{
servoPos = 90;
servo.write(servoPos);
}
}
}


note: I don't want to ever exit fom manual control which is why I have put  in the while(1) loop.


UKHeliBob

(1) How many times will this loop execute ?

Code: [Select]
   
    do
    {
      servoTime = millis();
      autoLoopStart = false;
    }
    while(autoLoopStart == true);


(2) There is no break; at the end of the AUTO case

(3) When the routine gets to the manualControl() function it will move between angles of 90/89 or 89/90, hence the jitter.

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

WizenedEE

Quote

note: I don't want to ever exit fom manual control which is why I have put  in the while(1) loop.

I wouldn't do that; I would instead say that in the 'manual' case, it never reverts back to the 'auto' case. That way you can easily change it if you change your mind (eg press another button instead of "reset"). The switching from auto to manual should also take place inside the "AUTO" case since it only makes sense to "switch" to manual when you're not in it already.

However if you do that another problem will show its face -- your variable "state" (of type "states") is forgotten at the end of loop() and recreated at the beginning, and the whole point of the variable is to keep track of the state between loops. Using the "static" keyword means it will keep its value between calls of loop().

In the manualControl() function, you should only call servo.write() once. That way, you can be sure you don't write it multiple times in one loop.

Your digitalRead() syntax is wrong. You don't want to check if "rightButton" is 1, you want to check if digitalRead(rightButton) is 1. So just move the parentheses.

Code: [Select]

do{
servoTime = millis();
autoLoopStart = false;
}while(autoLoopStart == true);
if(millis() - servoTime <= 3000){

the if will never be true, since you had just set the value of servoTime. You probably want to have an if around that statement rather than a do...while(), which always executes the code at least once.

Go Up