> | | > Understanding Control Signals on the Arduino

Understanding Control Signals on the Arduino

Posted on Wednesday, 28 November 2012 | No Comments

An Arduino is used to control each robot. Through the use of XBees, a signal will be sent from Processing, which the robot Arduino will pick up. The packet that is sent from Processing is in the following format:
< - indicates the start of the packet
F or f - sets whether the laser is on or off
XX - two numbers that determine the position of servo x
XX - two numbers that determine the position of servo y
F, B or S - determines left motor state
F, B or S - determines right motor state
> - indicates the end of the packet

For the Arduino to receive the packets, the Arduino reads its serial port. While there is information available on the serial port, it stores the incoming bytes into an array. The code for this can be seen below.

while(Serial.available() > 0){//look for Serial data 
    int incoming = Serial.read();//read and store the value
    instruction[i] = incoming; //store the instruction in the array

There are then checks put into place to see whether or not what was sent to the Arduino is in the correct packet format. If the Arduino cannot find the start and end delimiters of the packet (< and >, respectively) it ignores the received information. 

//loop round the instruction array (expecting 9 characters)
    for (j = 0; j<9; j++)
      //get the coordinates for the motor  
      if ((instruction[j] == '<') &&  (instruction[j+8] == '>'))

If the incoming packet does have the start and ending characters, the Arduino can parse the packet. The string format is known so it is as simple as comparing each character to what you expect. 

Firstly, the servo instructions are dealt with. There should be 4 numbers in the packet - two for servo x and two for servo y. Since these numbers arrive as characters, they need to be concatenated into a String and then converted to an Integer. The code for this can be seen below. Once the Integer has been retrieved, the number is written to the correct servo.
//concatenate the two strings for x coordinates together
stringXCoord += instruction[j+2];
stringXCoord += instruction[j+3];
//make the string an integer
intXCoord = stringXCoord.toInt();
servoX.write(intXCoord); //write to the servo
//concatenate the two strings for y coordinates together
stringYCoord += instruction[j+4];
stringYCoord += instruction[j+5];
//make the string an integer
intYCoord = stringYCoord.toInt(); 
servoY.write(intYCoord); //write to the servo 

Next, the laser is dealt with. If the laser character is 'F', then the laser should be turn on else if it is 'f' then it should be turned off. 
          //turn laser on
          if (instruction[j+1] == 'F')
            digitalWrite(laser, LOW);
          //turn laser off
          if (instruction[j+1] == 'f')
            digitalWrite(laser, HIGH);

The motors on the robot are next to be parsed. The expected characters are 'F', 'B' or 'S'. 'F' means that the motor should move forward, 'B' means that the motor should go backwards and 'S' means the motor should stop moving. There is one character for the left motor and one for the right. The code for the motors can be seen below.
//control motors on robot - left motor forward
        if (instruction[j+6] == 'F')
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
        //control motors on robot - left motor stop
        if (instruction[j+6] == 'S')
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
        //control motors on robot - left motor backward
        if (instruction[j+6] == 'B')
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
        //control motors on robot - right motor forward
        if (instruction[j+7] == 'F')
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
        //control motors on robot - right motor stop
        if (instruction[j+7] == 'S')
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
        //control motors on robot - right motor backward
        if (instruction[j+7] == 'B')
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
Finally, variables need to be reset. The variable i used for storing the incoming serial into an array is set to -1 and then incremented to get back to 0, as resetting back to 0 would not work. 
        //reset variable for instruction array 
        i = -1;
    //increment counter for instruction array
    //reset variables used
    stringXCoord = "";
    stringYCoord = "";
    intXCoord = 0;
    intYCoord = 0;
All of the code given was in the void loop() method. For the code to work, all variables were stated at the start of the sketch and any libraries needed were included.
#include <Servo.h>
char instruction [9]; //instruction sent to arduino
int i = 0; //index for instruction array
int j = 0; //index for for loop

String stringXCoord = "";
int intXCoord; //x coordinate for motor
String stringYCoord = "";
int intYCoord; //y coordinate for motor

Servo servoX; //servo x
Servo servoY; //servo y

//pin for laser and LDR
int laser = 13;

//pin numbers for the motor on the robot
int leftMotor1 = 11;
int leftMotor2 = 12;
int rightMotor1 = 9;
int rightMotor2 = 10;

In void setup(), pins have to be set as either an input or output, and servos need to be attached.
void setup(){
  //init Serial library (make sure Processing is sending data at the same baud rate)
  pinMode(sensor1, INPUT);
  pinMode(laser, OUTPUT);
  pinMode(leftMotor1, OUTPUT);
  pinMode(leftMotor2, OUTPUT);
  pinMode(rightMotor1, OUTPUT);
  pinMode(rightMotor2, OUTPUT);

Any extensions to the packet sent between the robots can easily be integrated. The indices of any arrays will need to be changed, and if statements will need to be added, which is relatively easy to do, showing that the code is very flexible in terms of future work. 

Leave a Reply

Theme MXS. Powered by Blogger.