Instructions May 2014

The RoboSlam robot is built in three stages. Each stage involves some circuit construction and programming to add a new feature to the robot.

Preparation

Step 0.1: Switch to Firefox

If you’re reading this in Internet Explorer, please switch to Firefox now. Copying and pasting the example programs from Internet Explorer does not work correctly.

Step 0.2: Download roboslam.zip

To use the example programs provided below to control your robot, you need a text editor called Notepad++ and a C compiler called mspgcc. We have created a zip file called "roboslam.zip" which contains both, together with some other useful tools. If you haven’t already downloaded this zip file, you should do so now:

Extract the contents of the zip file to "C:\RoboSlam\".

WARNING: If you decide to place your RoboSlam folder in a different location, the path to the folder must not contain any spaces. For example, "C:\Documents and Settings\users\Joe\RoboSlam" won’t work because there are spaces in the folder name "Documents and Settings".

Stage 1: Blinking LED

In this stage, we build a very simple breadboard circuit and then copy a short example program onto the microcontroller to blink an LED on and off.

Step 1.1: Introducing the breadboard

This is the breadboard. We use it to build electronic circuits quickly without any soldering. Each of the two main sections in the centre of the breadboard consists of many short rows of five connected holes. To connect two wires or components together, just plug them into the same short row. For example, wires plugged into holes a3 and e3 will become electrically connected because they are both in the same short row.

02_roboslam_circuit_breadboard

The long red and blue lines on each side of the breadboard indicate that each of these long rows of holes is connected continuously along the full length of the board. We call these long rows “rails” and they are normally used to supply voltage to different parts of the circuit. The red rail is used for the positive supply voltage (6V in this circuit). The blue rail is normally used for the negative supply voltage (0V).

Step 1.2: Connect the battery pack

If there are batteries in your battery pack, remove at least one of them and don’t put it back until the circuit is ready to be powered up.

Connect the battery pack to the breadboard as shown below.

03_roboslam_circuit_batteries

Step 1.3: Place the MSP430 microcontroller on the breadboard

WARNING: The MSP430 chip is very fragile! The pins bend and break easily, so be careful when placing it into the breadboard.

The “brain” of the robot is the MSP430 microcontroller. A microcontroller is an entire computer on a single chip. It contains a microprocessor, RAM memory, flash memory (like in a USB memory stick) and other useful features.

Place the MSP430G2553 microcontroller in the position shown. Make sure that the end of the chip with the semi-circular indentation is in row 4.

04_roboslam_circuit_MSP430

Step 1.4: Connect a “pull-up” resistor to the reset pin

To prevent the microcontroller from accidentally resetting while the robot is running, a 22kΩ resistor (colour code: red, red, orange, gold) must be placed in the position shown below (between d4 and g8). It doesn’t matter which way around it is inserted.

05_roboslam_circuit_reset_pin_resistor

Step 1.5: Connect the voltage supply to the microcontroller

To supply voltage to the MSP430 microcontroller,

  • Connect a diode between the red rail on the left and hole a2. The diode is a small black cylidrical component with a silver band at one end and two metal legs. The end with the silver band must be connected to hole a2.
  • Connect a green LED between hole b2 and hole b4. The LED is ever so slightly flattened on one side of its plastic body. This side is the cathode (minus leg) and must be connected to hole b4.
  • Connect a black wire between the left-hand blue rail (0V) and hole 4g.

06_roboslam_circuit_MSP430_power_connections

Step 1.6: Add a capacitor to stabilise the microcontroller supply voltage

  • Connect a capacitor between the left-hand blue rail and hole a4. The capacitor is the small cylindrical component with two parallel legs sticking out the bottom. Note that the minus leg of the capacitor, which is marked by a long black stripe running down the body of the capacitor, must be connected to the blue rail (0V).

07_roboslam_circuit_MSP430_capacitor

Step 1.7: Add an indicator LED

  • Connect a green LED between holes c5 and d1. The slight flattening on one side of the LED should be on the side that is connected to hole d1.
  • Connect the 270Ω resistor (colour code: red, violet, brown, gold) between the blue rail (0V) and hole b1.

08_roboslam_circuit_LED_and_resistor

Step 1.8: Connect the LaunchPad to the microcontroller

