Arduino-controled mini hoverboard

I have a servo to control the rudder on my hoverboard, and I have two buttons that control the direction of my servo. When I press the buttons, sometimes it goes left, sometimes it goes right, and sometimes it goes as much right as it can. I think it is a problem with my code. Here is my entire code. If there are any problems, or if I can make it better, than can someone tell me how?

#include <Servo.h>

Servo steerServo;

//pin variables
const int potPin = A0;
const int motorPin = 9;
const int rightButtonPin = 4;
const int leftButtonPin = 2;
const int LEDPin = 13;

//value variables
int potVal = 0;
int motorVal = 0;
int state = 0;
int servoPos = 90;
int LButtonVal = 0;
int RButtonVal = 0;

void setup() {
 //serial communication
 Serial.begin(9600);
 //attach servo to pin 3
 steerServo.attach(3);
 //declare input and output
 pinMode(rightButtonPin, INPUT);
 pinMode(leftButtonPin, INPUT);
 pinMode(motorPin, OUTPUT);
 pinMode(LEDPin, OUTPUT);
 //initially set my servo to 90
 steerServo.write(90);
}

void loop() {
 //put my LED high
 digitalWrite(LEDPin, HIGH);

 //map potentiometer to motor
 potVal = analogRead(potPin);
 motorVal = map(potVal, 0, 1023, 0, 255);

 //write values to motor
 analogWrite(motorPin, motorVal);

 //get values from servo steering buttons
 RButtonVal = digitalRead(rightButtonPin);
 LButtonVal = digitalRead(leftButtonPin);

 //If both buttons are pressed blink the led until they are not.
 while((RButtonVal == HIGH) && (LButtonVal == HIGH)){
   digitalWrite(LEDPin, HIGH);
   delay(250);
   digitalWrite(LEDPin, LOW);
   delay(250);
 }
 
 //check which buttons are being pressed and
 //and write the values to the servo
 if(RButtonVal == HIGH){
   servoPos++;
   steerServo.write(servoPos);
 }  
 if(LButtonVal == HIGH){
   servoPos--;
   steerServo.write(servoPos);
 }

 //make sure the LED is still on
 digitalWrite(LEDPin, HIGH);

 //print the serial info
 Serial.print("potentiometer =");
 Serial.print(potVal);
 Serial.print("\t motor = ");
 Serial.print(motorVal);
 Serial.print("\n Servo = ");
 Serial.println(servoPos);

 //just a small delay to allow all parts to finish moving
 delay(2);
}

Arduino-Hoverboard.ino (1.76 KB)

Please edit your post to add code tags, so that your code looks like this:

  //If both buttons are pressed blink the led until they are not.
  while((RButtonVal == HIGH) && (LButtonVal == HIGH)){
    digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
  }

which, incidentally, is an infinite loop. Once in that loop, the Arduino is stuck blinking that LED until the power is turned off.

This is not causing the problem, because I took that section out and tested it, and it still did not work. Would a do-while loop like this work?

//If both buttons are pressed blink the led until they are not.
  do{
    digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
  }
  while((RButtonVal == HIGH) && (LButtonVal == HIGH))

Same problem. You are not reading the buttons in the loop, so it will never exit.

Will this work?

//If both buttons are pressed blink the led until they are not.
  do{
    int i = 0;
    int j = 1;
    j = i + 1;
    for(i = 0; i < j; j++; i++){
      digitalWrite(LEDPin, HIGH);
      delay(250);
      digitalWrite(LEDPin, LOW);
      delay(250);
      if((RButtonVal == HIGH) && (LButtonVal == HIGH)){
        i = j;
      }
    }
  }
  while((RButtonVal == HIGH) && (LButtonVal == HIGH))

You didn't update the values of RButtonVal or LButtonVal inside the loop. You need to do the digitalRead() again inside the loop. Then you can detect if the buttons change while looping.

Thanks! Would this work?

//If both buttons are pressed blink the led until they are not.
  if((RButtonVal == HIGH) && (LButtonVal == HIGH)){
    int i = 0;
    int j = 1;
    j = i+1
    for(i = 0; i < j; i++){
      digitalWrite(LEDPin, HIGH);
      delay(250);
      digitalWrite(LEDPin, LOW);
      delay(250);
      j = i+1
      RButtonVal = digitalRead(rightButtonPin);
      LButtonVal = digitalRead(leftButtonPin);
      if((RButtonVal == HIGH) && (LButtonVal == HIGH)){
        i = j;
      }
    }
  }

This does not fix the servo problem though. I think the issue is in this.

//check which buttons are being pressed
 //and write the values to the servo
 if(RButtonVal == HIGH){
   servoPos++;
   steerServo.write(servoPos);
 }  
 if(LButtonVal == HIGH){
   servoPos--;
   steerServo.write(servoPos);
 }

Will it work if I change it to this?

//check which buttons are being pressed and
  //and write the values to the servo
  RButtonVal = digitalRead(rightButtonPin);
  LButtonVal = digitalRead(leftButtonPin);
  if(RButtonVal == HIGH){
    servoPos++;
    steerServo.write(servoPos);
  }else if(LButtonVal == HIGH){
    servoPos--;
    steerServo.write(servoPos);
  }else if(RButtonVal == LOW){
    steerServo.write(servoPos);
  }else{
    steerServo.write(servoPos);
  }
      if((RButtonVal == HIGH) && (LButtonVal == HIGH)){

i = j;
      }

This is a very poor way to break out of a loop. Some languages don’t let you play with the loop variable like this. The C compiler will let you, but it will produce less efficient code.

Use the break; statement to break out of a loop. When you do, put a comment next to it to describe which loop you think you are breaking - future changes to the code may result in you forgetting that this is here and it will break something you didn’t expect.

Your other changes don’t do much. If you think it is necessary to explicitly write to the servo on every iteration, then just put that once, after all the if()'s that set the value. It’s actually the better way to do it.

Here’s an example of a very large Arduino program. This is the entire loop().

void loop() {
  readInputs();
  doCalculations();
  setOutputs();
}

The output function doesn’t care if the calculations changed something. It just outputs whatever is the current value.