Robots with Wheels

Enter Your Electronics & Design Project for Your Chance to Win a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

This project started life as a challenge.

The local Robot Club (who spend time on everything except robots) was looking to get back into robots since they had a sumo ring.

 

We talked about making something small and decided on the 300g class.

It allowed for new and younger members to make something which could compete, and wouldn't cost a fortune, or require lifting gear.

 

 

 

 

 

 

Nintendo Wii

Since our bots were not intended to be autonomous, a method of controlling the bot was required.

As many people know the Nintendo company make a very good gaming platform.

One of the spin-offs was their Nunchuck, and as expected third party suppliers developed a wireless version of the Nunchuck.

The interface to the Wiimote is I2C which is ideal to interface to a microcontroller..

 

Using one of these provided all the control necessary in a very cheap package.

 

 

 

 

Chassis

The chassis is a lightweight wedge design.

The idea was to lift the competitor rendering them immobile and therefore securing a victory.

 

I made it oversized and then flipped it upside down and scribed the finished height with a small taper towards the rear.

 

 

It is configured as a "tail drager" which is a term used on planes where the tail is supported by a piece of metal and is dragged across the surface, rather than having a proper wheel.

In this case I used a plastic bolt and rounded and smoothed it using a battery drill.

 

 

 

Electronics

The black box houses an Arduino Nano, and some Mosfet driver IC's.

The pictures show an 11.1 volt Lithium battery, but it works on a 7.2 volt battery which is lighter and allowed it to weigh 305grams.

 

The higher voltage battery was an attempt to eliminate a glitch that caused the loss of connection between the Nunchuck joystick and the receiver.

Sadly it also overtaxed the original mosfet drivers which emitted the magic smoke and stopped working.

 

 

Software

The controller is an Arduino, and the biggest part is the motor control.

The joystick provides a value between 0 and 255 in the x direction and a 0 to 255 in the y direction. This is converted and provides proportional control.

The C button allows the behaviour to be modified.

 

For movement at full lock, the default is to just power the applicable motor, while leaving the other wheel stopped.

But by operating the button, the software will drive the opposite motor in the other direction, meaning it will rotate on the other wheel.

 

There is a glitch that I've never got to the bottom of, where the Joystick (transmitter) and the receiver lose connection.

The connection is manual and when it occurs there is no method of detecting it in the software, so consequently it can take off when you least expect it.

I managed to tame it by improving the power supply to the receiver, but I suspect more work is needed before I can tick it off the list.

 

 