The LaunchPad is the red circuit board shown below. It is used to transfer the programs you write from the PC to the microcontroller. Connect it to the breadboard using the black, yellow and green wires as shown below.

09_roboslam_circuit_LaunchPad

Step 1.9: Program the microcontroller to blink the LED

It’s time to compile the first program for your microcontroller.

Programming note for Mac users: This blog asssumes that you are using a Windows PC to program the MSP430. The Mac equivalent of the three MSP430 example programs used in the workshop are contained in this PDF, which was created by Jim Blair from Kinsale Coder Dojo.
  • Create a folder called "C:\RoboSlam\blink\".
  • Copy and paste the C code below into Notepad++ and save it as the filename "main.c" in the "blink" folder.
  • Copy and paste the file "build_for_g2553.bat" from the "RoboSlam" folder into the "blink" folder.
  • Ask one of the workshop facilitators to check your circuit before inserting the batteries!
  • Insert the batteries into your battery holder so that the microcontroller is receiving power.
  • Double click the file “build_for_g2553.bat” to compile the blinking LED example and copy it onto the microcontroller, where it should start running immediately, causing the LED to blink on and off!
Don’t Panic! If the program doesn’t work straight away, don’t worry. It’s probably something quite simple. Just ask one of the workshop facilitators to help you find the problem.

//
// RoboSlam Example: Blinking LED
// Code is for MSP430G2553
// Last updated 26-9-2014
//

#include <msp430.h>

// main function
int main( void )
{
    // stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    // configure digital inputs and outputs
    P1OUT = 0b00000000; // set P1.0-7 low
    P1DIR = 0b00000001; // set P1.0 as an output

    // repeat the following steps indefinitely
    while(1)
    {
        // LED on for 1 second
        P1OUT = 0b00000001;
        __delay_cycles(1000000);

        // LED off for 1 second
        P1OUT = 0b00000000;
        __delay_cycles(1000000);
    }

    return 0;
}
Challenge: Change the blinking rate of the LED so that it’s on for 100ms and off for 900ms.

Stage 2: Motor control

Step 2.1: Add the SN754410NE driver chip

  • Remove at least one battery from the battery holder to power down the robot.
  • Add the SN754410NE driver chip to the breadboard as shown below. The end of the chip with the semi-circuitar indentation must be in row 21.

10_roboslam_circuit_driver_chip

Step 2.2: Connect the voltage supply to the driver chip

Add the supply voltage connections shown below:

  • A red wire between the left-hand red rail (6V) and hole a28.
  • A black wire between the left-hand blue rail (0V) and hole a25.
  • A red wire between holes d28 and g21.

11_roboslam_circuit_motors_power_connections

Step 2.3: Add a capacitor to the supply rails to reduce motor interference

Add a 220uF capacitor between the left-hand red (6V) and blue (0V) rails as shown below. Note that the negative leg of the capacitor, which is marked by the long black stripe down the side of its cylindrical body, must be connected to the blue rail (0V).

12_roboslam_circuit_motors_capacitor

Step 2.4: Connect the microcontroller to the driver chip

Add the connections shown below. These allow the microcontroller to send signals to the driver chip to control the motors:

  • A purple wire between holes 11d and 27d.
  • A purple wire between holes 12d and 22d.
  • A blue wire between holes 13d and 21d.
  • A blue wire between holes 11g and 28g.
  • A purple wire between holes 12g and 27g.
  • A purple wire between holes 13g and 22g.

13_roboslam_circuit_motors_signals

Step 2.5: Connect the motors to the driver chip

  • Connect the left motor to holes 23h and 26h
  • Connect the right motor to holes 23b and 26b

14_roboslam_circuit_motors_complete

Step 2.6: Program the microcontroller to control the motors

  • Create another new folder called "C:\RoboSlam\zigzag\".
  • Copy and paste the code below into a new file in Notepad++ and save it as filename "main.c" in the "zigzag" folder.
  • Copy and paste the file "build_for_g2553.bat" from the "RoboSlam" folder into the "zigzag" folder.
  • Ask one of the workshop facilitators to check your circuit before inserting the batteries!
  • Insert the batteries into your battery holder so that the microcontroller is receiving power.
  • Double click the file “build_for_g2553.bat” to compile the zigzag example program and copy it onto the microcontroller, where it should immediately start running, causing the motors to move.
  • Disconnect the robot from the LaunchPad and it should drive along the floor in a zigzag pattern.

