If statement calling a function

Hi all! I am working on making an autonomous vehicle and am trying to test it out by sending the car values over serial to which it will execute a function. My code is very simple, it is only controlling one l293 on pins 8 and 9. Any help would be greatly appreciated. Thank you for your time.

int x; // variable to determine which direction to turn

void setup() {
  pinMode (9, OUTPUT); // pin connected to l293
  pinMode (8, OUTPUT); // pin connected to l293
  Serial.begin (9600); // baud rate set
  establishContact(); // function to see if serial is availible
}

void loop() {
  if (Serial.available() > 0) { 
    x = Serial.read (); // store variable from serial as x
    Serial.write ("hi"); // just proof that the variable is from the arduino
    Serial.write (x); //returns variable to prove arduino has variable
  }
  if (x == 1) { // if I send value 1 over serial, initiate function left
    left();
  }
  else { // if I send any other values over serial, call right()
    right();
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("HI!");   // send an initial string
    delay(300);
  }
}

void left() { // turns car left
  digitalWrite (9, LOW);
  digitalWrite (8, HIGH);
  delay (2000);
  digitalWrite (8, LOW);
}

void right() { // turns car right
  digitalWrite (9, HIGH);
  digitalWrite (8, LOW);
  delay (2000);
  digitalWrite (9, LOW);
}

Post a schematic of your connections and a link to the motors you are using.

What do you see happening when you send 1 and anything that is not 1? Any whirs, clicks, anything?

    Serial.write ("hi"); // just proof that the variable is from the arduino
    Serial.write (x); //returns variable to prove arduino has variable

Time to hit the reference material, and source code, if needed, and learn the difference between Serial.print() and Serial.write() for all the possible variable types.

Understanding what Serial.read() returns would be a good idea, too.

  if (x == 1) { // if I send value 1 over serial, initiate function left
    left();

If you are using the Serial Monitor, you can not send the value 1. You can send the value ‘1’, which, of course, is NOT the same as the value 1.

  while (Serial.available() <= 0) {
    Serial.println("HI!");   // send an initial string

While you are looking at the reference material, and source code, if needed, figure out under what circumstances Serial.available() can return a negative number.

Are the values you are supposed to send to 8 and 9 direction and speed?

OK so when I enter any value in the serial monitor, including 1, with the code I posted above, the car turns and stays in the right position. My code does not include anything with the speed of the car as of yet, only the turning. Turning is accomplished by a dedicated motor which turns the wheels until they cannot turn anymore and holds them there. When voltage is released they return to neutral due to a spring mechanism. I changed my code to be

if (x == '1') { // if I send value 1 over serial, initiate function left
    left();

and now the wheels don't move at all. I realized that Serial.read() returns -1 when there is no data to be read which would account for the reason the wheels are always turning right but not for the problem when I enter '1' upon which they should turn left. I have also changed Serial.write() to Serial.print(). Pins 8 and 9 are connected to the input pins of my motor driver. If 8 is high and 9 low, the motor will turn one direction. If 8 is low and 9 high the motor will turn the other. If neither is high the motor will not turn. I have also tested each function by calling it without the if statements and they both work wonderfully so it is not a problem with the wiring. I will look into the problem further when I get home as I am at school now.

So what’s the code look like now?

void loop() {
// ****************************
if (Serial.available() > 0) {
x = Serial.read (); // store variable from serial as x
Serial.write (“hi”); // just proof that the variable is from the arduino
Serial.write (x); //returns variable to prove arduino has variable
}

// *************************************************
if (x == 1) { // if I send value 1 over serial, initiate function left // <<< if x gets set to 1, will stay here as nothing clears it
left();
}
else { // if I send any other values over serial, call right() // <<< if No serial data sent , and x was never set to 1, wil always end up here.
right();
}

}

Here is my code so far

int x; // variable to determine which direction to turn

void setup() {
  pinMode (9, OUTPUT); // pin connected to l293
  pinMode (8, OUTPUT); // pin connected to l293
  Serial.begin (9600); // baud rate set
  establishContact(); // function to see if serial is availible
}

void loop() {
  if (Serial.available() > 0) { 
    x = 42; //random number to clear X of previous value, hoping 42 is the answer to life universe and everything :P
    x = Serial.read (); // store variable from serial as x
    Serial.print ("hi"); //proof of going through the arduino, not really needed
    Serial.println (x, BYTE); //returns variable to prove arduino has variable
  
    if (x == '1') { // if I send value 1 over serial, initiate function left
      left();
    }
    if (x == '2'); { // Changed to be a specific value not just everything else
      right();
    }
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("HI!");   // send an initial string
    delay(300);
  }
}

void left() { // turns car left
  digitalWrite (9, LOW);
  digitalWrite (8, HIGH);
  delay (2000);
  digitalWrite (8, LOW);
}

void right() { // turns car right
  digitalWrite (9, HIGH);
  digitalWrite (8, LOW);
  delay (2000);
  digitalWrite (9, LOW);
}

I am happy to say that it is working much better now. The problem now is that when I enter 1 it turns left for 2 seconds, then right for two seconds. If I enter 2 it just turns right for two seconds, Hmm…

Hmm indeed, why the extra right? Does it turn left, then sit there printing "HI!" over and over until the next character and a "hi,x" comes out?

How can it get back in here if (Serial.available() > 0) if a 2nd byte isn't sent?

As I understand, the data comes down the usb cable and is stored in the serial buffer. The serial.availible() just looks to see if there is anything there but doesn't change or delete anything. As my program is written, it loops just the serial.avalible() until the if is true and then it runs the rest of function. I do not know why it turns left and right when only left was called for.

You've got a stray semicolon:

if (x == '2'); {
...
}

This says to the compiler: "If x is '2' then do absolutely nothing. Then, no matter what, do what's inside these braces".

Dang, didn't even notice that!

Wow, that did the trick. One single inconspicuous semicolon can screw up an entire sketch? I have learned my lesson today. Thank you guys for all your patience and help :stuck_out_tongue:

Final Code

int x; // variable to determine which direction to turn

void setup() {
  pinMode (9, OUTPUT); // pin connected to l293
  pinMode (8, OUTPUT); // pin connected to l293
  Serial.begin (9600); // baud rate set
  establishContact(); // function to see if serial is availible
}

void loop() {
  if (Serial.available() > 0) { 
    x = 33;
    x = Serial.read (); // store variable from serial as x
    Serial.print ("hi");
    Serial.println (x, BYTE); //returns variable to prove arduino has variable
  
    if (x == '1') { // if I send value 1 over serial, initiate function left
      left();
    }
    if (x == '2') { // if I send any other values over serial, call right()
      right();
    }
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.println("HI!");   // send an initial string
    delay(300);
  }
}

void left() { // turns car left
  digitalWrite (9, LOW);
  digitalWrite (8, HIGH);
  delay (2000);
  digitalWrite (8, LOW);
}

void right() { // turns car right
  digitalWrite (9, HIGH);
  digitalWrite (8, LOW);
  delay (2000);
  digitalWrite (9, LOW);
}