/* .......................................................................
   Code to control a robot using a Wii Nunchuk
    most of the Wii code was from the Arduino forum ..thanks to the many contributors.
   
   Here is the bitmapping for the standard nunchuk mapping
      Bit
   Byte     7 6 5 4 3 2 1 0
     0 SX<7-----------------------------------------------------0>
     1 SY<7-----------------------------------------------------0>
     2 AX<9-----------------------------------------------------2>
     3 AY<9-----------------------------------------------------2>
     4 AZ<9-----------------------------------------------------2>
     5 AZ<1----0>   AY<1-------0>   AX<1-------0>      BC BZ
   
   The Arduino I2C uses 7 bits, therefore the MP address (0xA6) becomes 0x53, and the (0xA4) becomes 0x52
      
   Hardware Arduino with ATMega 328
   Connections 
   
   Pin assignments
   Analog4 SCA with pullup of 2k7 to 3.3 volts
   Analog5 SCL with pullup of 2k7 to 3.3 volts
   Pin 3 (pwm) Right Motor enable
   Pin 4  In1  Stepper
   Pin 5  In2  Stepper
   Pin 6  In3  Stepper
   Pin 7  In4  Stepper
   
   Pin 11 (pwm)Left Motor enable
   Pin 12 Forward motor control 
   Pin 13 Reverse motor control
   Nunchuk gets 3.3v
   
   There isn't much else as it was designed for a 300g robot, and I wanted some protection.
   
  
   Modified by Mark Beckett
   July 2010
   
   
    References:
     _     _   _
    | |__ | |_| |_ _ __  
    | '_ \| __| __| '_ \ 
    | | | | |_| |_| |_) |
    |_| |_|\__|\__| .__/ 
                  |_|        http://www.network-science.de/ascii/ for font (standard, no, left, no, 80)
  
   Nunchuk plug details are at http://voidbot.net/wii-addapter.html (thanks very much)
   ************************************
   To Do:
    Detect if the interface has disconnected and don't go full speed.
    Tidy the code around the seering area ...(hey it was late Sunday night and complex equations hurt my head) 
    Allow for instances where all four motor control pins are PWM capable. (allows for spinning on the spot)
    Include controls for a lifting weapon using the Z button and the joystick.
    
    ************************************
    The Serial.print lines have been commented out, as they are unecessary when in use.
    Feel free to uncomment them during debugging. MCB
  
  */
  
  
  //setup the variables, etc
  //int ledPin = 13;
  int xID;
  #define STEPS  64   //Number of steps per revolution
  
  //Nunchuck
  uint8_t outbuf[6];           //nunchuck buffer for data
  //int cnt = 0;                 //nunchuck buffer counter
  int joy_x_axis;              //Joystick x (8 bits)
  int joy_y_axis;              //Joystick y (8 bits)
  int z_button;
  int c_button;
  
  // Motor Movement              I used the pins that match some of the common motor shields.
  int RightEn = 3;            //Pin 3 Right Enable
  int LeftEn = 11;            //Pin 11 Left Enable
  int Forward = 12;           //Pin 12 Forward
  int Reverse = 13;           //Pin 13 Reverse
 
  
  int Speed;                  // This is the amount of forward/reverse applied
  int RightAmount;            // This is the PWM amount sent to the RightEn pin
  int LeftAmount;             // This is the PWM amount sent to the LeftEn pin
  int RightCorrection;        // Right reduction to match left motor (0 to 100) 
  int LeftCorrection;         // Left reduction to match right motor (0 to 100) 
  
  int  Steps2Take;
  Stepper small_stepper(STEPS, 4, 6, 5, 7);
  
  //Wii Nunchuk
  byte data[6];                //buffer for WM+ data
  
  /*
     ____       _               
    / ___|  ___| |_ _   _ _ __  
    \___ \ / _ \ __| | | | '_ \ 
     ___) |  __/ |_| |_| | |_) |
    |____/ \___|\__|\__,_| .__/ 
                         |_| 
  
  */
  
  void setup (){
    Serial.begin (19200);
  
    pinMode(Forward, OUTPUT);
    pinMode(Reverse, OUTPUT);
    RightCorrection = 100;          // Reduce if right motor is faster than left motor
    LeftCorrection = 100;           // Reduce if left motor is faster than right motor
    // use this after ensuring that joy_x_axis at centre is 128 by uncommenting the first line in motor control.
    
    Wire.begin();
    //Serial.print ("Finished setup\n");
    //Serial.print ("Now detecting WM+\n");
    delay(100);
    
  // initiate Wii Nunchuk
      //Serial.print ("Initialising Wii Nunchuk ........");
      Wire.beginTransmission(0x52); //0xA4
      Wire.send(0xF0);
      Wire.send(0x55);
      Wire.endTransmission();
      //Serial.print (" OK done"); 
      //Serial.print ("\r\n");
      delay (100); 
      
      //Serial.print ("Set reading address at 0xFA .......");
      Wire.beginTransmission(0x52); //0xA4
      Wire.send(0xFA);
      Wire.endTransmission();
      //Serial.print(" OK done");
      //Serial.print ("\r\n");
      delay (100);
      Wire.requestFrom (0x52,6);  //0xA4
     outbuf[0] = Wire.receive();//Serial.print(outbuf[0],HEX);Serial.print(" ");
     outbuf[1] = Wire.receive();//Serial.print(outbuf[1],HEX);Serial.print(" ");
     outbuf[2] = Wire.receive();//Serial.print(outbuf[2],HEX);Serial.print(" ");
     outbuf[3] = Wire.receive();//Serial.print(outbuf[3],HEX);Serial.print(" ");
     outbuf[4] = Wire.receive();//Serial.print(outbuf[4],HEX);Serial.print(" ");
     outbuf[5] = Wire.receive();//Serial.print(outbuf[5],HEX);Serial.print(" ");
     //Serial.print ("\r\n");
     xID= outbuf[0] + outbuf[1] + outbuf[2] + outbuf[3] + outbuf[4] + outbuf[5];
     //Serial.print("Extension controller xID = 0x");
     //Serial.print(xID,HEX);
     //delay (200);
     //if (xID == 0xCB) { Serial.print (" Wii Motion plus connected but not activated"); } // 00 00 A6 20 00 05
     //if (xID == 0xCE) { Serial.print (" Wii Motion plus connected and NC activated"); } // 00 00 A4 20 00 05
     //if (xID == 0x00) { Serial.print (" Wii Motion plus not connected"); } // 00 00 00 00 00 00
     //Serial.print ("\r\n");
  
     delay (500);
     // Now we want to point the read adress to 0xa40008 where the 6 byte data is stored
      //Serial.print ("Set reading address at 0x08 .........");
      Wire.beginTransmission(0x52);
      Wire.send(0x08);
      Wire.endTransmission();
      //Serial.print(" OK done");
     // Serial.print ("\r\n");
      //lcd.clear();
    }
    
  void send_zero (){
      Wire.beginTransmission(0x52);
      Wire.send(0x00);
      Wire.endTransmission();
  }
  
  /*
   _                      
  | |    ___   ___  _ __  
  | |   / _ \ / _ \| '_ \ 
  | |__| (_) | (_) | |_) |
  |_____\___/ \___/| .__/ 
                   |_| 
  */
  
  void loop (){


    send_zero (); // send the request for next bytes
    delay (100);
    Wire.requestFrom (0x52,6);
    
    // Collect all 5 Bytes of data.
    outbuf[0] = Wire.receive();
    outbuf[1] = Wire.receive();
    outbuf[2] = Wire.receive();
    outbuf[3] = Wire.receive();
    outbuf[4] = Wire.receive();
    outbuf[5] = Wire.receive();
  
    joy_x_axis = outbuf[0];               // Left or Right
    joy_y_axis = outbuf[1];               // Forward or Reverse
    z_button = (outbuf[5]>>0) & 1;        // Byte 5 Bit 0
    c_button = (outbuf[5]>>1) & 1;        // Byte 5 Bit 1 (shift it 1 place so its either a 1 or 0, rather than 2 or 0)
  
    ButtonDetect();
    //if (z_button ==0)                          // If we push the Z button is weapon time
    motorcontrol ();                      // call the process to do something with the data
    //print ();
    //cnt = 0;
   
  
    }
    /*
       __  __       _                ____            _             _ 
      |  \/  | ___ | |_ ___  _ __   / ___|___  _ __ | |_ _ __ ___ | |
      | |\/| |/ _ \| __/ _ \| '__| | |   / _ \| '_ \| __| '__/ _ \| |
      | |  | | (_) | || (_) | |    | |__| (_) | | | | |_| | | (_) | |
      |_|  |_|\___/ \__\___/|_|     \____\___/|_| |_|\__|_|  \___/|_|
                                                                   
    */
    void motorcontrol(){
      /* This process decides which direction and by how much
      
     */
      if ((joy_y_axis) == 128 && (joy_x_axis) == 128){          //stopped
        Speed = 0;
        digitalWrite(Forward, LOW);
        digitalWrite(Reverse, LOW);     
      }
    
      if ((joy_y_axis) > 128){                                 //forward
        digitalWrite(Forward, HIGH);
        digitalWrite(Reverse, LOW);
        
     /* 
        map takes the number and changes it to the desired range
        In the case below it maps a 128 to 0, and a 255 to 255.
        
        The joystick at centre should be 128.
        Fully back is 0, while fully forward is 255.
        
        We treat centre as 0, and fully forward or fully back as 255.
        
     */
     
        Speed = map(joy_y_axis, 128, 255, 0, 255);
  
      }
      if ((joy_y_axis) < 128){                                 //reverse
        digitalWrite(Reverse, HIGH);
        digitalWrite(Forward, LOW);
        Speed = map(joy_y_axis, 128, 0, 0, 255);
  
      } 
     
       /*
         ____  _                 _             
        / ___|| |_ ___  ___ _ __(_)_ __   __ _ 
        \___ \| __/ _ \/ _ \ '__| | '_ \ / _` |
         ___) | ||  __/  __/ |  | | | | | (_| |
        |____/ \__\___|\___|_|  |_|_| |_|\__, |
                                         |___/ 
 
       Forward and Right means the left motor goes faster
       Backwards and Right means the left motor goes faster
       
       For the spin, most motor controls have a single direction for both motors.
       They use only two PWM pins so the others are available for other things.
       Effectively we can't make one motor go forward, and the other backwards.
       
       A normal spin will see the BOT move forward heading in the direction of turn.
       If the C Button is pressed, it will move backwards in the direction of turn.
          
       The joystick at centre should be 128.
       Fully left is 0, while fully right is 255.
          
       We treat centre as 0, and fully Left or fully Right as 100.
       We then apportion that to the appropriate motor based on the speed value
       
       */
       
        //Serial.println(joy_x_axis, DEC);                         // uncomment before attempting motor correction
        
      if (joy_x_axis == 128){                                    // centre  
        analogWrite(RightEn,(abs(Speed*RightCorrection/100)));
        analogWrite(LeftEn, (abs(Speed*LeftCorrection/100)));
      }
      if ((joy_x_axis) > 128 && (joy_y_axis) != 128){            // Right with some fwd/rev
        RightAmount = map(joy_x_axis, 128, 255, 100, 0);
        analogWrite(RightEn,((Speed * RightAmount)/100));
        analogWrite(LeftEn,Speed);
      }
      else if ((joy_x_axis) > 128 && (joy_y_axis) == 128){       // Spin to the right with no fwd/rev 
        LeftAmount = map(joy_x_axis, 128, 255, 0, 255);          // right axis reading fed into Left motor
        if (c_button == 1)
        {
          digitalWrite(Reverse, LOW);
          digitalWrite(Forward, HIGH);
        }
        else                                                     // reverse spin
        {
          digitalWrite(Reverse, HIGH);
          digitalWrite(Forward, LOW);
        }
        analogWrite(LeftEn, LeftAmount);                         // Left motor forward
      }
      
      if ((joy_x_axis) < 128 && (joy_y_axis) != 128){            // Left with fwd/rev
        LeftAmount = map(joy_x_axis, 128, 0, 100, 0);
        analogWrite(LeftEn,((Speed * LeftAmount)/100));
        analogWrite(RightEn, Speed);
      }
      else if ((joy_x_axis) < 128 && (joy_y_axis) == 128){       // Spin to the left with NO fwd/rev
        RightAmount = map(joy_x_axis, 128, 0, 0, 255);           // left axis reading fed into Right motor
        if (c_button == 1)
        {
          digitalWrite(Reverse, LOW);
          digitalWrite(Forward, HIGH);
        }
        else                                                     // Spin turning in a reverse motion
        {
          digitalWrite(Reverse, HIGH);
          digitalWrite(Forward, LOW);
        }
        analogWrite(RightEn,RightAmount);                        //Left motor forward
      } 
  }
  
  void ButtonDetect()
  {
    // this process checks to see what is pressed.
   if ((z_button == 0)&&(c_button ==0))
  {
    small_stepper.setSpeed(200);   
    Steps2Take  =  -16;                    // Rotate CW
    small_stepper.step(Steps2Take);
  }
    
   else if (z_button ==0)
  {
    //Serial.println ("Z Button");
    small_stepper.setSpeed(200);   
    Steps2Take  =  16;                    // Rotate CW
    small_stepper.step(Steps2Take);
  }
  else if (c_button == 0)
  {
  //Serial.println ("C Button");
  }


    
//  small_stepper.setSpeed(200);   
//  Steps2Take  =  2;  // Rotate CW
//  small_stepper.step(Steps2Take);
//  //delay(2000);
//  
//  small_stepper.setSpeed(200);  // 200 a good max speed??
//  Steps2Take  =  -2;  // Rotate CCW
//  small_stepper.step(Steps2Take);
//  //delay(2000); 
    
    
    
  }
  /*
      
     ____       _       _   
    |  _ \ _ __(_)_ __ | |_ 
    | |_) | '__| | '_ \| __|
    |  __/| |  | | | | | |_ 
    |_|   |_|  |_|_| |_|\__|
                                  
      You can uncomment the call to print() if you want debugging data
      You may wish to comment out some and shift where the print() is located.
      Each char printed takes an amount of time, and hence leaving it in slows down the loop time.
      For testing it is not noticeable, but may be when operating.
  
  */
  
  void print(){
        delay (100); //slow down the printing
       
        int joy_x_axis = outbuf[0];
        int joy_y_axis = outbuf[1];
        int z_button = (outbuf[5]>>0) & 1;
        int c_button = (outbuf[5]>>1) & 1;
        Serial.print ("joyx= ");
        Serial.print (joy_x_axis, DEC);
        Serial.print ("  joyy=");
        Serial.print (joy_y_axis, DEC);
        Serial.print ("  ");
        if (z_button == 0) { Serial.print ("z_button "); }
        if (c_button == 0) { Serial.print ("c_button "); }
        Serial.print ("\r\n");
  
  
        Serial.print("joyy= "    );
        Serial.print (joy_y_axis, DEC);
        Serial.print("   Fwd Speed=  ");
        Serial.print (Speed);
        Serial.println();


  
        Serial.print("joyx= "    );
        Serial.print (joy_x_axis, DEC);
        Serial.print("   Left pwm=  ");
        Serial.print((Speed * LeftAmount)/100);
        Serial.print("   Right pwm=  ");
        Serial.print((Speed * RightAmount)/100);
        Serial.println();
   }

 