//
// RoboSlam Example: Driving ZigZag
// Code is for MSP430G2553
// Last updated 26-9-2014
//

#include <msp430.h>

// function prototypes
void setup();
void set_motors(int left_speed, int right_speed);

// main function
int main( void )
{
    // call setup function to configure microcontroller
    setup();

    // repeat the following steps indefinitely
    while(1)
    {
        // forward for 1 second
        set_motors(100, 100);
        __delay_cycles(1000000);

        // turn left for 0.5 seconds
        set_motors(-100, 100);
        __delay_cycles(500000);

        // forward for 1 second
        set_motors(100, 100);
        __delay_cycles(1000000);

        // turn right for 0.5 seconds
        set_motors(100, -100);
        __delay_cycles(500000);
    }

    return 0;
}

//
// This function configures the microcontroller. It disables the
// watchdog timer, configures digital i/o, sets up Timer_A0 for
// measuring the duration of the rangefinder echo pulse, sets up
// Timer_A1 for motor PWM, and enables the internal pull up
// resistor on digital input P1.6.
//
void setup()
{
    // stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    // configure digital inputs and outputs
    P1OUT = 0b00000000; // set P1.0-7 low
    P1DIR = 0b10000001; // set P1.0, P1.7 as outputs
    P2OUT = 0b00000000; // set P2.0-7 low
    P2SEL = 0b00100100; // set pin 10 as TA1.1, pin 13 as TA1.2
    P2DIR = 0b00111111; // set P2.0-5 as outputs

    // configure Timer_A1 for motor PWM (for speed control)
    TA1CTL = TASSEL_2 + ID_0 + MC_1; // Timer_A1: SMCLK clock, input divider=1, "up" mode
    TA1CCR0 = 1000;                  // set Timer_A1 period to 1ms for 1kHz PWM
    TA1CCR1 = 1000;                  // 100% duty cycle initially
    TA1CCR2 = 1000;                  // 100% duty cycle initially
    TA1CCTL1 = OUTMOD_7;             // select "Reset/Set" output mode
    TA1CCTL2 = OUTMOD_7;             // select "Reset/Set" output mode
}

//
// This function sets the speed and direction of both motors. The
// first argument controls the left motor. The second argument
// controls the right motor. Each argument can be any integer between
// -100 and +100, where -100 is full speed reverse. +100 is full speed
// forwards.
//
void set_motors(int left_speed, int right_speed)
{
    // work out P2OUT value for requested directions
    int p2out_value = 0;
    if (left_speed > 0)  p2out_value += 0b00000001;
    if (left_speed < 0)  p2out_value += 0b00000010;
    if (right_speed > 0) p2out_value += 0b00001000;
    if (right_speed < 0) p2out_value += 0b00010000;

    // clamp motor speed to allowed range
    if (left_speed > 100)   left_speed = 100;
    if (left_speed < -100)  left_speed = -100;
    if (right_speed > 100)  right_speed = 100;
    if (right_speed < -100) right_speed = -100;

    // set motor directions and speeds
    P2OUT = p2out_value;
    TA1CCR1 = 10 * left_speed;
    TA1CCR2 = 10 * right_speed;
}
Challenge: Modify and recompile the above code to make the robot drive in a square pattern. Place a block in the centre of the RoboSumo arena and see how many times you can make your robot drive around a block without either touching the block or falling off the RoboSumo arena.

Stage 3: Rangefinder

Step 3.1: Add the rangefinder and connect it to the microcontroller

The rangefinder is an ultrasonic distance sensor.

  • Add the rangefinder to the breadboard in the position shown (holes 14j, 15j, 16j and 17j).
  • Connect a red wire from the left-hand red rail (6V) to hole 17h.
  • Connect a black wire from the left-hand blue rail (0V) to hole 14h.
  • Connect a diode between holes 15i and 10h. The end of the diode marked with a silver band must be connected to hole 15i.
  • Connect a blue wire between holes 9h and 16i.

15_roboslam_circuit_complete

