** Balancing robot for dummies **
Part seven: Xbee wireless control, KasBot V 3.0
The objective is to obtain basic motion control (Forward/Backward, Stop Right/Left)
Xbee modules act as a serial line replacement, a USB cable without the cable
See post #82 for more info
1) controller side:
Shopping list at post #77
Transmitter with Nunchuck joystick controller is shown on post #107
The additional micro joystick and the 3 LED's will be used for advanced features wich are beyong the scope of this basic KasControl V1.0
Nunchuk_kas.h does take care of the I2C communication with the joystick
// Nunchuck_kas.h joystick functions ----------------------------------------------------------------
#include "Wprogram.h"
#include <Wire.h>
static uint8_t nunchuck_buf[6]; // array to store nunchuck data,
void nunchuck_init() {
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends a zero.
Wire.endTransmission(); // stop transmitting
}
void nunchuck_send_request() { // Send a request for data to nunchuck
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}
char nunchuk_decode_byte (char x) { // Encode data to format that most wiimote drivers
x = (x ^ 0x17) + 0x17; // except only needed if you use one of the regular
return x; // wiimote drivers
}
int nunchuck_get_data() { // Receive data back from the nunchuck
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) { // receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
if (cnt >= 5) return 1; // If we recieved the 6 bytes, then go print them
return 0; // failure
} // returns 1 on success read, returns 0 on failure
int nunchuck_joyx() { // returns value of x-axis joystick
return nunchuck_buf[0];
}
int nunchuck_joyy() { // returns value of y-axis joystick
return nunchuck_buf[1];
}
This is a strip down version of the code that can be found in the Arduino Playground section.
We only use the joystick data, (we have enough accelerometers in this project ;))
More info on wiring and code here
The main code uses a communication protocol based on 3 Bytes:
controlByte = 'd' (just says "hey, I am coming with new joystick data !!")
dataByte_1 = value of y-axis joystick
dataByte_2 = value of x-axis joystick
To reduce traffic, data is only sent when joystick is moved
// ** Kas Control V10 Balancing bot RC with nunchuk **
// Yellow: Clock SCL (AI5) Red: 3.3V Green: Data SDA(AI4) Write: Ground
// serial data format: <controlByte> <dataByte_1> <dataByte_2> <CR>
// V1.0 basic control
#include <Wire.h>
#include "Nunchuck_kas.h"
int refreshTime = 100; // time in millisecs between Nunchuck poolings
long lastPulse = 0;
char controlByte = 0;
char dataByte_1 = 0; // joystick data
char dataByte_2 = 0;
void setup() {
Serial.begin(19200);
nunchuck_init(); // send the initilization handshake
delay(100);
nunchuck_joyx();
nunchuck_joyy();
}
void loop() {
if (millis() - lastPulse >= refreshTime) { // x ms have passed
checkNunchuck();
lastPulse = millis(); // save the time of last pulse
}
}
void checkNunchuck() {
static int Byte1_ant, Byte2_ant;
nunchuck_get_data();
controlByte = 'd';
dataByte_1 = map(nunchuck_joyy(), 27, 218, 0, 40); // nunchuck joystick North/South
dataByte_2 = map(nunchuck_joyx(), 27, 218, 0, 40); // nunchuck joystick East/West
dataByte_1 = constrain(dataByte_1, 0, 40);
dataByte_2 = constrain(dataByte_2, 0, 40);
if((dataByte_1!=Byte1_ant)||(dataByte_2!=Byte2_ant)) {
updateBot();
Byte1_ant = dataByte_1;
Byte2_ant = dataByte_2;
}
}
void updateBot() { // send data stream
Serial.print(controlByte);
Serial.print(dataByte_1);
Serial.print(dataByte_2);
Serial.print("\n");
}
...........