This was the first version of software, and includes some of the features along with various print statements for debugging.

The button() routine was originally or a stepper motor and hasn't been removed.

 

/* .......................................................................
 Code to control a robot using a Wii Nunchuk
  most of the Wii code was from the Arduino forum ..thanks to the many contributors.
 
 Here is the bitmapping for the standard nunchuk mapping
    Bit
 Byte     7 6 5 4 3 2 1 0
   0 SX<7-----------------------------------------------------0>
   1 SY<7-----------------------------------------------------0>
   2 AX<9-----------------------------------------------------2>
   3 AY<9-----------------------------------------------------2>
   4 AZ<9-----------------------------------------------------2>
   5 AZ<1----0>   AY<1-------0>   AX<1-------0>      BC BZ
 
 Hardware Arduino with ATMega 328
 Connections 
 SCA to AD4 (Analog4) with pullup of 2k7 to 3.3 volts
 SCL to AD5 (Analog5) with pullup of 2k7 to 3.3 volts
 
 Connections to IR4427P chips are :-
  Pin 3 to 2 (Left Motor)Left2
  Pin 5 to 4 (Left Motor)Left1
  Pin 6 to 2 (Right Motor)Right2
  Pin 9 to 4 (Rigtht Motor)Right1
 
 There isn't anything else as it was designed for a 300g robot, and I wanted some protection


 The Arduino I2C uses 7 bits, therefore the MP address (0xA6) becomes 0x53, and the (0xA4) becomes 0x52
 Modified by Mark Beckett
 jun 2010
 ************************************
 To Do
  Detect if the interface has disconnected and don't go full speed.
  Use something other than a Rugged Circuit driver which needs 8v to run.
  Reduce weight to enable a lifting motor on the front

*/


