this is how I did the Tx controller for my Rover 5.
#define deadBand 20
#define Xraw_center 534
#define Yraw_center 471
#define Joy_X_pin A0
#define Joy_Y_pin A1
char button0=3, button1=4, button2=5, button3=6;
char sel=2;
int rawX;
int rawY;
int yaxis;
int xaxis;
int xspeed;
int yspeed;
char speedCom;
char steerCom;
char speedArray[7][7] ={
{'v','v','v','v','v','v','v'},
{'v','c','c','c','c','c','v'},
{'v','c','x','x','x','c','v'},
{'v','c','x','z','x','c','v'}, //
{'v','c','x','x','x','c','v'},
{'v','c','c','c','c','c','v'},
{'v','v','v','v','v','v','v'},
};
char steerArray[7][7] ={
{'7',' ',' ','8',' ',' ','9'},
{' ','7',' ','8',' ','9',' '},
{' ',' ','7','8','9',' ',' '},
{'4','4','4','5','6','6','6'},
{' ',' ','1','2','3',' ',' '},
{' ','1',' ','2',' ','3',' '},
{'1',' ',' ','2',' ',' ','3'},
};
void setup(void)
{
pinMode(sel, INPUT); //Set the Joyaxisstick "Select"button as an input
digitalWrite(sel, HIGH); //Enable the pull-up resistor on the select button
pinMode(button0, INPUT); //Set the Joyaxisstick button 0 as an input
digitalWrite(button0, HIGH); //Enable the pull-up resistor on button 0
pinMode(button1, INPUT); //Set the Joyaxisstick button 1 as an input
digitalWrite(button1, HIGH); //Enable the pull-up resistor on button 1
pinMode(button2, INPUT); //Set the Joyaxisstick button 2 as an input
digitalWrite(button2, HIGH); //Enable the pull-up resistor on button 2
pinMode(button3, INPUT); //Set the Joyaxisstick button 3 as an input
digitalWrite(button3, HIGH); //Enable the pull-up resistor on button 3
Serial.begin(9600); //Turn on the Serial Port at 9600 bps
Serial3.begin(9600); //Turn on the XBee Serial Port at 9600 bps
}
void loop(void)
{
// Get joystick position
rawX = analogRead(Joy_X_pin);
rawY = analogRead(Joy_Y_pin);
xaxis = rawX;
yaxis = rawY;
xspeed = map(rawX,0,1023,0,7);
yspeed = map(rawY,0,1023,0,7);
Serial.print("X,Y - ");
Serial.print(xaxis);
Serial.print(" , ");
Serial.println(yaxis);
Serial.print("speed - ");
Serial.print(xspeed);
Serial.print(" , ");
Serial.println(yspeed);
//speed
if (rawX>0){
if (rawX<1023) {speedCom = 'v';}
}
if (rawX>128){
if (rawX<896) {speedCom = 'c';}
}
if (rawX>256){
if (rawX<768) {speedCom = 'x';}
}
if (rawX>384){
if (rawX<896) {speedCom = 'z';}
}
if ((rawX<=(Xraw_center-deadBand))&&(rawX>=(Xraw_center-deadBand))) {speedCom = ' ';}
if (rawY>0){
if (rawY<1023) {speedCom = 'v';}
}
if (rawY>128){
if (rawY<896) {speedCom = 'c';}
}
if (rawY>256){
if (rawY<768) {speedCom = 'x';}
}
if (rawY>384){
if (rawY<896) {speedCom = 'z';}
}
if ((rawY<=(Yraw_center-deadBand))&&(rawY>=(Yraw_center-deadBand))) {speedCom = ' ';}
//steering
if (xaxis<(Xraw_center-deadBand)) //left of centre
{
if (yaxis<Yraw_center-deadBand)
{steerCom = '1';}
else if ((yaxis>(Yraw_center-deadBand))&&(yaxis<(Yraw_center+deadBand)))
{steerCom = '4';}
else if (yaxis>Yraw_center+deadBand)
{steerCom = '7';}
}
else if (xaxis>=(Xraw_center-deadBand)&&(xaxis<=(Xraw_center+deadBand))) // centre
{
if (yaxis<(Yraw_center-deadBand))
{steerCom = '2';}
else if ((yaxis>=(Yraw_center-deadBand))&&(yaxis<=(Yraw_center+deadBand)))
{steerCom = '5';}
else if (yaxis>(Yraw_center+deadBand))
{steerCom = '8';}
}else if (xaxis>(Xraw_center+deadBand)){ //right of centre
if (yaxis<(Yraw_center+deadBand)) {steerCom = '3';}
else if ((yaxis<(Yraw_center-deadBand))&&(yaxis>(Yraw_center+deadBand)))
{steerCom = '6';}
else if (yaxis>(Yraw_center+deadBand))
{steerCom = '9';}
}
Serial.print("Speed - ");
Serial.println(speedCom);
Serial3.print(speedCom);
delay(200);
Serial.print(" Direction - ");
Serial.println(steerCom);
Serial3.print(steerCom);
delay(200);
}
It is set up for to map a joystick to look like a numeric keypad.
the number keys control direction,
z,x,c,v control speed.
Using a keyboard you select a speed, then a direction.
On the Rover 5 Mega -
/* My Rover 5 basic receiver for use with a Sparkfun Monster Motor Shield
on A Mega
It's basically the example for the monster motor shield
*/
#define BRAKEVCC 0
#define CW 1
#define CCW 2
#define BRAKEGND 3
#define CS_THRESHOLD 100
/* VNH2SP30 pin definitions
xxx[0] controls '1' outputs
xxx[1] controls '2' outputs */
int inApin[2] = {7, 4}; // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input
int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
int turnRate = 8;
int leftspeed = 80;
int rightspeed = 80;
int statpin = 13;
void setup()
{
Serial.begin(9600);
Serial3.begin(9600);
pinMode(statpin, OUTPUT);
// Initialize digital pins as outputs
for (int i=0; i<2; i++)
{
pinMode(inApin[i], OUTPUT);
pinMode(inBpin[i], OUTPUT);
pinMode(pwmpin[i], OUTPUT);
}
// Initialize braked
for (int i=0; i<2; i++)
{
digitalWrite(inApin[i], LOW);
digitalWrite(inBpin[i], LOW);
}
}
void loop()
{
while (Serial3.available() < 1) {} // Wait until a character is received
char val = Serial3.read();
Serial.println(val); // for debugging
switch(val) // Perform an action depending on the command
{
case '6':// pivot right
{
motorGo(0, CW, leftspeed);
motorGo(1, CW, rightspeed);
}
break;
case '4':// pivot left
{
motorGo(0, CCW, leftspeed);
motorGo(1, CCW, rightspeed);
}
break;
case '9'://fwd right
{
motorGo(0, CW, leftspeed - turnRate);
motorGo(1, CW, rightspeed + turnRate);
}
break;
case '1'://rev left
{
motorGo(0, CW, leftspeed + turnRate);
motorGo(1, CW, rightspeed - turnRate);
}
break;
case '3'://rev right
{
motorGo(0, CCW, leftspeed - turnRate);
motorGo(1, CCW, rightspeed + turnRate);
}
break;
case '7'://fwd left
{
motorGo(0, CCW, leftspeed + turnRate);
motorGo(1, CCW, rightspeed - turnRate);
}
break;
case '8'://fwd
{
motorGo(0, CW, leftspeed);
motorGo(1, CCW, rightspeed);
}
break;case '2'://rev
{
motorGo(0, CCW, leftspeed);
motorGo(1, CW, rightspeed);
}
break;
case 'z'://min
{
leftspeed = 80;
rightspeed = 80;
}
break;
case 'x'://slow
{
leftspeed = 100;
rightspeed = 100;
}
break;
case 'c'://fast
{
leftspeed = 128;
rightspeed = 128;
}
break;
case 'v'://max
{
leftspeed = 255;
rightspeed = 255;
}
break;
default:
{
motorOff(0);
motorOff(1);
leftspeed = 0;
rightspeed = 0;
}
break;
}
}
void motorOff(int motor)
{
// Initialize braked
for (int i=0; i<2; i++)
{
digitalWrite(inApin[i], LOW);
digitalWrite(inBpin[i], LOW);
}
analogWrite(pwmpin[motor], 0);
}
/* motorGo() will set a motor going in a specific direction
the motor will continue going in that direction, at that speed
until told to do otherwise.
motor: this should be either 0 or 1, will selet which of the two
motors to be controlled
direct: Should be between 0 and 3, with the following result
0: Brake to VCC
1: Clockwise
2: CounterClockwise
3: Brake to GND
pwm: should be a value between 0 and 255, higher the number, the faster
it'll go
*/
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
if (motor <= 1)
{
if (direct <=4)
{
// Set inA[motor]
if (direct <=1)
digitalWrite(inApin[motor], HIGH);
else
digitalWrite(inApin[motor], LOW);
// Set inB[motor]
if ((direct==0)||(direct==2))
digitalWrite(inBpin[motor], HIGH);
else
digitalWrite(inBpin[motor], LOW);
analogWrite(pwmpin[motor], pwm);
}
}
}
From here you could "vectorize" each character, you'll need to have some kind of odometer to see how far it went.
If you make up a list of unit vectors for each character you could then scale them to get different size characters.