Pimp My Sumovore

After Nick Jones' original work with the Sumovore, and Simons subsequent experiments, I decided it was time to start pulling somthing together a bit. This was also inspired by Linton Village College starting up an Afterschool robotics club, for which we suggested the Sumovore as a great platform to build on. source:/PimpMySumovore/doc/sumovore.jpg

The plan is to build a prototyping PCB platform that links the Sumovore sensors and motor drivers to the mbed board to take care of the wiring and form factor, but allow for experimentation.

The connections

The first thing to look at is the connectivity between the main Sumovore board, and the brain board. I have taken the table of conenctions from Simons page, and reassigned the wire to more suitable positions.

mbed pinSumovore pinExplanation
GNDPin 1Ground
VINPin 2mbed input voltage
5Pin 3Left reverse enable
6Pin 4Left forward enable
7Pin 5Right reverse enable
8Pin 6Right forward enable
23Pin 7Left PWM
24Pin 8Right PWM
29Pin 9IR DET1
30Pin 10IR DET2
20Pin 17Edge1 Detector
19Pin 18Edge2 Detector
17Pin 20Edge3 Detector
16Pin 19Edge4 Detector
15Pin 21Edge5 Detector

The PCB

The main requirements are :

  • To be a drop in replacement for the Sumovore "Discrete brain board"
  • Replace the IR detector threshold detectors with a fixed resistor circuit connected to an AnalogIn - let the software decide, not a pot!
  • To hook up to tall the sensors and motor controllers, leaving as much useful IO free as possible.
  • Provide a PCB prototyping space for adding additional circuits
  • Provide easy access to all the mbed pins
  • Provide easy access to 0v, 3v3 and 5v

The PCB was captured and layed out in Eagle, and I had 20-off manufactured at PCBCART.com, costing a total of $150.

When it is up and running, I'll post the gerbers, in the mean time, here are the:

Building it up

Okay, so it is 12:05 on 24/11/2008, and I have just got an email from reception to tell me my PCBs have arrived. I hit F5 in IE which has been open at the FedEx tracking page since 6am, and FedEx also tell me my PCBs are here.

The first thing I noticed is that although I ordered the longest possible pin connectors from Farnell, the ones I were after are now end-of-line and were replaced with something a little shorter, unfortunatley a little too short. So i'm onthe hunt again for SIL pin headers of the right length. In the mean time, I only push the pins through the PCB just enough to be able to soder them, keeping as much as I can below.

I have now ordered some parts from SAMTEC. Part number MTSW-108-11-T-S-600. I got them all 8 way, as there are 2 x 8 way connectors, and 2 x 4 way. three per board, snapping one in half for the 4 ways.

I've used a pair of 20 way SIL sockets for mounting the mbed board. They do make the mbed board sit very tall, but thats not too much of a problem.

I measureed the resistance that has been set on the potentiometer for the IR detectors to be 340k, which is consistent with being about 1/6 of a turn of the 2M pot. As I didnt have 330k resistors o hand, I've used some 390k. I will eventually get some 330k resistors and swap them in so I have a good reference point when it comes to useing the AnalogIn for sensing.

First program

The first thing to do is take Simons original code, and port it to the new connectivity.

#include "mbed.h"

DigitalOut leftrev(p5);
DigitalOut leftfwd(p6);
DigitalOut rightrev(p7);
DigitalOut rightfwd(p8);

PwmOut pwmleft(p23);
PwmOut pwmright(p24);

int main() {
	leftfwd = 1;
	leftrev = 0;
	rightfwd = 1;
	rightrev = 0;

	pwmleft = 1;
	pwmright = 1;
	
	wait(1);

	leftfwd = 0;
	leftrev = 0;
	rightfwd = 0;
	rightrev = 0;	
}

Yup, as with Simons attempts, this got it moving.

Motor Abstraction

As with Simons experiments, the next experiment is to make a Motor abstraction to simplify the control:

#include "mbed.h"

class Motor {
public:
	Motor(int pwm, int fwd, int rev) : _pwm(pwm), _fwd(fwd), _rev(rev) {}
	
	void speed(float p) {
		_fwd = (p > 0.0);
		_rev = (p < 0.0);
		_pwm = abs(p);
	}
	
private:
	PwmOut _pwm;
	DigitalOut _fwd;
	DigitalOut _rev;
};

Motor left(p23, p6, p5);
Motor right(p24, p8, p7);

int main() {
	left.speed(1);
	right.speed(1);
	
	wait(1);

	left.speed(0);
	right.speed(0);
}

Note this does exactly the same as before, but now the raw pwm and digitial motor controls are abstracted to a Motor object with a single speed control which takes a percentage between -1.0 and 1.0.

Logo style interpreter

Now there is a nice abstraction for the motors, the next step is to reuse Nick Jones' code to recreate the logo style interpreter.

The code can be imported as a project :

#include "mbed.h"
#include "Motor.h"

/*
 *  This code reads command files to control the motors.
 *  The file name it reads is command.txt
 *
 *  The file format is :
 *
 *      <command> <data> 
 *
 *  The commands are :
 *
 *      F - Forward, both motor on full speed forwards
 *      B - Backwards, both motors on full speed in reverse
 *      L - Left, left motor full speed backwards, right motor full speed forward
 *      R - Right, right motor full speed backwards, left motor full speed forward
 *      W - Wait, both motors stop
 *
 *  Data :
 *
 *      Data is a time in milliseconds to carry out the command.
 *
 *  Example :
 *
 *      F 1000
 *      W 200
 *      L 1000
 *      W 200
 *      R 1000
 *      W 200
 *      B 1000
 *      W 200
 */


LocalFileSystem local("local");

Serial pc(USBTX, USBRX);

BusOut leds(LED1,LED2,LED3,LED4);

Motor left(p23, p6, p5);
Motor right(p24, p8, p7);


int main() {    
            
    leds = 0x0;
    
    // flash the LED 3 time before starting
    for (int i=0; i < 3 ; i++) {
        leds = 0x1;    
        wait (0.5);    
        leds = 0x0;    
        wait (0.5);
    }
        
    // Open the command.txt file
    FILE *commandfile = fopen("/local/command.txt", "r");

    // If there is no file, sit flashing the LEDs
    if (commandfile == NULL) { 
        while(1) {
            leds = 0xf;
            wait(0.5);
            leds = 0x0;
            wait(0.5);
        }
    } 
    
    // process each of the commands in the file
    while (!feof(commandfile)) {
    
        char command = 0;
        int data = 0.0;
         
        // Read from the command file
        fscanf(commandfile, "%c %d\n", &command, &data); 
                         
        if((command=='f') || (command=='F')){
                left.speed(1);
                right.speed(1);
        }        
        else if((command=='b') || (command=='B')){
                left.speed(-1);
                right.speed(-1);
        }
        else if((command=='l') || (command=='L')){
                left.speed(-1);
                right.speed(1);
        }
        else if ((command=='r') || (command=='R')){
                left.speed(1);
                right.speed(-1);
        }
        // Wait commands
        else if ((command=='w') || (command=='W')){
        }

        // wait for the length of the command
        wait(data/1000.0);        

        // Switch the motors off
        left.speed(0);
        right.speed(0);


    } // this is the end of the file while loop


    for (int i=0;i<10;i++) {
        leds = 0x0;
        wait (0.2);
        leds = 0xf;
        wait (0.2);
    }
        
    fclose(commandfile);
    exit(0);
    
} // end of main