#include 
#include 
#include 


//setup the variables, etc
//int ledPin = 13;
int xID;


//Nunchuck
uint8_t outbuf[6];           //nunchuck buffer for data
int cnt = 0;                 //nunchuck buffer counter
int joy_x_axis;              //Joystick x (8 bits)
int joy_y_axis;              //Joystick y (8 bits)
int z_button;
int c_button;


// Motor Movement
int Left2 = 3;  
int Left1 = 5;
int Right2 = 6;  
int Right1 = 9;
int Speed;
int RightAmount;
int LeftAmount;


//Wii Nunchuk
byte data[6];                //buffer for WM+ data


void setup (){
  Serial.begin (19200);


  pinMode(Right1, OUTPUT);
  pinMode(Right2, OUTPUT);
  pinMode(Left1, OUTPUT);
  pinMode(Left2, OUTPUT);
  
  Wire.begin();
  Serial.print ("Finished setup\n");
  Serial.print ("Now detecting WM+\n");
  delay(100);
  
// initiate Wii Nunchuk
    Serial.print ("Initialising Wii Nunchuk ........");
    Wire.beginTransmission(0x52); //0xA4
    Wire.send(0xF0);
    Wire.send(0x55);
    Wire.endTransmission();
    Serial.print (" OK done"); 
    Serial.print ("\r\n");
    delay (100); 
    
    Serial.print ("Set reading address at 0xFA .......");
    Wire.beginTransmission(0x52); //0xA4
    Wire.send(0xFA);
    Wire.endTransmission();
    Serial.print(" OK done");
    Serial.print ("\r\n");
    delay (100);
    Wire.requestFrom (0x52,6);  //0xA4
   outbuf[0] = Wire.receive(); //Serial.print(outbuf[0],HEX);Serial.print(" ");
   outbuf[1] = Wire.receive(); //Serial.print(outbuf[1],HEX);Serial.print(" ");
   outbuf[2] = Wire.receive(); //Serial.print(outbuf[2],HEX);Serial.print(" ");
   outbuf[3] = Wire.receive(); //Serial.print(outbuf[3],HEX);Serial.print(" ");
   outbuf[4] = Wire.receive(); //Serial.print(outbuf[4],HEX);Serial.print(" ");
   outbuf[5] = Wire.receive(); //Serial.print(outbuf[5],HEX);Serial.print(" ");
   //Serial.print ("\r\n");
   xID= outbuf[0] + outbuf[1] + outbuf[2] + outbuf[3] + outbuf[4] + outbuf[5];
   //Serial.print("Extension controller xID = 0x");
   //Serial.print(xID,HEX);
   //delay (200);
   //if (xID == 0xCB) { Serial.print (" Wii Motion plus connected but not activated"); } // 00 00 A6 20 00 05
   //if (xID == 0xCE) { Serial.print (" Wii Motion plus connected and NC activated"); } // 00 00 A4 20 00 05
   //if (xID == 0x00) { Serial.print (" Wii Motion plus not connected"); } // 00 00 00 00 00 00
   //Serial.print ("\r\n");


   delay (500);
   // Now we want to point the read adress to 0xa40008 where the 6 byte data is stored
   // Serial.print ("Set reading address at 0x08 .........");
    Wire.beginTransmission(0x52);
    Wire.send(0x08);
    Wire.endTransmission();
    //Serial.print(" OK done");
    //Serial.print ("\r\n");
    //lcd.clear();
  }
