Balancing robot for dummies

** 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 :slight_smile:
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");
}

...........