Home > Comms

Comms

Games Master GUI

Wednesday, 16 January 2013 Category : , , , 0

The Games Master GUI is the graphical user interface that is displayed on a laptop that is connected to the Games Master Arduino. Its purpose is to display the scores of each LaserBot for everyone to see.

DESIGN

The Games Master GUI was designed using Processing. In Processing, there are quite a few examples on how to draw different things. Firstly,it was figured out how to draw text by looking at the Processing example "Words". The screen was to be split into two halves, one the left hand side would be LaserBot one's score, and on the right LaserBot two's score. 

Testing Multiple Controllers

Sunday, 13 January 2013 Category : , , 0

In order for the two robots to be controlled effectively, it is necessary to receive and differentiate between messages sent from two controllers.  The TouchOSC app allows for the IP address of the host to be configured, along with the port of the application to send messages to.  The port of received messages on the iPad can also be configured, this is generally left as default.  At the bottom is the iPads IP address, which is required to send messages back to the controller to control LEDs and labels on screen. The configuration screen is shown below.
TouchOSC configuration screen

Sending Messages

Using some of the examples on the OscP5 library's website it was possible to create some prototype code to send OSC messages back to the controller, to update labels and turn on LEDs etc. The processing code below updates the player's score label.

Circle Network: Controlling each robot

Monday, 7 January 2013 Category : , , 0

In this post, it was explained that the LaserBots are now connected in a circle network as shown below. The Games Master talks to LaserBot 1, LaserBot 1 talks to LaserBot 2 and LaserBot 2 talks back to the Games Master. 
Circle Network Setup

NEW PACKET STRUCTURE

To implement this correctly, the packet that is being sent round needs to be modified so that the instruction is sent to the correct LaserBot. Therefore, the new packet format is as follows:
< - character to signify start of message
1 or 2 - robot ID 
F or f - turn laser on or off
XX - numbers to control servo x
XX - numbers to control servo y
F, B or S - left motor controls (forward, back or stop)
F, B or S - right motor controls (forward, back or stop)
> - character to signify end of message

Also, to send the scores back to the Games Master, another packet needs to be introduced:
[ - character to signify start of message
G - intended for Games Master
1 or 2 - robot ID
XX - number representing how much score should be incremented
] - character to signify end of message


LASERBOT ONE CODE 

INSTRUCTION PACKET CODE

The code in each robot needs to be modified to accept this new packet structure. Firstly, the array used to store the instruction needs to be made bigger to accommodate the extra characters being sent. 
char instruction [10]; //instruction sent to arduino 
Next, a String needs to be introduced so that a message can be resent on to robot 2.

//message to send on to Robot 2
String resendMessage = "";
Inspecting the previous code for the robot, the first part of void loop() stays the same - while there is serial data available, read the data and store in the instruction array. Next, check to see if the instruction starts and ends with the characters '<' and '>' (remembering to change the index by one for the ending character). 

