Tuesday, August 23, 2016

The iRobot Create and STM32 Nucleo F411RE board.


It's been a while since I did any project related to robotics. I have never done anything advanced, but some time ago (about 10 years) me and few friends from work got interested in the topic of making our own autonomous robot and programming it for fun and ultimately entering some competition with it.
We have never got that far, but what we ended up with was buying iRobot Create and Qwerk 1.2b robotic controller module from Charmed Labs for a considerable cost (at that time all that single board cheap computers, boards and shields were not as readily and cheaply available as they are today).
I don't think that Charmed Labs carry this module anymore. It was a single board computer powered by 200 MHz ARM9 RISC processor and Linux O.S. with multitude of I/O pins already built in and useful for robotic applications (digital I/O, analog I/O, servos, motors). It's been advertised as a Telepresence Robot Kit (TeRK). On top of Linux ran a server that used CORBA like protocol (ICE) to which client application written in Java, C# or C++ could connect remotely to control the hardware connected to the controller.

Here is the actual module that I still have:


and below are some of our (mostly mine as my friends lost interest quite quickly) clumsy attempts at making a robot based on iRobot Create platform and the Qwerk controller:


That robot's main function was to autonomously ride around the house, avoid obstacles and take pictures. It could also talk. The iRobot Create has its own controller and default programs for navigating autonomously of course, because it is basically Samba vacuum cleaner with the vacuum hardware removed to make a space/cargo bay for a controller, sensors and other junk to be able to piggy back on it. Thanks to iRobot's Open Interface, accessible via serial port, the platform could be controlled by external computer which was desirable and much more interesting than just running built in programs of a robotic vacuum cleaner.

Anyway, long story short, the Qwerk controller proved to be buggy and clumsy to use. It crashed constantly, WiFi often froze, etc. I ran out of ideas and didn't have proper skills to develop anything more interesting out of this robot.
After few more failed attempts at image (from camera) processing and light following (servo turret, now I have enough knowledge to know that this should be done with PID method) I finally got bored with it and moved on to other projects. Robot has been dismantled and stored.

In recent days I took the iRobot Create out of the box and charged it. The plan is to use one of the modern (Arduino or similar) SBC-s to control it via iRobot's Open Interface. I had an unused and untested yet STM32 Nucleo F411RE board. With some extra hardware and mbed IDE I have been able to write short program that sends data via Open Interface to play short melody via robot's internal speaker. That's a start. I will expand upon that code by implementing more commands and ultimately a library to create a skeleton for an autonomous robot, similar to the one I made before. I want it to be able to follow the light, ask to be recharged, avoid obstacles and bring me beer from the fridge (well, maybe this is too far for my skill, but who knows where this project will lead me?)

Here is the code:

#include "mbed.h"

Serial pc(PB_6, PB_7);  // TX, RX : UART1
DigitalOut myled1(LED1);

/*
    Hardware:
    
    STM32 Nucleo-F411RE board.
    RS232-TTL module.
    DB9 NULL MODEM connector.
    DB9 GENDER CHANGER.
    iRobot Create.
    iRobot Serial Mini DIN to DB9 converter/adapter.

    Connections:
    
    Pin PB_6 (TX, CN5.3, Arduino D10) -> RS232-TTL RXD
    Pin PB_7 (RX, CN7.21, Morpho)     -> RS232-TTL TXD
    Pin GND  (CN7.22, Morpho)         -> RS232-TTL GND
    Pin +5V  (CN7.18, Morpho)         -> RS232-TTL VCC
    iRobot Create Mini DIN -> Serial Converter -> NULL MODEM -> 
    -> Gender Changer -> RS232

*/

int main() {
  // play melody on iRobot Create every 10 seconds via Open Interface
  int data[20] = {128, 132, 140, 0, 4, 62, 12, 66, 12, 69, 12, 74, 36, 141, 0, 
                    -1};
  pc.baud(57600);
  wait(1.0);
  myled1 = 0;
  while(1) {
    int i = 0;
    while(data[i] >= 0) {
      pc.putc(data[i]);
      i++;
    }
    wait(10.0);
    myled1 = !myled1.read();
  }
}


The RTOS variant of the code which executes 3 tasks in parallel:

#include "mbed.h"
#include "rtos.h"

#define NL "\n\r"

using namespace rtos;

void print_char(char c = '*')
{
    printf("%c", c);
    fflush(stdout);
}

DigitalOut led1(LED1);

void print_thread(void const *argument)
{
    int n = 20;
    while (true) {
        Thread::wait(1000);
        print_char();
        n--;
        if (n == 0) {
            n = 20;
            printf(NL "... and again ..." NL);
        }
    }
}

Serial pc(PB_6, PB_7);  // TX, RX : UART1
int data[20] = {128, 132, 140, 0, 4, 62, 12, 66, 12, 69, 12, 74, 36, 141, 0, 
                    -1};

void irobot_thread(void const *argument)
{
  pc.baud(57600);
  Thread::wait(1000);
  while(1) {
    int i = 0;
    while(data[i] >= 0) {
      pc.putc(data[i]);
      i++;
    }
    Thread::wait(60000);
  }    
}

int main()
{
    printf(NL NL "*** RTOS basic example ***" NL);
    Thread t1(print_thread);
    Thread t2(irobot_thread);
    while (true) {
        led1 = !led1;
        Thread::wait(125);
    }
}

and some pics and a video:


Hopefully I will find time for this project and some more updates will come soon.
Thank you for visiting.

M.K.
8/24/2016