Step 3.4: Program the microcontroller to navigate using the rangefinder

//
// RoboSlam Example: Rangefinder navigation
// Code is for MSP430G2553
// Last updated 26-9-2014
//

#include <msp430.h>

// function prototypes
void setup();
void set_motors(int left_speed, int right_speed);
int get_distance();

// main function
int main( void )
{
    // call setup function to configure microcontroller
    setup();

    // implement robot behaviour
    while(1)
    {
        __delay_cycles(50000);
        
        // is distance greater than 500mm?
        if (get_distance() > 500)
        {
            // yes, so turn around looking for enemy
            set_motors(50,-50);
        }
        else
        {
            // no, so enemy is straight ahead
            set_motors(100,100);
        }
    }

    return 0;
}

//
// This function configures the microcontroller. It disables the
// watchdog timer, configures digital i/o, sets up Timer_A0 for
// measuring the duration of the rangefinder echo pulse, sets up
// Timer_A1 for motor PWM, and enables the internal pull up
// resistor on digital input P1.6.
//
void setup()
{
    // stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    // configure digital inputs and outputs
    P1OUT = 0b00000000; // set P1.0-7 low
    P1DIR = 0b10000001; // set P1.0, P1.7 as outputs
    P2OUT = 0b00000000; // set P2.0-7 low
    P2SEL = 0b00100100; // set pin 10 as TA1.1, pin 13 as TA1.2
    P2DIR = 0b00111111; // set P2.0-5 as outputs

    // configure Timer_A1 for motor PWM
    TA1CTL = TASSEL_2 + ID_0 + MC_1; // Timer_A1: SMCLK clock, input divider=1, "up" mode
    TA1CCR0 = 1000;                  // set Timer_A1 period to 1ms for 1kHz PWM
    TA1CCR1 = 1000;                  // 100% duty cycle initially
    TA1CCR2 = 1000;                  // 100% duty cycle initially
    TA1CCTL1 = OUTMOD_7;             // select "Reset/Set" output mode
    TA1CCTL2 = OUTMOD_7;             // select "Reset/Set" output mode

    // configure Timer_A0 for measuring rangefinder echo pulse
    // select SMCLK clock, input divider=1, "continuous" mode
    TA0CTL = TASSEL_2 + ID_0 + MC_2;

    // enable pull up resistor on P1.6 for rangefinder echo
    P1OUT |= BIT6;
    P1REN |= BIT6;
}

//
// This function sets the speed and direction of both motors. The
// first argument controls the left motor. The second argument
// controls the right motor. Each argument can be any integer between
// -100 and +100, where -100 is full speed reverse. +100 is full speed
// forwards.
//
void set_motors(int left_speed, int right_speed)
{
    // work out P2OUT value for requested directions
    int p2out_value = 0;
    if (left_speed > 0)  p2out_value += 0b00000001;
    if (left_speed < 0)  p2out_value += 0b00000010;
    if (right_speed > 0) p2out_value += 0b00001000;
    if (right_speed < 0) p2out_value += 0b00010000;

    // clamp motor speed to allowed range
    if (left_speed > 100)   left_speed = 100;
    if (left_speed < -100)  left_speed = -100;
    if (right_speed > 100)  right_speed = 100;
    if (right_speed < -100) right_speed = -100;

    // set motor directions and speeds
    P2OUT = p2out_value;
    TA1CCR1 = 10 * left_speed;
    TA1CCR2 = 10 * right_speed;
}

//
// This function measures the distance in mm to the nearest object
// using the rangefinder.
//
int get_distance()
{
    // send trigger pulse
    P1OUT |= BIT7;
    __delay_cycles(20);
    P1OUT &= ~BIT7;

    // measure echo pulse duration
    TA0CTL |= TACLR;                            // reset timer
    while ((P1IN & BIT6) == 0 && TA0R < 12000); // wait for start of echo pulse
    TA0CTL |= TACLR;                            // reset timer
    while ((P1IN & BIT6) > 0 && TA0R < 12000);  // wait for end of echo pulse
    return (TA0R / 6);                          // return the distance in mm
}
Challenge: Can your robot find an object and push it out of the RoboSumo arena? If so, you’re ready to rumble!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s