Bot4Julia, a Start Here CD robot, Arduino clone
| Attachment | Size |
|---|---|
| Bot4Julia.zip | 5.59 KB |
This is a Start Here robot style I built for my daughter Julia, so she can have something to play with, because she keeps bugging me wanting to play with my MiniEric robot. (I allow her to remote control it some times, but she still grabs his arms and breaks the servo gears.)
Here is Bot4Julia. To build one, the recipe is simple. Get 2 CDs, drill holes for standoffs, attach 2 geared motors (I used GM17 just because I had them) with double side foam tape, a battery box, then mount the second CD on the standoffs, feed the wires through the second CD center hole, add some more standoffs for the PCB, plug the wires in the proper sockets, use some more double side tape to attach a small servo and a SeeedStudio US sensor (works like a Ping sensor, costs only $15) on the servo horn, plug them on the board and start programming. I used an old Ro-Bot-X board I designed years ago. This board had a MAX232 serial converter on board, but my laptop does not have a serial port anymore, so instead of making an adapter, I just unplugged the ATmega168 and plugged it in the Roboduino board for programming. This is OK for one time, but I had to repeat this operation about 20 times to be able to tweak out parts of the code. This board will soon be replaced by a uBotino board that will allow easy programming has everything needed for this robot. I did not intended this robot to be a tutorial, so I did not take pictures at the time of construction. Here are the pictures after the robot was built:



