Introduction: HelveKit Robot: How I Designed a Robot

About: chipKIT enthusiast

In this Instructable I want to describe how I designed a little robot, what guided my thoughts and why I took certain decisions. I deliberately did not name it "How to design a robot" as I have no intend to tell somebody how he/she should design their robot. So if you find things done in a unusual way, smile at it and consider that I have never learned how to do this. If you wan to do things different - go ahead! This article only reflects the results of a more than 12 months long journey. I hope you enjoy the outcome.

Guiding principles

I had a few goals with this robot:

  • Small - originally aiming at less than 5cm * 5cm, I ended up with 9.5cm * 6cm excluding wheels with all the features I had added to the robot
  • Cheap - all parts should sum up to less than 50 USD. Currently I need about 30-35 USD with low volume discounts. All other robots I have seen so far with similar features were way above 100 USD which makes it unattractive for students and scholars
  • Easy to Solder - Originally I started out with through-hole parts but switched to SMD parts early in the design phase. I use SMD1206 parts that are easy to solder with some practice. The tricky most part is a chip with TQFP-44. Using the flood/suck technology, even these parts are easy to solder by hand
  • Easy to Program - The robot should be programmable via the Arduino IDE or UECIDE (an IDE I can recommend for programming Arduino boards and ChipKIT boards)
  • Autonomous - The robot should be able to act autonomously with its own micro controller, Furthermore, it should be able to talk to other devices such as an Arduino, ChipKit or Raspberry-Pi board.
  • Plenty of holes - a good robot has plenty of holes to connect additional devices including the holes for Arduino shaped boards to be carried on top
  • Swarm capable - the robot should be able to exchange information with other robots of this kind

Step 1: Move the Robot

The robot follows the very common car design with two motors building an axle and a caster ball instead of a second axle.

Motor Selection

I selected a small gear motor that you can get for a few USD/EUR that run at Voltages of 3-12 V with a directly connected transmission at a gear ratio of 1:50 - 1:200. They all have the same size and come with a simple housing to screw them to the plate of the robot. I prefer motors with a high gear ratio, as they move slower, which makes debugging of the code easier. As the motors are cheap, I got me a pair of all ratios.

Lately I found a gear motor with a built-in encoder. This instructable does not handle this but as a preparation, I inserted a large hole in the robot plate to be able to pass cables from the bottom side to the top side for processing.

The wheels I use are Pololu 32x7mm Wheels.

Driving, Push or Pull

The simple car setup makes driving pretty simple. As long as the motors turn at the same speed, the robot goes straight forward. as soon as one motor runs at a slower speed, the robot turns towards that side.

The direction decides, if we have a push configuration with the caster ball in front or a pull configuration with the caster ball behind. Both configurations have advantages and disadvantages. I therefore decided to take this into account for the further design to offer both configurations. This is the reason for the odd hexagon shape of the robot plate.

Motor Driver

There are plenty of motor drivers available. I decided to use the L9110 as it is very simple to handle and comes with internal protecting diodes and the following features

  • Low quiescent current
  • Wide supply voltage range: 2.5V -12V
  • 800mA continuous cur rent output capability per channel
  • Lower saturation voltage
  • TTL / CMOS output level compatible
  • can be directly connected to the CPU
  • Output built -in clamp diodes for inductive load
  • Integrated control and drive into a monolithic IC
  • With pin high -voltage protection function
  • low price

The function of a motor driver is described on lots of internet pages, so I will not repeat this here again. Searching for L9110 gives you plenty of information

The last three pictures show a test setup to get used to the driver chip and the way I put the parts on the robot plate.

Schematic for motor driver

The schematic shows the simplicity of this chip. You just connect the motor supply voltage ad GND and the input pin state determine the movements of the motor.

I added a 4.7 uF capacitor on both L9110 driver chips to compensate the power drain a motor takes when started, stopped or reversed. Depending on the motor used, these may need to be adjusted in capacity.

