LaserBots: User Manual
Friday, 18 January 2013 Category : Game, Implementation, Phase Two, User Manual 1
Home > Implementation
Friday, 18 January 2013 Category : Game, Implementation, Phase Two, User Manual 1
Category : Implementation, Phase Two 0
Category : Implementation, Phase Two 0
Category : Implementation, Phase Two 0
#include <Servo.h> #include "avr/interrupt.h" char instruction [10]; //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 servo String stringYCoord = ""; int intYCoord; //y coordinate for servo Servo servoX; //servo x Servo servoY; //servo y
Thursday, 17 January 2013 Category : Implementation, Phase Two 0
Wednesday, 16 January 2013 Category : Comms, Design, Implementation, Phase Two 0
Sunday, 13 January 2013 Category : Comms, Implementation, Phase Two 0
![]() |
| TouchOSC configuration screen |
Friday, 11 January 2013 Category : Implementation, Phase Two 1
| PCB Schematic |
Tuesday, 8 January 2013 Category : Implementation, Phase Two 0
![]() |
| Completed Prototype |
Monday, 7 January 2013 Category : Comms, Implementation, Phase Two 0
![]() |
| Circle Network Setup |
char instruction [10]; //instruction sent to arduinoNext, 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).
//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.
//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]";
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. char instruction [10]; //instruction sent to arduinoNext, 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).
//check the message is for robot 2 <2...>
if (instruction[j+1] == '2')
{
//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. 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.
Category : Comms, Implementation, Phase Two 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 |
![]() |
| Coordinator and Router Setup for Circle Network |
Category : Implementation, Phase Two 0
Category : Comms, Implementation, Phase Two 0
| Broadcast configuration for an Xbee network |
Friday, 4 January 2013 Category : Comms, Implementation, Phase Two 2
![]() |
| Xbees in Unicast mode |
Wednesday, 12 December 2012 Category : Comms, Implementation, Phase Two 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.
Category : Detection, Implementation, Laser, Phase Two 0
Monday, 10 December 2012 Category : Implementation, Phase Two 0
The Tamiya tank systems, gearbox, tracks and platforms all came with instructions and although they had many small parts and were time consuming to assemble were otherwise relatively straightforward to assemble and test.
![]() |
| Wheel and Track Parts |
![]() |
| Gearbox Parts |
![]() |
| Gearbox Assembly |
![]() |
| Platform, wheel and track assembly |
![]() |
| Full Assembly |
![]() |
| Battery and motor chip installation for testing |
![]() |
| Motor chip connected to gearbox |
![]() |
| Ready for Arduino |
![]() |
| Testing
For testing code see
|
Wednesday, 28 November 2012 Category : Comms, Implementation, Phase Two 1
![]() |
| iPad interface for control - note space at the top for future game messages |
Category : Comms, Implementation, Phase Two 0
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
//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] == '>'))
{
//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
//turn laser on
if (instruction[j+1] == 'F')
{
digitalWrite(laser, LOW);
}
//turn laser off
if (instruction[j+1] == 'f')
{
digitalWrite(laser, HIGH);
}
//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;
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);
}
Wednesday, 21 November 2012 Category : Detection, Implementation, Laser, Phase Two 3
![]() |
| Arduino Laser Connections |
![]() |
| LDR and circuit symbol |
![]() |
| Mini Photocell |
![]() |
| LDR circuit |
/*
int LDR = 7; //LDR attached to pin 7
int laser = 8; //Laser attached to pin 8
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the LDR's pin an input:
pinMode(LDR, INPUT);
//make the laser's pin an output:
pinMode(laser, OUTPUT);
digitalWrite(laser, LOW);//turn laser on
}
Now that the pins have been set up, code can be written to interact with the detector circuit that has been built. When the LDR is hit with the laser, the output changes from high to low. This change can be picked up by the Arduino by doing a digital read of the pin. A digital read reads the value from a specified digital pin, either HIGH or LOW. If the value read is LOW, the Arduino can state that it has been hit, else if it is HIGH it won't do anything, as can be seen in the following code.
// the loop routine runs over and over again forever:
void loop() {
// read the input pin:
int hitState = digitalRead(LDR);
//LDR goes low when it has been hit
if (hitState == 0)
{
Serial.println("HIT");
delay(2000); // delay in between reads for stability
}
This code can now be put together and uploaded onto the Arduino. The Arduino and detector circuit should be set up as follows.#include "avr/interrupt.h"Firstly, the pin that the LDR was on was changed from 7 to 2 (as pin 2 has an interrupt attached to it). In the setup method, the following code was added to enable the interrupt and set the interrupt to trigger on a falling edge.
sei(); //Enable global interrupts EIMSK |= (1 << INT0); //Enable external interrupt INT0 EICRA |= (1 << ISC01); //Trigger INT0 on falling edgeAn interrupt service routine (ISR) then needs to be written. An ISR is the code that is run when the interrupt is triggered. For the moment, the Arduino will just print out that it has been hit.
//interrupt service routine for when the LDR is hit
ISR(INT0_vect)
{
Serial.println("HIT INTERRUPT");
}
In the main loop of the program, the digital read is removed, as that is no longer needed. To get the program to still do something for the interrupt to interrupt, the Arduino will just print out that it is waiting for the interrupt. The whole code now looks like this:
int LDR = 2; //LDR attached to pin 2 (as pin 2 has an interrupt on it)
int laser = 8; //Laser attached to pin 8
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the LDR's pin an input:
pinMode(LDR, INPUT);
//make the laser's pin an output:
pinMode(laser, OUTPUT);
sei(); //Enable global interrupts
EIMSK |= (1 << INT0); //Enable external interrupt INT0
EICRA |= (1 << ISC01); //Trigger INT0 on falling edge
digitalWrite(laser, HIGH);//turn laser on
}
// the loop routine runs over and over again forever:
void loop() {
//print something so program has something to do
Serial.println("Waiting for interrupt");
delay(1000); //wait one second
}
//interrupt service routine for when the LDR is hit
ISR(INT0_vect)
{
Serial.println("HIT INTERRUPT");
}
Running the code and watching on a serial monitor, the program outputs "Waiting for interrupt" every second until the interrupt is called, in which case it prints "HIT INTERRUPT".
#include "avr/interrupt.h"
int LDR = 2; //LDR attached to pin 2 (as pin 2 has an interrupt on it)
int laser = 8; //Laser attached to pin 8
int score = 0; //score of the robot
int scoreFront = 10; //score of hitting the LDR
//introduce 5 second interval after hit before another hit can occur
int interval = 5000;
long lastBlinkTime = 0; //variable used with millis
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the LDR's pin an input:
pinMode(LDR, INPUT);
//make the laser's pin an output:
pinMode(laser, OUTPUT);
sei(); //Enable global interrupts
EIMSK |= (1 << INT0); //Enable external interrupt INT0
EICRA |= (1 << ISC01); //Trigger INT0 on falling edge
digitalWrite(laser, HIGH);
}
// the loop routine runs over and over again forever:
void loop() {
//make program do something
digitalWrite(laser, HIGH);
}
//interrupt service routine for when the LDR is hit
ISR(INT0_vect)
{
unsigned long hitMillis = millis();
//if there has been more than 5 seconds since the last hit
if ((hitMillis - lastBlinkTime) > interval)
{
lastBlinkTime = hitMillis;
//increment score
score = score + scoreFront;
Serial.println("Hit Interrupt");
Serial.println(score);
}
}
Running this code, when the LDR is hit, the ISR is called and "Hit Interrupt" along with a score is printed, for example 10 for the first hit. When the user tries to hit the LDR again, nothing happens until 5 seconds has passed. The user hits the LDR again and now the Arduino prints out "Hit Interrupt" with a score, now equal to 20. This concludes the code that is needed for laser detection.