The code is simple, but I had to overcome some hardware problems. First, the motors do not have encoders, and one is spinning faster than the other. So I had to find a good PWM value to keep them running at the same speed. Then I had to find out the turning time so the robot turns 90 degrees good enough. So I made a Square function, that drives Forward for 2 seconds, turns Right 90 degrees and so on 4 times to make a square. Once this was done, I wrote some simple avoiding routine that needs improving, but for now it's good enough to have fun with the robot. I will add remote control and let the robot avoid objects when necessary. This way my daughter can tel the robot where to go, but there will still be some autonomous routines in there. She also wants me to add arms to the robot, I'll have to work on something...
Oh, I had to use the SoftwareServo library, because the motors use the Timer1 for PWM (uBotino avoids this using Timer0) so they were fighting for the same Timer.
Here is the code so far:
// Bot4Julia, a simple Start Here style robot, made with 2 CDs,
// 2 GM17 motors and wheels, one servo, one SeeedStudio US sensor,
// one battery box, one Ro-Bot-X board (will be replaced by a uBotino)
//
// Ro-Bot-X board pinout:
//
// Ext RBX Funct Arduino ATmega168 Arduino Funct RBX External
// +-----\/----+
// Reset 1| PC6 PC5 |28 D19 A5 SCL
// Rx D0 2| PD0 PC4 |27 D18 A4 SDA
// Tx D1 3| PD1 PC3 |26 D17 A3
// Int0 D2 4| PD2 PC2 |25 D16 A2
// Int1 D3 5| PD3 PC1 |24 D15 A1 Ping
// S1 D4 6| PD4 PC0 |23 D14 A0
// 7| VCC GND |22
// 8| GND AREF |21
// Xtal 9| PB6 AVCC |20
// Xtal 10| PB7 PB5 |19 D13 SCK
// S2 OC0B D5 11| PD5 PB4 |18 D12 MISO M1B
// OC0A D6 12| PD6 PB3 |17 D11 OC2A MOSI
// Pan D7 13| PD7 PB2 |16 D10 OC1B M2A
// M2B (S3) D8 14| PB0 PB1 |15 D 9 OC1A (S4) M1A
// +-----------+
//
#include <SoftwareServo.h>
#include <Speaker.h>
//Inputs/outputs
//#define Encoder_1_ChA 2 // digital pin 2 // Right Encoder
//#define Encoder_1_ChB 6 // digital pin 6
//#define Encoder_2_ChA 3 // digital pin 3 // Left Encoder
//#define Encoder_2_ChB 14 // digital pin 14
#define Motor_1_PWM 9 // digital pin 9 // Right Motor
#define Motor_1_Dir 12 // digital pin 12
#define Motor_2_PWM 10 // digital pin 10 // Left Motor
#define Motor_2_Dir 8 // digital pin 8
//#define SleftPin 1 // analog pin 1
//#define SrightPin 2 // analog pin 2
#define PingPin 15 // digital pin 15
#define PanPin 4 // digital pin 4
#define SpeakerPin 13
#define center 90
//Variables
byte dir=0;
byte speed1=225;
byte speed2=255;
int turn90=500;
int turn45=250;
int stopTime=200;
int USdistance=0;
int treshold=20; //20cm min distance
SoftwareServo Pan;
Speaker speaker = Speaker(SpeakerPin);
//-----------------------------------------------------------------------------
void setup() {
// set motor pins as output and LOW so the motors are breaked
pinMode(Motor_1_PWM, OUTPUT);
pinMode(Motor_1_Dir, OUTPUT);
pinMode(Motor_2_PWM, OUTPUT);
pinMode(Motor_2_Dir, OUTPUT);
Stop();
pinMode(PingPin, OUTPUT);
digitalWrite(PingPin, LOW);
Pan.attach(PanPin);
Pan.write(center); //90
StepDelay();
pinMode(SpeakerPin, OUTPUT);
speaker.Beep();
//Serial.begin (9600);
//Serial.println("start");
Forward();
}
void loop(){
Drive();
//square();
}
void square(){
Forward();
delay(2000);
Stop();
delay(stopTime);
Right();
delay(turn90);
Stop();
delay(stopTime);
Forward();
delay(2000);
Stop();
delay(stopTime);
Right();
delay(turn90);
Stop();
delay(stopTime);
Forward();
delay(2000);
Stop();
delay(stopTime);
Right();
delay(turn90);
Stop();
delay(stopTime);
Forward();
delay(2000);
Stop();
delay(stopTime);
Right();
delay(turn90);
Stop();
delay(stopTime);
}
void Drive(){
USdistance=Read_Ping_Sensor();
if (USdistance<5){
Stop();
speaker.Beep();
StepDelay();
TurnAround();
}
if (USdistance<treshold){
Stop();
speaker.Beep();
StepDelay();
Avoid();
Forward();
}
delay(50);
}
void TurnAround(){
Reverse();
Pan.write(center);
StepDelay();
Stop();
Left();
delay(turn90);
delay(turn90);
Stop();
StepDelay();
Forward();
}
void Avoid(){
int prev=0;
for (byte i=0; i<5; i++){
Pan.write(i*45);
StepDelay();
StepDelay();
USdistance=Read_Ping_Sensor();
if (USdistance>prev){
dir=i;
prev=USdistance;
}
}
Pan.write(center);
StepDelay();
switch (dir){
case 0:
Right();
delay(turn90);
Stop();
speaker.Beep();
StepDelay();
break;
case 1:
Right();
delay(turn90); //turn45
Stop();
speaker.Beep();
StepDelay();
break;
case 2:
Forward();
break;
case 3:
Left();
delay(turn90); //turn45
Stop();
speaker.Beep();
StepDelay();
break;
case 4:
Left();
delay(turn90);
Stop();
speaker.Beep();
StepDelay();
break;
}
delay(500);
}
// Read Sensors
int Read_Ping_Sensor(){
int cm=0;
//trigger the sensor
unsigned long value = 0;
pinMode(PingPin, OUTPUT);
digitalWrite(PingPin, LOW);
delayMicroseconds(2);
digitalWrite(PingPin, HIGH);
delayMicroseconds(10);
digitalWrite(PingPin, LOW);
//receive the echo
pinMode(PingPin, INPUT);
digitalWrite(PingPin, HIGH); // turn on pull up resistor
value = pulseIn(PingPin, HIGH);
value=value/58;
cm=int(value);
return cm;
}
void StepDelay() {
for (byte t=0; t<10; t++){
SoftwareServo::refresh();
delay(20);
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Forward(){
digitalWrite(Motor_1_Dir, LOW); // forward
digitalWrite(Motor_2_Dir, LOW); // forward
analogWrite(Motor_1_PWM, speed1); //
analogWrite(Motor_2_PWM, speed2); //
}
void Reverse(){
digitalWrite(Motor_1_Dir, HIGH); // reverse
digitalWrite(Motor_2_Dir, HIGH); // reverse
analogWrite(Motor_1_PWM, 255-speed1); //
analogWrite(Motor_2_PWM, 255-speed2); //
}
void Right(){
digitalWrite(Motor_1_Dir, HIGH); // reverse
digitalWrite(Motor_2_Dir, LOW); // forward
analogWrite(Motor_1_PWM, 255-speed1); //
analogWrite(Motor_2_PWM, speed2); //
}
void Left(){
digitalWrite(Motor_1_Dir, LOW); // forward
digitalWrite(Motor_2_Dir, HIGH); // reverse
analogWrite(Motor_1_PWM, speed1); //
analogWrite(Motor_2_PWM, 255-speed2); //
}
void Stop()
{
digitalWrite(Motor_1_PWM, LOW);
digitalWrite(Motor_1_Dir, LOW);
digitalWrite(Motor_2_PWM, LOW);
digitalWrite(Motor_2_Dir, LOW);
}
I made this robot in about 4 hours, it was fun and rewarding to see my daughter so happy playing with it. You should all try that!



@ Tue, 2012-04-17 15:25
can i ask for the design of
can i ask for the design of the remote..i think i love to do this stuff.. its wonderful though ..
pls..post the design of the remote .. tnx
@ Wed, 2012-04-18 02:36
I used a universal TV remote
I used a universal TV remote programed for a Sony VCR. To receive the remote IR signal I used a TSOP4838 sensor. This sensor has 3 pins, Output, Gnd, Vcc. Tie the Gnd and Vcc pins to Arduino pins Gnd and 5V and the Output pin to any I/O pin. I can post the code if you want.
@ Thu, 2012-04-19 12:18
tnx for a quick reply i hope
tnx for a quick reply i hope you post it..once again tnx
@ Thu, 2012-04-19 13:46
Here it is:
@ Sun, 2012-04-22 03:59
thanks for sharing and
thanks for sharing and posting :)
@ Sun, 2012-03-04 01:24
Great bot, but wasnt you
Great bot, but wasnt you annoyed at everyone using ultrasonic sensors when you can use IR leds ? And yet you use ultrasonic
@ Sun, 2012-03-04 04:23
Well, that doesn't mean I
Well, that doesn't mean I can't use ultrasonics or IR range sensors! The problem with the IR leds and IR remote sensor is that they don't come mounted on a nice board you can fit on a servo or directly on the robot. You have to make that yourself. And this was a robot I made quickly from what I had available at the time. But if you want to take a look a a robot that I made that uses the IR leds and sensor, take a look at this one.
@ Thu, 2011-09-01 18:16
Is that stock gearing on the
Is that stock gearing on the GM17s? It looks faster than I expected. I am looking to pick some up.
@ Fri, 2011-09-02 01:19
I have no ideea. I played
I have no ideea. I played with the Didel gears but I don't remember which are curently in the motors. I remember being a bit dissapointed by the torque with the fastest setup, so I might have changed them to a lower speed.
@ Fri, 2011-09-02 08:32
Yeah I didn't think you
Yeah I didn't think you would get much torque on the fastest but the middle setting looked like it might be good. Thanks anyway!