GOduino: The Breadboard-friendly Robot Controller
UPDATES
INTRODUCTIONThe 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.
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. BACKGROUNDThis 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) http://www.instructables.com/id/GOduino-II-Arduino-L293D-Variable-Speed-Motor-/ 2) GOduino I (breadboard) http://www.instructables.com/id/GOduino-The-Arduino-Uno-Motor-Driver-clone/ OVERVIEWThe 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
PROGRAMMING
POWER
PARTS
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.
https://github.com/techbitar/goduino EAGLE LAYOUTThe GOduino III is Open Source hardware and software package so anyone can download and reuse the design using files from Github in Eagle 6.x formats.
https://github.com/techbitar/goduino Controlling 2 DC brushed motorsThe 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:
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); } Controlling 2 servosThere'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 } } Building a breadboard robotThis 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); } Building An Object Avoidance RobotI 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); } } Credits
Enjoy, Hazim Bitar (techbitar at gmail dot com) |
Created: Aug 26, 2012
|