I also added LEDs to each input line. This is very convenient while programming the robot, as you can see what your code is doing without moving the robot by switch off the supply voltage. The LEDs are connected via solder pad jumpers (SJ1-SJ4). This saves battery power once the code is final and the LEDs are no longer needed. Opening these solder pad jumpers disables the LEDs.

Step 2: Power the Robot

Simple Power Setup

The power setup of the robot is very common and simple: I use two LM1117 voltage regulators with 3.3V and 5V fixed output and a maximum current of 1 A. They are located on the robot plate at a place that a heat sink can be attached if needed.

There are three input connectors:

  • JST socket
  • 2 0.1" pins
  • screw terminal

and the incoming voltage is protected by a diode (1N5819).

The incoming voltage goes via a switch to the input of the 5V voltage regulator. The output of that chip goes to the 3.3V regulator that is used for the chips on the robot as VDD/VCC.

The now available three voltages (Vin, 5V and 3.3V) are now hooked up to a 3x2 header where the motor voltage can be selected via a jumper. That motor voltage is then connected to the motor drivers via a switch to power the motors independently from the robot logic.

As I want to power the robot from the USB connection I use to program and debug the robot, VBUS from the USB port is connected with the 5V network and protected by a diode (1N5819)

Step 3: Add a Micro-controller

The next step is to select a micro-controller to give the robot the capability to act autonomously. There are plenty of micro-controllers available ranging from the popular ATmega328 used for the Arduino up to the chips of the raspberry pi. The later however is not for hobby soldering.

I selected the PIC32MX270f256D from Microchip for the following reasons:

  • 256 kB Flash - this gives me plenty of memory to program complex robot activities. This is 8 times the 32 kB of the ATmega328
  • 64 kB RAM - this is 32 times the ATmega328 2kB
  • 48 MHz clock speed - 3 times the ATmega328
  • 5 hardware interrupts - good for handling sensors (see later steps)
  • 2 I2C buses - I will use them for communication and a display
  • 2 UART - this is one of the most beneficial features, as it allows to connect a bluetooth interface withotu interfering with the USB connection as of the Arduino
  • USB on chip - I can connect the USB port directly to the micro-controller without the need of a FTDI chip
  • TQFP-44 - this chip pinout can be soldered by hand with some experience
  • Arduino IDE compatible - with the chipKIT bootloader, I can program the robot the way I program an Arduino. Most of the Arduino libraries work with the chip and only a few adjustments need to be done if 8-bit needs to be ported to 32.bit
  • Task Manager - a powerful chipKIT feature to handle the execution of (semi-)parallel tasks, making programming so much easier

The picture shows the micro-controller and the peripheral electronics needed. The chipKIT bootloader boots directly into the current sketch unless you press the program button when pushing RESET. That puts you into bootloader mode and you can download the compiled sketch.

The bootloader is written to the chip using the PICKIT-3 adapter. The pin-1 on the connector is marked and the holes of the jumper in the PCB are slightly offset to allow a programming without soldering headers.

Soldering the TQFP-44 chip

At first sight, it appears impossible to solder such a chip with a soldering iron. But there is a simple technique that allows you to solder such a chip using the "flood-suck" technology:

  • You position the chip in the right place on the PCB
  • solder one pin in the corner to fix that position
  • solder one pin on the opposite side to add stability to the chip location
  • solder all pins on one side with plenty of solder - all pins are shortened by the solder
  • Heat the solder and use a suction pump to remove the solder
  • and you are done.

It takes about 5 - 10 Minutes to solder the chip that way and most of the time is spent on positioning the chip correctly.

Of course, there are other techniques, e.g. solder paste and a stencil. Use what works best for you.

Step 4: Time for a First Test

Now would be a good moment to test the motors in a simple way by driving forward, backward left and right for a defined period of time. The code looks quite simple:

#define M1A 22
#define M1B 21
#define M2A 20
#define M2B 19

void setup() {
  Serial.begin(9600);
  pinMode(M1A, OUTPUT);
  pinMode(M1B, OUTPUT);
  pinMode(M2A, OUTPUT);
  pinMode(M2B, OUTPUT);
  digitalWrite(M1A, HIGH);
  digitalWrite(M1B, HIGH);
  digitalWrite(M2A, HIGH);
  digitalWrite(M2B, HIGH);
}