void send_zero (){
    Wire.beginTransmission(0x52);
    Wire.send(0x00);
    Wire.endTransmission();
}
void loop (){
// all sensor data and put them into 6 byte register within the extension controller


  send_zero (); // send the request for next bytes
  delay (100);
  Wire.requestFrom (0x52,6);
  outbuf[0] = Wire.receive();
  outbuf[1] = Wire.receive();
  outbuf[2] = Wire.receive();
  outbuf[3] = Wire.receive();
  outbuf[4] = Wire.receive();
  outbuf[5] = Wire.receive();


  joy_x_axis = outbuf[0];
  joy_y_axis = outbuf[1];
  z_button = (outbuf[5]>>0) & 1;
  c_button = (outbuf[5]>>1) & 1;
  motorcontrol();
  cnt = 0;
 
}


void motorcontrol(){
  // this bit decides which direction and by how much
    
    //Steering
   //Forward and right means the left motor goes faster
   //Backwards and right means the left motor goes faster
   
    //if (joy_x_axis == 128)                            //centre
   // { 
      RightAmount = map(joy_x_axis, 128, 255, 100, 0);
      LeftAmount = map(joy_x_axis, 0, 128, 0, 100);
   // }
    
    if ((joy_y_axis) == 128 && (joy_x_axis) == 128)     //stopped
    {
      //Speed = 0;
      digitalWrite(Right1, LOW);
      digitalWrite(Right2, LOW);
      digitalWrite(Left1, LOW);  
      digitalWrite(Left2, LOW);   
    }
  
    if ((joy_y_axis) > 128)        //forward
    {  
      digitalWrite(Right2, LOW);
      digitalWrite(Left2, LOW);
      Speed = map(joy_y_axis, 128, 255, 0, 255);
      analogWrite(Right1,((Speed * RightAmount)/100));
      analogWrite(Left1,((Speed * LeftAmount)/100));
    }
    
    if ((joy_y_axis) < 128)        //reverse
    {  
      digitalWrite(Right1, LOW);
      digitalWrite(Left1, LOW);
      Speed = map(joy_y_axis, 0, 128, 255, 0);
      analogWrite(Right2,((Speed * RightAmount)/100));
      analogWrite(Left2,((Speed * LeftAmount)/100));


    } 
   
   /*
   
   //Steering
   //Forward and right means the left motor goes faster
   //Backwards and right means the left motor goes faster
   
    if (joy_x_axis == 128)                                    //centre
    { 
      analogWrite(Right2,Speed);
      analogWrite(Left2, Speed);
    }
    
    if ((joy_x_axis) > 128 && (joy_y_axis) != 128)            //right with fwd/rev
    {            
      RightAmount = map(joy_x_axis, 128, 255, 100, 0);
      analogWrite(Right2,((Speed * RightAmount)/100));
      analogWrite(Left2,Speed);
    }
    else if ((joy_x_axis) > 128 && (joy_y_axis) == 128)       //spin to the right with no fwd/rev 
    {  
      LeftAmount = map(joy_x_axis, 128, 255, 0, 255);          // right axis reading fed into left motor
      if (c_button == 1)
      {
        digitalWrite(Right1, LOW);
        digitalWrite(Left1, HIGH);
      }
      else                                                     //reverse
      {
        digitalWrite(Right1, HIGH);
        digitalWrite(Left1, LOW);
      }
      analogWrite(Left2, LeftAmount);                        //Left motor forward
    }
    
    if ((joy_x_axis) < 128 && (joy_y_axis) != 128){            // left with fwd/rev
      LeftAmount = map(joy_x_axis, 128, 0, 100, 0);
      analogWrite(Left2,((Speed * LeftAmount)/100));
      analogWrite(Right2, Speed);
    }
    else if ((joy_x_axis) < 128 && (joy_y_axis) == 128){       // left with no fwd/rev
      RightAmount = map(joy_x_axis, 128, 0, 0, 255);          // left axis reading fed into right motor
      if (c_button == 1)
      {
        digitalWrite(Right1, LOW);
        digitalWrite(Left1, HIGH);
      }
      else                                                     //reverse
      {
        digitalWrite(Right1, HIGH);
        digitalWrite(Left1, LOW);
      }
      analogWrite(Right2,RightAmount);                          //Left motor forward
    } 
    
    */
}

 

