Hi,
Been searching around now for a few days without much luck. I'm trying to get my head around a way to toggle between two modes for my robot. The first mode is "remote control" where I control the robot using my keyboard sending serial commands over a xbee connection, the second mode is autonomous where actions of the robot are controlled using input from various sensors. I have the code for each mode working separately now what I'd like to do is this:
- Start the robot in autonomous mode and let it do its thing.
- If the robot starts to get in trouble, override autonomous mode with a key press (say the 'o' key).
- Control robot using keyboard to get it out of trouble.
- Toggle back to autonomous mode and let it go
As I said I have the two separate modes working great but i can't get my head around making the switch between the two.
I have started to play around with finite states using the FSM library but have not had much luck.
A kick in the right direction would be greatly appreciated.
Here is my FSM code I've been playing around with. To make things easier, I've made the autonomous section of the code simple for now. It just turns the motors forward for a few seconds and then stops. It sort of works but seems to be a bit unpredictable, I'm pretty sure I don't have the keyboard toggle setup right.
Thanks for any help
#include <FiniteStateMachine.h>
#include <NewSoftSerial.h>
NewSoftSerial mySerial(4, 3); //int rx, int tx)
const byte NUMBER_OF_STATES = 2;
int motor_reset = 12; //motor reset pin
//initialize states
State remote = State(remoteOn);
State automatic = State(autoOn);
FSM autoStateMachine = FSM(automatic); //start in automatic mode
void setup()
{
pinMode(motor_reset, OUTPUT); //motor reset pin
Serial.begin(9600);
mySerial.begin(9600);
digitalWrite(motor_reset, LOW);
delay(50);
digitalWrite(motor_reset, HIGH);
delay(50);
}
void loop () {
if (Serial.available() > 0) {
int onByte = Serial.read(); //check for keyboard letter o press to switch states (pretty sure this doesn't work)
if (onByte == 'o') {
autoStateMachine.transitionTo(remote); //change to remote
}
else {
autoStateMachine.transitionTo(automatic); //use automatic mode (need a toggle in here somewhere)
}
}
autoStateMachine.update();
}
void remoteOn() { //remote stuff - this works
if (Serial.available() > 0) {
int inByte = Serial.read();
switch (inByte) {
case 'w':
motorforward();
break;
case 's':
motorreverse();
break;
case 'd':
rotateccw();
break;
case 'a':
rotatecw();
break;
default:
motorstop();
}
}
}
void autoOn() { //simple auto mode for now
motorforward();
delay(5000);
motorstop();
}
//subroutine motor forward
void motorforward()
{
//left motor
unsigned char buff1[6];
buff1[0] = 0x80; //start byte - do not change
buff1[1] = 0x00; //device type byte - do not change
buff1[2] = 0x01; //Motore number and direction byte; motor one = 00,01
buff1[3] = 0x7F; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff1[i], BYTE);
}
//right motor
unsigned char buff2[6];
buff2[0] = 0x80; //start byte - do not change
buff2[1] = 0x00; //device type byte - do not change
buff2[2] = 0x03; //Motore number and direction byte; motor two = 02,03
buff2[3] = 0x7F; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff2[i], BYTE);
}
}
//subroutine motor reverse
void motorreverse()
{
//left motor
unsigned char buff3[6];
buff3[0] = 0x80; //start byte - do not change
buff3[1] = 0x00; //device type byte - do not change
buff3[2] = 0x00; //Motore number and direction byte; motor one = 00,01
buff3[3] = 0x46; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff3[i], BYTE);
}
//right motor
unsigned char buff4[6];
buff4[0] = 0x80; //start byte - do not change
buff4[1] = 0x00; //device type byte - do not change
buff4[2] = 0x02; //Motore number and direction byte; motor two = 02,03
buff4[3] = 0x46; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff4[i], BYTE);
}
//subroutine motor all stop
}
void motorstop()
{
//left motor
unsigned char buff3[6];
buff3[0] = 0x80; //start byte - do not change
buff3[1] = 0x00; //device type byte - do not change
buff3[2] = 0x00; //Motore number and direction byte; motor one = 00,01
buff3[3] = 0x00; //Motor speed "0 to 128" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff3[i], BYTE);
}
//right motor
unsigned char buff4[6];
buff4[0] = 0x80; //start byte - do not change
buff4[1] = 0x00; //device type byte - do not change
buff4[2] = 0x02; //Motore number and direction byte; motor two = 02,03
buff4[3] = 0x00; //Motor speed "0 to 128" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff4[i], BYTE);
}
}
void rotateccw()
{
//left motor
unsigned char buff3[6];
buff3[0] = 0x80; //start byte - do not change
buff3[1] = 0x00; //device type byte - do not change
buff3[2] = 0x01; //Motore number and direction byte; motor one = 00,01
buff3[3] = 0x40; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff3[i], BYTE);
}
//right motor
unsigned char buff4[6];
buff4[0] = 0x80; //start byte - do not change
buff4[1] = 0x00; //device type byte - do not change
buff4[2] = 0x02; //Motore number and direction byte; motor two = 02,03
buff4[3] = 0x40; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff4[i], BYTE);
}
}
void rotatecw()
{
//left motor
unsigned char buff3[6];
buff3[0] = 0x80; //start byte - do not change
buff3[1] = 0x00; //device type byte - do not change
buff3[2] = 0x00; //Motore number and direction byte; motor one = 00,01
buff3[3] = 0x40; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff3[i], BYTE);
}
//right motor
unsigned char buff4[6];
buff4[0] = 0x80; //start byte - do not change
buff4[1] = 0x00; //device type byte - do not change
buff4[2] = 0x03; //Motore number and direction byte; motor two = 02,03
buff4[3] = 0x40; //Motor speed "0 to 127" in hex
for(int i=0;i<4;i++) {
mySerial.print(buff4[i], BYTE);
}
}