Introduction: GOduino III - the Breadboard-friendly Arduino-based Robot Controller

About: Did I unplug the solder iron?
UPDATES
  • Nov 16, 2012 Featured on DangerousPrototypes.com  http://goo.gl/N4DIC
  • Oct 3, 2012: I have designed a PCB adapter to help position IR & Ultrasonic sensors 90 degree to breadboard to support GOduino III robot projects
  • Sep 1, 2012: Added EAGLE board layout

INTRODUCTION

The GOduino III is an inexpensive Arduino compatible Open Source Hardware robot controller. It's a simple and inexpensive robot controller (appx. $25). I built this controller for my robotics workshops as well as for my personal projects. The GOduino III can be inserted into a breadboard for easy prototyping. I have also developed a software library (Goduino.h) to support motor functions. It's an extension of Adafruit's Boarduino

NOTE: This is my first PCB project so your feedback is most appreciated. I am also certain this guide contains plenty of typos. So over the next few days I will be making corrections and adding more details based on readers' feedback. Thanks in advance for your assistance.

BACKGROUND

This is a 3rd generation GOduino. The one before was the prefboard GOduino II and the first one was a breadboard GOduino.

1) GOduino II (prefboard)
https://www.instructables.com/id/GOduino-II-Arduino-L293D-Variable-Speed-Motor-/

2) GOduino I (breadboard)
https://www.instructables.com/id/GOduino-The-Arduino-Uno-Motor-Driver-clone/

OVERVIEW

The GOduino III is based on the ATmega328p microcontroller and the L293D dual h-bridge. It's built with DIP ICs and through-hole components for ease of assembly and repair.  This robot controller can handle 2 small servos and 2 DC brushed motors (max 1.2A for each motor with 2 X L293D).

The GOduino III can be programmed with a standard Arduino IDE via an FTDI USB/UART programmer or via the ICSP header using programmers such as AVR-ISP, STK500, or parallel programmers.

SPECIFICATIONS
  • Based on the ATmega328p microcontroller @ 16 MHz (the heart of the Arduino Uno DIP model)
  • Size:  5cm X 2.5cm.
  • Plugs into a breadboard with the help of 0.1" (2.54mm) male headers or you can solder female headers. 
  • Arduino standard digital, analog, and special purpose pins exposed.
  • Digital I/O Pins: 14 (of which 6 provide PWM output) - Analog Input Pins: 6
  • 2 X LED: one for power and another for pin 13.  
  • Reset button.
  • 2 X 3-pin 0.1" (2.54mm) headers (5V) for small servos.
  • 2 X 2-pin 0.1" (2.54mm) header for brushed DC motors.
  • 6-pin 0.1" (2.54mm) ICSP male header.
  • 6-pin 0.1" (2.54mm) male header to accommodate FTDI USB programmer.
  • Flash Memory: 32 KB of which 0.5 KB used by bootloader
  • SRAM: 2 KB
  • EEPROM: 1 KB  

PROGRAMMING
  • The GOduino III can be programmed with the Arduino IDE via an FTDI USB programmer
  • It can also be programmed via the ICSP header using programmers such as AVR-ISP, STK500, or parallel programmers.
  • The FTDI "FT232RL USB to Serial adapter" can be purchased for less than $10 from Ebay.
  • Also, you can use an Arduino Uno DIP to program the GOduino III ATmega328 microcontroller then insert it back into the GOduino III.
  • Auto-reset capability for FTDI programmers via the DTR pin.  

POWER
  • Logic Voltage: 5V supplied by the T7805CV regulator. 
  • Input Voltage (recommended): 7-12V. (limits): 6-20V
  • Motor Voltage: While the L293D motor driver IC is rated for 4.5V to 36V, we are bound by the recommended/limit  voltage ratings of the power regulator. 
  • 1N7001 diode protects against reverse voltage from the external power source.
  • The L7805CV regulator provides 1.5 A which is enough to power the GOduino III and 2 small servos.
  • You can swap the 7805 with pin-compatible low-drop out voltage regulators with higher current such as the LM1084-5V which can source 5A with a maximum dropout voltage of 1.5V.
  • The 5V regulator also powers the servos but not the motors.
  • For the motors, the L293D h-bridge gets its power from the DC jack or from the VIN pin directly. 
  • You can select to power the GOduino III from USB or External power with a pin jumper. Please note that USB power may not be enough to operate servos and motors.
  • The L293D h-bridge can supports 2 DC motors @ 600mA continuous current each. You can piggyback two L293D to double the current to 1.2A per DC motor. 