Next, another if statement needs to be added to check whether or not the instruction received is for robot 1. 
//check that message is for robot 1 <1....>
        if (instruction[j+1] == '1')
        {
If the message is for the robot, the normal parsing takes place (parse the rest of the message to deal with lasers, servos and motors). Else, if the message is for robot 2, robot 1 needs to resend the message. The message is concatenated together and then printed out. Before being printed, however, the serial port is flushed. 
//else check is message is for robot 2 <2...>
        else if (instruction[j+1] == '2')
        {
          //reset resend message to blank
          resendMessage = "";
          int k = 0;
          //loop around the instruction message
          for (k = j; k<(j+10); k++)
          {
            //concatenate all characters of message
            resendMessage += instruction[k];
          }
          Serial.print(0); //flush the serial port
          Serial.print(resendMessage); //send the message onto Robot 2
        }
That is all the code that needs to be added/changed for robot 1 to parse the instruction message.

SCORE PACKET CODE

To update the score, a score packet needs to be sent on to robot 2, who will then send it on to the Games Master, which keeps track of all scores. Therefore, when the robot is hit, it needs to send a score packet. Firstly, the variables need to be stated.
//string to print to contact games master - in the following form:
//G (games master) 2 (robot 2's score) 10 (how much to increment score)
String GMscoreLR = "[G210]";
String GMscoreB = "[G215]";

As can be seen, the robot ID has been stated has 2, even though this code is on robot 1. This is because robot 1 has been hit, but it has been hit by robot 2 and so it is robot 2's score that needs to be updated. 

The reason for two different score packets is for the two interrupts that are used to detect when the robot is hit. This allows for two different scores to be implemented. Therefore, in interrupt one the following code needs to be added
    Serial.print(0);//flush the serial port
    //print message to GM to increment Robot 2's score
    Serial.println(GMscoreLR);
In the other interrupt, this code needs to be added:
    Serial.print(0);//flush the serial port
    //print message to GM to increment Robot 2's score
    Serial.println(GMscoreB);
These interrupts print the correct string which will then be sent on to robot 2. 

LASERBOT TWO CODE

INSTRUCTION PACKET CODE

Again, the array used to store the instruction needs to be made bigger to accommodate the extra characters being sent. 
char instruction [10]; //instruction sent to arduino 
Next, a String needs to be introduced so that a message can be resent on to the Games Master.
//message to send on to Games Master
String resendMessage = "";
Again, inspecting the previous code for the robot, the first part of void loop() stays the same - while there is serial data available, read the data and store in the instruction array. Next, check to see if the instruction starts and ends with the characters '<' and '>' (remembering to change the index by one for the ending character). 

Next, another if statement needs to be added to check whether or not the instruction received is for robot 2. This is not really needed as anything that is sent to robot 2 will be for it, but it is extra error checking.
//check the message is for  robot 2 <2...>
        if (instruction[j+1] == '2')
        {
If the message is for robot 2, the normal parsing takes place (parse the rest of the message to deal with lasers, servos and motors). That is all the code needed for the instruction packet. 

SCORE PACKET CODE

For the score packet, as well as sending its own score packet, robot 2 needs to process robot 1's score packet. Let's deal with that first. 

In void loop(), there is an if statement to check for the characters '<' and '>.' After this statement and else if statement needs to be included to check for the characters '[' and ']'. 
//if message is score packet for the Games Master
      else if ((instruction[j] == '[') &&  (instruction[j+5] == ']'))
      {
        //reset resend message to blank
          resendMessage = "";
          int k = 0;
          //loop around the instruction message
          for (k = j; k<(j+6); k++)
          {
            //concatenate all characters of message
            resendMessage += instruction[k];
          }
          Serial.print(0); //flush the serial port
          Serial.print(resendMessage); //send the message onto games master
      }
In this else-if statement, the message is concatenated together and then sent on to the Games Master. 

For robot 2's own score, the same code as robot 1 needs to be included in the interrupts.
    Serial.print(0);//flush the serial port
    //print message to GM to increment Robot 2's score
    Serial.println(GMscoreLR);
And in the other interrupt, this code needs to be added:
    Serial.print(0);//flush the serial port
    //print message to GM to increment Robot 2's score
    Serial.println(GMscoreB);
That concludes all the code that needs to be updated on the robots. Please see post BLAH for the parsing of the Games Master packets in Processing.

XBee Configuration: Coordinator and Router (Circle Network)

Category : , , 1

After trying a point to point network, and a point to multipoint network, it was decided that a circle network would be implemented. 

Circle network
For this, one XBee needed to be set up as a coordinator and two XBees needed to be set up as routers. 

WHICH ONE TO BE THE COORDINATOR?

For this circle network, the XBees were configured several times until the network worked. Trial and error was used, changing which robot or games master should be a coordinator or router. In order to test the system, a simple test was done by sending integers around the circle, which were read and retransmitted by the correct XBees. Eventually, the setup that worked was:
Coordinater - Robot 2
Router 1 - Games Master
Router 2 - Robot 1
Coordinator and Router Setup for Circle Network

Point to Multipoint - Broadcast Network Design

Category : , , 0

This method for configuring Xbees ended up being too slow for this projects requirements, due to the Zigbee protocol's requirement for delays to be in place to allow packets to propogate through the whole network.

A simple solution could be to simply use another Xbee, and have a separate channel for each robot, however this would require another shield and Arduino as an interface.  The budget and hardware is not available for this.  Instead a 'circle' network configuration was devised to allow all devices to communicate at rate that was suitable.

In a broadcast network, one module is set as the 'master'.  This sends out all it's messages to all devices on the network.  The devices can then check an ID that is sent as part of the message, and then decide whether they need to act upon it or not.  This sounded suitable for this project, as both robots could then receive all messages, and only carry out the instructions if the ID matched the number of the robot.  They can then reply to the master if they are hit, or as required through a uni-cast connection which is configured in their modules. This configuration is illustrated below.
Broadcast configuration for an Xbee network
This is not as simple as the standard uni-cast point to point network with two modules that is often employed with Xbees so direct configuration of the Xbee's firmware was required.

Point to Point Xbee Network Testing

Friday, 4 January 2013 Category : , , 2

Xbees are wireless modules which interface radio transmissions with standard serial input output.  All transmission issues are taken care of by the Zigbee protocol (which is the protocol that Xbee Series 2 modules use).  This ease of use means Xbees are often used as drop in replacements for a serial cable as can be seen in the diagram below.  In this configuration the module's default settings mean that a link can be set up quickly and easily.
Xbees in Unicast mode
This is called 'uni-cast', when a module knows the address of it's recipient, and sends data directly to it.  In this example, the second module also knows the address of the first Xbee, and therefore can reply back to it.

Xbee Shields

In this project, shields are used to interface the Xbee module with the Arduino Uno on the robots.  The main component on these shields is a voltage regulator to convert the Arduino's 5V logic to the Xbee's 3.3V. Without this the Xbee module could be damaged.

Raspberry Pi Setup

Wednesday, 12 December 2012 Category : , , 0


The offboard system uses the raspberry pi as the base station to send and receive signals from the iPads over the network interface and process the messages and send control packets to the game master Xbee.


This Xbee is connected to the raspberry pi using a slice of pi interface board which sends and receives serial signals from the serial GPIO TX and RX pins on the raspberry pi to the UART data in and UART data out pins on the Xbee.

iPad to Computer Comms

Wednesday, 28 November 2012 Category : , , 1

Further research into the game's communication systems led to the discovery of the OSC (Open Sound Control) protocol. This is often used instead of MIDI in electronic musical instruments to allow communication and control between different devices.

Much of the inspiration for this section of the project came from Pete-O's excellent work on OSC and the Arduino which can be found here.

For this project we used TouchOSC on the iPad, as there are two iPads available for use within the group (freeing up iPhones and iPod touches for possible camera use).  This app costs £3, and includes a free interface designer for Windows. Using this designer, an application was developed to send robot control signals from the iPad, this interface can be seen below.
iPad interface for control - note space at the top for future game messages
Once run, the app was configured with host IP address and port of the Processing application which is discussed later.

Processing is an IDE and language that builds on Java, but with a simpler graphics programming model.  This is ideal for us, as it works very well alongside the Arduino development environment, which was developed on the same interface.  This makes it relatively easy, and well documented online to get an Arduino talking to the Processing sketch.  In addition, there is an OSC library available, allowing us to parse and process OSC messages received over a local network.  The OSC library has been developed by Andreas Schlegel, and is available here.

Understanding Control Signals on the Arduino

Category : , , 0

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
    i++;
    //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)
  Serial.begin(9600);
  servoX.attach(5);
  servoY.attach(6);
  
  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. 

Communications

Tuesday, 30 October 2012 Category : , , 0

This system involves controlling the robots through a smartphone and notifying the games master when game events happen, such as a robot being hit, game start/stop etc.

OUTLINE OF COMMUNICATIONS LINKS REQUIRED
Different communication options and configurations were considered in terms of cost and ease of implementation.

Theme MXS. Powered by Blogger.