Arduino RC Control

Hi all I've been working on a wifi bot project interfaced with the serial port of a fonera and a python script that sends commands through an SSH session with the router. Im using a startbyte to read the values in the buffer then assign them to spaces in an array. A switch statement then sets the correct pin on or off.

Im getting stuck with the steering part. It uses a potentiometer to relay the position of the steering arm. In the ways I've attempted to write it it wont break out of the switch statement. So I'm looking for advice on a better way to write it

Here's a snippet of the code I'm using:

// the measured stop points  using the values of analogRead are
// leftStop = 280;
// rightStop = 800;

switch (axis){
       case 49: // 1 - forward
       if (userInput[1] == 49) { digitalWrite(drive1[0], HIGH);}
       else if (userInput[1] != 49) { digitalWrite(drive1[0], LOW);}
       break;
                    
       case 50: // 2 - reverse
       if (userInput[1] == 49) { digitalWrite(drive2[0], HIGH);}
       else if (userInput[1] != 49) { digitalWrite(drive2[0], LOW);}
       break;
       
       case 51: // 3 - left
       break; 
     
      
       
       
       case 52: // 4 - right
       break;
     
       
       case 121: // y turns off forward and reverse motors
       digitalWrite(drive1[0], LOW);
       digitalWrite(drive2[0], LOW);
       break;
       
       case 120: // x  centers steering
       break;

it wont break out of the switch statement.

I think you need to post all the code rather than the snippet, as I can't see why that should go into the switch and not come out.
There is a } missing at the end but I assume it is just been missed out in the copy.

Things like this:-
if (userInput[1] == 49) { digitalWrite(drive1[0], HIGH);}
else if (userInput[1] != 49) { digitalWrite(drive1[0], LOW);}

should be simplified to:-
if (userInput[1] == 49) { digitalWrite(drive1[0], HIGH);}
else { digitalWrite(drive1[0], LOW);}

you don't need the second IF because this condition is met if the first is not.

Or even simpler:

digitalWrite(drive1[0], (userInput[1] == 49) ? HIGH : LOW);

How is "axis" derived?

Heres what I have so far

//Working Bot Control w/o steering w/ fonera and joystick
int driveArray[4] = {7, 6, 5, 4};
int userInput[2];
int startbyte;
int axis;
int action;
int drive1[2];
int drive2[2];
int drive3[2];
int drive4[2];

// Steering
int potPin = 0;
int val = 0;
int rightStop = 800;
int leftStop = 280;
int centerStop = (leftStop + rightStop)/ 2;


void setup()
{
  Serial.begin(9600);
  
  for (int i = 0; i < 4; ++i) 
  {
    pinMode(driveArray[i], OUTPUT);
  }
  // map pins to drive direction
  drive1[0] = driveArray[0]; // forward
  drive2[0] = driveArray[1]; // reverse
  drive3[0] = driveArray[2]; // left
  drive4[0] = driveArray[3]; // right
  
  //set all to off
  for (int i = 0; i < 4; ++i)
  {
    digitalWrite( driveArray[i], LOW);
  }

}

void loop()
{
  val = analogRead(potPin);
  // Waits until theres 3 bytes in buffer
  if (Serial.available() > 2)
  {
   // Read the first byte
   startbyte = Serial.read();
   
   if (startbyte == 122) {
     for (int i = 0; i < 2; ++i)
     {
       userInput[i] = Serial.read();
       Serial.println(startbyte);
     }
     // Which axis to move
     axis = userInput[0];
     action = userInput[1];
  
     switch (axis){
       case 49: // 1 - forward
       if (userInput[1] == 49) { digitalWrite(drive1[0], HIGH);}
       else if (userInput[1] != 49) { digitalWrite(drive1[0], LOW);}
       break;
                    
       case 50: // 2 - reverse
       if (userInput[1] == 49) { digitalWrite(drive2[0], HIGH);}
       else if (userInput[1] != 49) { digitalWrite(drive2[0], LOW);}
       break;
       
       case 51: // 3 - left
       break; 
     
      
       
       
       case 52: // 4 - right
       break;
     
       
       case 121: // y turns off forward and reverse motors
       digitalWrite(drive1[0], LOW);
       digitalWrite(drive2[0], LOW);
       break;
       
       case 120: // x  centers steering
       break;

     }
   }   
  }
}

Well, it's usually a good idea to have a trap "default" in a switch (helps debugging).

What makes you think you're not getting out of the switch?
Are you sending a continuous stream of triplets of characters (122, axis, action) on the serial line? If you're not, you'll stall after the first time through "loop"

You could simplify this somewhat - you've assigned "axis" and "action" but then reverted to "userInput[1]" instead of "action".
Not a big deal, but this sort of thing often comes back to bite you in the ass.
You could save time by:
#define action userInput[1]
You're not using the value read from "potPin" - if you're debugging, and you don't need it, simply comment it out.

It sends triplets every time any time the joystick is pushed past a point a certain point on the given axis (255, axis, action) and also when it returns to the center positions on the x or y axis
For the steering parts I had something like the following before removing it and trying to start again. It is supposed to move in one direction until the pot value reaches a point then it'll break out of the while loop turn off that pin and break out of the switch

case 51: // 3 - left
      if (action == 49) 
      { 
        while (val > leftStop)
        {
          digitalWrite(drive3[0], HIGH);
        }
         digitalWrite(drive3[0], LOW);
         break;
         }

       
case 52: // 4 - right
     if (action == 49) 
      { 
        while (val < rightStop)
        {
          digitalWrite(drive4[0], HIGH);
        }
         digitalWrite(drive4[0], LOW);
         break;
         }
while (val > leftStop)
        {
          digitalWrite(drive3[0], HIGH);
        }

What causes this loop to exit if, on entry, "val" is greater than "leftStop"?

wont it exit when val <= leftStop ?

How does val get changed? - I don't see a read anywhere in the loop/

I think I see what I'm doing wrong.
I read the pot value at the beginning of the loop

void loop()
{
  val = analogRead(potPin);
  // Waits until theres 3 bytes in buffer
  if (Serial.available() > 2)
  ............

but I would also have to be reading it within the while loop so I should write it as so:

while (val > leftStop)
        {
          digitalWrite(drive3[0], HIGH);
            val = analogRead(potPin);
        }

:slight_smile:

You could also write it as a for loop :

for (; val > leftStop) ; val = analogRead (potPin)) {
digitalWrite(drive3[0], HIGH);
}