The software I've included is not polished and is a WIP.

However this should provide a starting point for anyone wanting to make a bot using the Nintendo Wii Nunchuck as the controller.

 

 

 

Performance.

When we first discussed this idea, there were three others keen to develop something, but they never progressed to a working model.

 

We did have a token battle against a Lego based bot that weighed 2kg, had 8 wheels and covered a large amount of the ring. My 305 gram tiny bot didn't really disgrace itself.

The control mechanism used a smartphone which compromised the ability to move quickly, so I had better speed and maneuverability, but I was very much outgunned in the weight department, so couldn't move it out the ring.

 

In one battle I did manage to make it very hard to move, however hanging around while the operator changed his approach wasn't a good idea.

We decided to try the push test and while the tyres remained gripping the surface, it lacked the energy needed to move the other.

My software hadn't allowed for dynamic braking, as consequently if it was being pushed you needed to apply some forward control.

 

 

 

 

Enhancements

There is a few more grams required to be removed to meet the 300g class.

I haven't removed any of the wireless case or the connector as I was still testing it.

The connector allowed a corded version Nunchuck to be used, and was intended to be removed eventually.

 

The software needs dynamic braking and could use one of the buttons.

 

I'm sure the glitch that sees the receiver drop-out is related to power, but needs further investigation.

I haven't even put an oscilloscope near it to see how bad it is.

 

The battery mounting needs something to help competitors to slide over the top, rather than having a surface to push against.

This could also be applied to the wheels to make them less of a target.

 

 

Video

Taking video while operating controls and trying to drive in the confines of an A4 paper box lid  ... is a challenge.

I couldn't manage to include the controller as well ... but you can guess it was getting moved.

 

 

Cheers

Mark