void loop() {
  int wait=5000;
  Serial.println("Forward");
  digitalWrite(M1A, HIGH);
  digitalWrite(M2A, HIGH);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(wait);
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(50);
  Serial.println("Backward");
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, HIGH);
  digitalWrite(M2B, HIGH);
  delay(wait);
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(50);
  Serial.println("Left turn");
  digitalWrite(M1A, HIGH);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(wait);
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(50);
  Serial.println("Right turn");
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, HIGH);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(wait);
  digitalWrite(M1A, LOW);
  digitalWrite(M2A, LOW);
  digitalWrite(M1B, LOW);
  digitalWrite(M2B, LOW);
  delay(50);
}
 

Step 5: Adding Sensors: Collision Avoidance

A very common sensor for robots is the TCRT5000 infrared sensor with an infrared LED and an infrared sensor in one housing. The light from the LED is shielded from the sensor so that only reflected light gets to the sensor.

The disadvantage of this sensor is that black or non-reflective surfaces are not detected.

I use a setup, where the signal is taken from a pull-up resistor (R2, 10kOhm) and sent to an inverter chip (74HC14D). With incoming light, the infrared sensor will shift the voltage level at the input of the 74HC14D matching the intensity of the incoming light. Once a threshold is reached, the output signal of the inverter is going from LOW to HIGH. The LED D1 is optional to show that the sensor has triggered. R3 limits the current of that LED and the super-bright LED I use, run well with the 1kOhm giving a current of 3 mA at the 3.3V I use as Vcc.

In addition to the digital state of the sensor, the analog signal at the input of the 74HC14D is connected to an ADC pin of the micro-controller. This offers the opportunity to write code that acts on the level of the incoming light.

R1 limits the current/brightness of infrared LED.

Positioning the sensors

The 74HC14D has 6 inverters, so I decided to put a TCRT5000 in each corner and one in the center on each side. The sensors are placed in a way that the receiving infrared sensor points to the outside of the robot giving a maximum reception angle.

Selecting the infrared LED voltage

Initially, the infrared LEDs are lightened permanently. In the course of the development of this robot I got the idea to have the choice to either light the LED permanently or to drive it from the micro-controller. Only the center LED are still permanently on to have a fail-save collision detection.

With the light of the corner sensors controlled by code, I could send signals, e.g. Morse Code to other robots.

There is a header setup that offers the selection of either 5V or 3.3V as permanent LED voltage and the choice to wither permanently light the LED or use the micro-controller.

Selecting the Sensor input

The second header row offers to connect the digital sensor signals to the 5 interrupt pins of the micro-controller. As there are only 5 interrupts, the right-most 3 pins select the center sensor to be used. This way, it can be aligned with the push or pull configuration of the robot.

In case that you want to use other sensors, these pins offer to connect other sensors to the interrupt lines.

With these headers, it is possible to configure the robot in a very flexible way, offering a quite powerful default sensor setup.

Step 6: Using the I2C Bus

I like the I2C bus and will use it for two purposes:

  • add a I2C based OLED display
  • add a 32 kB EEPROM

OLED Display

There are cheap OLED displays available that use the SSD1306 driver and the I2C bus to communicate with the micro controller. Unfortunately, these OLEDs come in different pin configurations. So far I encountered:

  • GND - VCC - SDA - SCL
  • GND - VCC - SCL - SDA
  • VCC - GND - SDA - SCL
  • VCC - GND - SCL - SDA

I therefore added a 3-pad solder jumper to each pin. For the first two pins, GND and VCC can be assigned to the respective pin, for the remaining two pins, SDA and SCL can be assigned according to the OLED in use.

EEPROM

The PIC32MX270f256D processor I have chosen has no built in EEPROM. I therefore added a 24LC256 EEPROM chip to the robot. This gives me 32 kB of memory where I can store configuration information for the robot.