PARTS
  • Capacitor ceramic 0.1uF X 5
  • 10uF/25V
  • 100uF/16V
  • 100uF/6V X 2
  • Diode 1N4007
  • LED Red 3MM
  • LED Green 3MM
  • ATMEGA168P Microcontroller
  • 7805 5V regulator
  • L293D dual h-bridge
  • DC Jack female 1X2-3.5MM
  • 40-pin male header (0.1" 2.54mm)
  • DIP sockets 28-pin
  • DIP socket 16-pin
  • Resistor 10K Ohms
  • Resistor 1.0 K Ohms X 2
  • Reset button
  • 16.00MHz Ceramic resonator 3-pin

I am considering replacing the 3.5mm DC power jack with a terminal block for the next patch of GOduino PCBs.

You can get the EAGLE schematics for the PCB from Github along with the library. The board layout is being modified but I will post it to Github soon as I am done.

SOFTWARE LIBRARY

There are 4 motor functions in the Goduino library. They will be explained in the section on controlling motors. 
  • motorSpeed(mot1speed, mot2speed)  Sets speed for both motors.
  • motorStop(motorNum)  Stops a motor.
  • motorForward(motorNum)  Spins a motor in one direction.
  • motorBack(motorNum) Spins a motor in the reverse direction.
The GOduino III motor library and other support files can be downloaded from Github:
https://github.com/techbitar/goduino

VIDEO



Step 1: The Eagle Schematic

The GOduino III is Open Source Hardware so anyone can download and reuse the design files from Github in Eagle 6.x formats.

https://github.com/techbitar/goduino

Step 2: Controlling 2 DC Brushed Motors


The GOduino III uses the L293D h-bridge (motor driver) which is a robust and inexpensive DIP IC that simplifies circuit design. It has built-in EMF protection and thermal shutdown in case motors pull too much current which might also damage the L293D.

A single L293D can control 2 brushed DC motors with peak/stall current up to 600mA per motor. Peak/stall current is the current the motor draws when prevented from rotating while still powered. 

If you piggyback two L293D ICs, you can double the current of the GOduino III to 1.2A per motor. This is more than enough to power most DC motors for small robots.

Pololu and Solarbotic, for example, provide a wide selection of motors that work well within the current ratings of the L293D. 

The L293D logic circuit is powered via the GOduino III power regulator (7805) but the L293D's motor control circuit is powered directly from the battery. 

Each motor is powered from the L293D via a 2-pin male header (Motor 1 and Motor 2). The order of connecting a motor poles to the 2-pin header decides the rotation direction of the motor. You can also change motor rotation direction from your Arduino sketch. 

TIP: Solder a 0.1uF ceramic capacitor across the poles of your brushed DC motor for added circuit stability. Shorten the leads on the capacitor as much as possible for better response and to avoid accidental electric shorts. 

The GOduino III's ATmega328 pins are mapped to the L293D h-bridge in this manner (using Arduino pin numbering system):

Motor 1 Pole1 --->  Arduino Pin  4
Motor 1 Pole 2---> Arduino Pin 2
Motor 1 Enable ---> Arduion Pin 5 (PWM)

Motor 2 Pole1--->  Arduino Pin 7
Motor 2 Pole2 --->  Arduino Pin 8
Motor 2 Enable ---> Arduion Pin 6 (PWM)

THE SOFTWARE LIBRARY

I wrote the Goduino motor library to eliminate the need to memorize the HIGH, LOW pin output sequences needed to turn or stop a motor. 

There are 4 functions in the Goduino motor library:
  • motorSpeed(mot1speed, mot2speed)  Sets speed for both motors.
  • motorStop(motorNum)  Stops a motor.
  • motorForward(motorNum)  Spins a motor in one direction.
  • motorBack(motorNum) Spins a motor in the reverse direction.
PARAMETERS

There are two 2-pin male headers on the GOduino III PCB: Motor 1 and Motor 2. Any functions in the Goduino motor library that take a single parameter, it's either 1 for Motor 1 or 2 for Motor 2.

The only function that takes two parameters is the motorSpeed() function. The first parameter sets speed for Motor 1 and the second sets speed for Motor 2. The maximum speed is 1023. This means your motor's max speed can be increased or decreased by 1023 increments.  

The GOduino III library and other support files can be downloaded from Github:
https://github.com/techbitar/goduino

You can use the example code (motortest.ino) included in the Goduino library under the examples folder to test and synchronize the direction of motor rotation. The video shows the GOduino III running the test routine. From the Arduino IDE open:

                     Files/Examples/Goduino/motortest

NOTE: I have avoided using Arduino Uno pins 3 and 11 because they are used by the Arduino tone() function. So now I can build a robot that makes noise.  (applause).

This is the test code used in the video. Please check my Github for updates and bug fixes:

/*
File: motortest.ino - example sketch to test the GOduino III robot controller.
Created by: Hazim Bitar (techbitar at gmail dot com)
Date: August 23, 20012.
Version: 0.11 beta
License: Released into the public domain.
*/

#include <Goduino.h>

Goduino myrobot;

void setup() {
  Serial.begin(9600);
  Serial.println("Set speed of both motors to 100 (max 1024)");
  myrobot.motorSpeed(50,50);
}

void loop() {

  Serial.println("TEST PHASE I - SPIN BOTH MOTORS TOGETHER IN SAME DIRECTION");
  delay(3000);

  Serial.println("Spin both motors in one direction (3 sec)");
  myrobot.motorForward(1);
  myrobot.motorForward(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin both motors in opposite direction (3 sec)");
  myrobot.motorBack(1);
  myrobot.motorBack(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  //=================================================================================

  Serial.println("TEST PHASE II - SPIN EACH MOTOR OPPOSTE OF THE OTHER");
  delay(3000);

  Serial.println("Spin  motor 1 in one direction while motor 2 in opposite direction (3 sec)");
  myrobot.motorForward(1);
  myrobot.motorBack(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin  motor 2 in one direction while motor 1 in opposite direction (3 sec)");
  myrobot.motorBack(1);
  myrobot.motorForward(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  //=================================================================================

  Serial.println("TEST PHASE III - SPIN EACH MOTOR WHILE THE OTHER IS STOPPED");
  delay(3000);

  Serial.println("Spin motor 1 in one direction while motor 2 is stopped (3 sec)");
  myrobot.motorForward(1);
  myrobot.motorStop(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin motor 2 in one direction while motor 1 is stopped (3 sec)");
  myrobot.motorForward(2);
  myrobot.motorStop(1);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin motor 1 in reverse direction while motor 2 is stopped (3 sec)");
  myrobot.motorBack(1);
  myrobot.motorStop(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin motor 2 in reverse direction while motor 1 is stopped (3 sec)");
  myrobot.motorBack(2);
  myrobot.motorStop(1);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

}


Step 3: Controlling 2 Servos


There's nothing special about controlling servos with the GOduino III. Simply follow the instructions on the Arduino website and you will be spinning servos in no time.

http://arduino.cc/it/Reference/Servo


After connecting your servos, to do a quick test load the Sweep.ino sketch which turns the servos forward and backward. From the Arduino IDE open:

                    Files/Examples/Servo/Sweep

Make sure you change the number in the myservo.attach(SERVO_PIN_NUMBER) to either pin 9 or pin 10 depending on whether you connect your servo to the Servo 1 or Servo 2 header on the GOduino III.

Then upload the sketch to the GOduino III and watch the servos turn. 

You can connect additional servos (limited to the current supplied by the regulator and heatsink effectiveness) by using the The Software Servo Library

http://www.arduino.cc/playground/ComponentLib/servo

This blog entry has some useful information on the use of the Software Servo Library
http://rcarduino.blogspot.com/2012/01/can-i-control-more-than-x-servos-with.html

Please keep in mind the power requirements and regulator heat issues when using servos. Consider attaching a heat sink to the regulator to help with heat dissipation and to avoid thermal shutdown and random circuit resets. 

If small servos are not enough, you may need a beefier regulator such as the LM1084-5V which can source 5A with a maximum dropout voltage of 1.5V. Check the servo datasheet to ensure it can operate on 5V. 

This is the test code used in this video:

// Sweep
// by BARRAGAN <http://barraganstudio.com>
// Remixed by Hazim Bitar for GOduino III robot controller servo test
// This example code is in the public domain.


#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
Servo myservo2;  // create servo object to control a servo

int pos = 0;    // variable to store the servo position

void setup()
{
  myservo1.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo2.attach(10);  // attaches the servo on pin 9 to the servo object
}


void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'

    delay(15);                       // waits 15ms for the servo to reach the position

  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position


  }
}


Step 4: Building a Breadboard Robot With GOduino III



This is a breadboard robot prototype that I built in less than half an hour. I  wanted to see how quickly  I can assemble a GOduino III robot on a breadboard platform on a shoestring budget. The robot is programmed (via the FTDI USB programmer) to move back and forth. 

The wheels are covers for plastic containers. I used adhesive pads to give them more  thickness so the screws don't stick out too much. 

I used two GM9 plastic gear motors wich can be bought for $6 each from places like Solarbotic, Robotshop, Pololu. These brushed DC motors are rated at a peak/stall current of 700mA @ 6V which is fine for the GOduino III.  

The bottom of the breadboard has an adhesive strip attached to it. I just peeled off part of it and affixed the two GM9 motors.

I used a  7.4V (2-cell) Lipo battery and also tested the setup with 7.5V (6 X AA NiMh) battery pack and it worked. There's about 1V drop across the L293D so that brought the voltage down to near 6.5V which is slightly over the motors 6V ratings. The batteries were kept in place over the breadboard with a piece of tape.

For caster, I used a ping pong ball attached with tape to the breadboard.

I can add sensors and other parts by plugging them directly into the breadboard and connecting them to the GOduino III with jumper wires.

For rapid and cheap robot prototyping and for my workshops, the breadboard-friendly form factor of the GOduino III can make life easier for newbies but has all the needed power for my personal robot projects.  

This is the code used in this video:

#include <Goduino.h>

Goduino myrobot;

void setup() {
  Serial.begin(9600);
  Serial.println("Set speed of both motors to 100 (max 1023)");
  myrobot.motorSpeed(1000,1000);
}

void loop() {

  Serial.println("TEST PHASE I - SPIN BOTH MOTORS TOGETHER IN SAME DIRECTION");
  delay(3000);

  Serial.println("Spin both motors in one direction (3 sec)");
  myrobot.motorForward(1);
  myrobot.motorForward(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

  Serial.println("Spin both motors in opposite direction (3 sec)");
  myrobot.motorBack(1);
  myrobot.motorBack(2);
  delay(3000);

  Serial.println("Stop both motors for 1 sec");
  myrobot.motorStop(1);
  myrobot.motorStop(2);
  delay(1000);

}

Step 5: GOduino III Object Avoidance Robot


I am a big fan of using DVD cases as robot platforms. This robot is was also assembled in less than an hour. I already had the platform ready from a previous robot so all I had to do is to insert the GOduino III and the sensor into a short breadboard. 

I used Pololu's micro metal gear motor and the HC-SR04 ultrasonic distance sensor.  There are many code examples for the HC-SR04 sensor and an Arduino library that works well. 

This is the code used in the video demo:

// GOduino III object avoidance using the HC-SR04 distance sensor
// This code is in the public domain

#include <Goduino.h>
#include <Ultrasonic.h>

// Select pins for  HC-SR04 distance sensor
#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define DISRANCE_TO_OBJECT 1300 // This was the optimum value for object detection using trial & error

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);  //   HC-SR04 distance sensor object
Goduino myrobot;  //  GUduino III motor object
int mspeed=50;  // set initial speed value of both motors


void setup()
{
  Serial.begin(9600);
  myrobot.motorSpeed(50, 50);  // set initial speed for both motors
}


void loop()
{
  Serial.println("-------------");

  float cmMsec = 0, inMsec =0;
  long microsec = 0, avgDis =0;

  for (int i=0;  i < 10; i++) {  // average 10 readings from the distance sensor
    microsec = ultrasonic.timing();
    Serial.print("microsec: ");
    Serial.println(microsec); 
    avgDis += microsec;
  }
  avgDis = avgDis / 10;
  Serial.print("avgDis: ");
  Serial.println(avgDis);  

  if (avgDis > DISRANCE_TO_OBJECT){    // if no object withing range
    myrobot.motorForward(1);  // move forward
    myrobot.motorForward(2);
  }
  else   // but if object detected within range
  {
    myrobot.motorStop(1); // stop
    myrobot.motorStop(2); // stop
    delay(500);   // wait

    myrobot.motorBack(1);  // back
    myrobot.motorBack(2);  // back
    delay(1000); // wait

    myrobot.motorBack(1);  // turn
    myrobot.motorForward(2);
    delay(500); // wait

    myrobot.motorForward(1);  // Then move forward
    myrobot.motorForward(2);   
  }

}


Step 6: Thanks


CREDITS
  • Special thanks to my good friend Jafar Quttaineh for his invaluable suggestions.
  • The GOduino III form factor was based on Adafruit's Boarduino which is an Arduino clone that can be plugged into a breadboard. Using this form-factor for the GOduino III makes prototyping robots for newbies much simpler. (adafruit.com)
  • And of course I have to mention the good folks at Pin 13 Protospace who are very helpful with comments and suggestions.