It's Nothing without Software...

A project log for Edubot Controller (Benny)

An affordable educational robot for the classroom for South Africa

tom-van-den-bonTom Van den Bon 05/11/2016 at 14:580 Comments

So having an educational robot is all and good. But it's pretty useless without some decent software to program it.

Level 1 and Level 4 is relatively sorted. (Remember, Level 1 is a basic android app to control the robot and Level 4 is essentially regular stm32 programming using the available toolchain). Level 2 and Level 3 are however very important since most users will use those.

For a quick reminder, Level 2 is a visual programming interface using blockly and Level 3 is an arduino type library that lets you concentrate more on the logic of your robot and less on the low level initialization of the stm32 pheripherals.

For level 3, I'm taking inspiration from the Arduino library. This means that the functions are basic control functions for setting inputs and outputs and a few Benny Bot specific commands (like the motor control).

For example a basic program that reacts on a digital distance sensor (in this case the Sharp GP2Y0D810Z0F Digital Distance Sensor) for basic obstacle avoidance would like look this:

  setPinMode(IO7, PIN_MODE_INPUT);

  setMotorSpeed(MOTOR_BOTH, 100);

  while (1)
    if ( getPinState(IO7) == HIGH )
      setPinState(LED, HIGH);
      setMotorDirection(MOTOR_LEFT, MOTOR_DIRECTION_FWD);
      setMotorDirection(MOTOR_RIGHT, MOTOR_DIRECTION_FWD);
      setMotorSpeed(MOTOR_BOTH, 100);
      setPinState(LED, LOW);
      setMotorDirection(MOTOR_LEFT, MOTOR_DIRECTION_REV);
      setMotorDirection(MOTOR_RIGHT, MOTOR_DIRECTION_FWD);
      setMotorSpeed(MOTOR_BOTH, 100);

I created the following functions for testing this library, which I call the easylib library
// functions

// motor functions
void setMotorSpeed(uint8_t Motor, uint8_t Speed);
void setMotorDirection(uint8_t Motor, uint8_t Direction);

// io functions
void setPinMode( uint8_t pin, uint8_t mode );
void setPinState( uint8_t pin, uint8_t state);
uint8_t getPinState( uint8_t pin );

The library also consists of defines for motor/io selection to make things easier:

#define IO1 0					// gpio/i2c sda/
#define IO2 1					// gpio/uart/pwm	** bluetooth module connected to this pin - SJ1
#define IO3 2					// gpio/uart/pwm	** bluetooth module connected to this pin - SJ2
#define IO4 3					// gpio/i2c scl
#define IO5 4					// gpio
#define IO6 5					// gpio/spi mosi/pwm
#define IO7 6					// gpio/spi miso/pwm
#define IO8 7					// gpio/spo sck/pwm
#define BUTTON 8				// input
#define LED    9				// output

#define MOTOR_LEFT	0
#define MOTOR_RIGHT 1
#define MOTOR_BOTH  2


#define PIN_MODE_INPUT  0

#define HIGH 1
#define LOW  0
Obviously this library still needs a lot more functionality, but it does have enough to get Level 2 working.

For level 2 I settled on using the Google blockly library. I've been hard at work having it generate code that can be compiled by the gcc compiler. The idea is similar to how the arduino ide works, it generates the basic program that gets included in the bigger project when it gets compiled. The code it generate is basically the various easylib (from Level 2) functions.

Blockly works great for generating the code, but getting it loaded onto the benny bot is a different story. Initially I just copied and pasted the generated the code into my c file and ran a makefile. It works, but not ideal for a classroom environment.

To improve this I create a basic python server based on CherryPy. When the user clicks on the 'Program Benny' button, it performs the following actions:

  1. Create generated code based on the blocks
  2. Insert the generated code into a base project
  3. Compile the base project and generate the firmware
  4. Convert firmware to dfu format
  5. Try and load firmware to connected dfu bootloader over usb.

I currently have the basic concept working from blocks to firmware loaded onto Benny, but it still needs work in terms of error checking/handling, reliability.

It does however work great and I'll probably stick to this concept. Not sure how I would package all of this neatly so that a user can just download a single installation and get going, but will figure it out. Next step for the blockly interface is adding loading/saving capability of the programs and also extending the easylib library :)