Next to the EEPROM, I located the headers for the I2C bus and the UART to connect additional devices. The headers are placed in a way that an Arduino, that is placed on top of the robot is not blocking the pins.

Step 7: Adding an Arduino or ChipKIT Board

I have added holes to the robot that allow me to add a micro-controller board that is Arduino shaped like the chipKIT Lenny or the original Arduino Uno.

With a second micro-controler board on top, the robot can take care of the movements and be configured as a serial slave or I2C slave to take commands from the top board. The top board can be used to execute additional code.

The chipKIT Lenny has the same processor as the robot.

I also added holes to add my HelvePic32SMD board, a board similar to the chipKIT Lenny with a different form factor.

The UART and I2C pins are 5 Volt tolerant. Connecting an Arduino Uno via these pins can be done without level shifting parts.

Step 8: Programming the Robot

Using the Arduino IDE

One way to program the robot is to use the Arduino IDE and to load the chipKIT core board definitions and programming tools. I used the chipKIT Lenny bootloader on the robot so all that is left to do is to select that board. The programming is the same as for an Arduino board.

Using the UECIDE

There is a great IDE alternative to the Arduino IDE called UECIDE. This is the IDE I use most of the time to program the robot. The board definition files can be downloaded in the Download step

Pin Assignment

TypeFunctionUsageLabelPortSpecialPin
INPUTIR Signal from 74HC140Front RightFRGTRB13INT20
INPUTIR Signal from 74HC140Rear RightRRGTRB14INT13
INPUTIR Signal from 74HC140Rear LeftRLFTRA1INT36
INPUTIR Signal from 74HC140SelectedCenterFCTRRB7INT024
INPUTIR Signal from 74HC140Front LeftFLFTRB15INT44
OUTPUTIR-LED stateLed Front LeftLFLRC930
OUTPUTIR-LED stateLed Front RightLFRRC829
OUTPUTIR-LED stateLed Rear LeftLRLRC728
OUTPUTIR-LED stateLed Rear RightLRRRC627
OUTPUTMotor Driver PWMMotor 1 AIN1ARC522
OUTPUTMotor Driver PWMMotor 1 BIN1BRC4PWM21
OUTPUTMotor Driver PWMMotor 2 AIN2ARC3PWM20
OUTPUTMotor Driver PWMMotor 2 BIN2BRA919
INPUTraw IR signalFront RightRAW-FRGTRA0A05
INPUTraw IR signalFront CenterRAW-FCTRRB2A49
INPUTraw IR signalFront LeftRAW-FLFTRB3A510
INPUTraw IR signalFront RightRAW-RRGTRC0A611
INPUTraw IR signalRear CenterRAW-RCTRRC1A712
INPUTraw IR signalRear LeftRAW-RLFTRC2A813
I2CI2C busSCLRB825
I2CI2C busSDARB926
UARTSerial PortRXRA418
UARTSerial PortTXRB417
USBUSB ConnectD+RB1031
USBUSB ConnectD-RB1132
GPIOpins with GVS setupfreeS4RA101
GPIOpins with GVS setupfreeS3RA72
GPIOpins with GVS setupfreeS2RB0A27
GPIOpins with GVS setupfreeS1RB1A38
GPIOpins with GVS setupfreeS0RB5PWM23
PROGhold to start bootloaderbootloaderRA816
OSC1n/aCrystalRA3n/a
OSC2n/aCrystalRA2n/a

Step 9: Outlook and Next Steps

License: Creative Commons - BY - NC - ND - 3.0

This robot and this documentation is published under the Creative Commons License CC-BY-NC-ND-3.0

For private use, you can download the Eagle design files, create your PCBs, source the parts and build it. The micro-controller needs to be flashed with the chipKIT bootloader that you can download from this instructable as well.

I am considering building a batch of robot PCBs with the chips (PIC32MX270f256, 74HC14D, 24LC256) soldered to the board. The remaining parts are a simple soldering exercise, even that the parts are SMD. Soldering the TCRT5000 takes most of the time and if I would charge anyone for that effort, the robot becomes unnecessarily expensive.

Step 10: Downloads

Here are the files for download