Pages: [1]   Go Down
Author Topic: Failure at debounce or state machine?  (Read 407 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am working up my knowledge of Arduino.  I started with some basic PWM and LED stuff and now I am working to stack the lessons I have learned into a larger project.

In this project I want to have a servo that is stationary until I press the up or down button.  When the up button is pressed the servo will advance degrees until the limit is reached or the switch is released.  When the down button is pressed the same will be true in the opposite direction.

This portion works great.  Now I want to change the speed of the servo by pressing both up and down buttons at the same time.  My desire is to have this combination button press toggle the speed from 1 deg per count to 5 deg to count.

I have indicating LEDs built in to help me diagnose the problem.  The LEDs are driven by the MCU and not the buttons.  The up and down LEDs light properly as the servo moves the desired direction.  When I press both buttons the LED on A4 lights properly to show that the MCU knows both buttons are pressed.  However, there is no speed toggle.

I have looked this code over a hundred times and can't find the error.  Is it the debounce that is broken or is it the state machine protion?

Any help would be greatly appreciated.


Code:
#include <Servo.h>


Servo myservo;
int up; //var for servo degree up
int down; // var for servo degree down
const int upPin = 7; //pin for up button
const int downPin = 8; //pin for down button
int toggle = 0; // toggle used for servo speed state machine
int moveSpeed = 1; // initial servo speed changed by state machine
int pos; //position of servo, modified by button presses
int reading; // varible eventually set LOW when up button and down button are pressed together
int lastButtonState = HIGH; //  Initial setting of state machine
long lastDebounceTime = 0; //var used to count switch bounce.  Long because of size
long debounceDelay = 50; // how long the switch must be steady to count as pressed


void setup()
{
  myservo.attach(3);  // attaches the servo on pin 3 to the servo object
  pinMode(upPin, INPUT); //set pin 7 as input
  pinMode(downPin, INPUT); // set pin 8 as input
  digitalWrite(upPin, HIGH); // Turns on pullup resistor on upPin
  digitalWrite(downPin, HIGH); // Turns on pullup resistor on downPin
  pinMode(13, OUTPUT); //set pin for output for LED display
  pinMode(A5, OUTPUT); //set pin for output for LED display
  pinMode(A4, OUTPUT); //set pin for output for LED display 
}
 
 
void loop()
{


  up = digitalRead(upPin); //read the up button high or low
  down = digitalRead(downPin); //read the down button high or low


  if (up == LOW && down == LOW){ //if both buttons are pressed then start the machine to change speeds
    reading = LOW;
  }
    else {
    (reading = HIGH);
  }
 
 digitalWrite(A4, reading); //Light an LED to verify that both buttons are pressed, dev use only (LIGHTS PROPERLY)
 
  if(reading != lastButtonState){ //if button pressed or unpressed look at the clock
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay){ //if 50ms has passed since clock look, logic toggle the switch
    toggle = reading;
  }
 
  if (toggle == LOW && moveSpeed == 1){ //toggle speed to 5 if it is at 1
    moveSpeed = 5;
  }
  if (toggle == LOW && moveSpeed == 5){ //change speed to 1 if it is at 5
    moveSpeed = 1;
  }
 
  lastButtonState = toggle; //remember the last state of the button greater than the debounce time of 50ms
 


 
  if (up == LOW){ //if up button is pressed move servo degrees up by state machine set speed
  pos = pos +moveSpeed;
  }
  if (pos >= 160){ //don't let the servo move up past 160 deg (to prevent hitting mechanical limits)
  pos = 159;
  }
  if (down == LOW){ //if down button is pressed move servo degrees up by state machine set speed
  pos = pos - moveSpeed;
  }
  if (pos <= 1){ //don't let the servo move down past 1 deg  (to prevent hitting mechanical limits)
  pos = 2;
  }
  digitalWrite(13, up * -1); //light an led if servo is moving up or down, dev use only (LIGHTS properly)
  digitalWrite(A5, down * -1);
 
  myservo.write(pos);
          // tell servo to go to position in variable 'pos'
    delay(10);       
}    // waits 15ms for the servo to reach the position
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Toggling states is typically done using signal edges, rather than signal states. I see where you are changing the speeds based on the switches state, not based on a signal edge. This line looks like you were planning on doing that, but a red flag should be raised when you notice that lastButtonState is only ever used here.

Code:
lastButtonState = toggle; //remember the last state of the button greater than the debounce time of 50ms
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46029
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now I want to change the speed of the servo by pressing both up and down buttons at the same time.
The problem with this approach is that your definition of "at the same time" and the Arduino's definition of "at the same time" are not the same thing. Kind of like your wife saying "I'll be ready in a minute". Your definition of a minute and hers are not the same thing, are they.

It would be much simpler to add one more switch. When that switch is pressed, the existing up and down switches do one thing. When it is not pressed, the existing up and down switches do something else (what they currently do).
Logged

Pages: [1]   Go Up
Jump to: