Antika - my little robot "a BoeBot-like robot"
hi,
this is my 1st robot, a very basic obstacle detection/avoidance robot.
UPDATE 12/06/2013:
- added IR control code. with the help of this excellent pdf file that explains IR and how to deal with it and also how to decode RCs: http://www.mediafire.com/download/jjmnaizseuk4dlq/Infrared_Remote_Control_Signal_Analysis_-_By_Karl_Williams.PDF
Background:
i started learning electronics two years ago, all i wanted to do is to be able to control things like a LED or so through the PC, so i spent sometime learning the basics of electricity and what components do i need to achieve my goal, i wrote down every thing i need (programmer, microcontroller, leds, resistors,.....etc), and decided to code using basic language (having experience with pc programming languages like Delphi, VBA, C# made it a lot easier to learn), so got every thing and started to setup the circuit to just blink a LED, i remember that day very well, i spent the whole day trying not to blink a LED but to even switch it on, finally i was able to blink the LED i was sooo happy :D
then i learned how to send/receive data to/from a microcontroller through rs232, i programmed a little program using Delphi to monitor the serial port and been able finally to achieve my main goal, i was able to switch a LED on and off by a PC software :D.
the electronics field owned me i couldn't stop at this point, i started learning infrared and learned how to control every thing using a remote control, i stopped a while then decided to come back with a new project, a robot :D
The Robot project:
i started this project about a year ago, i wanted to make a basic obstacle detection/avoidance robot, spent sometime reading about sensors and servo motors basics, and finally decided to chose an ultrasonic sensor for my project, but as soon as i started, i started to face some problems
The problems:
1- the body of the robot: i managed to solve this using some plastic junk and hot glue (as you will see in the photos, but do not laugh :D)
2- the batteries: as i said before i started this project about one year ago, at that time, after preparing every thing (the circuit, the body, the code,...etc) i powered the robot to watch my final result, and i was shocked o_O, it was acting very strangely, because i was a beginner (and still), i used one 9 volts battery to power this robot, tried two with no luck, tried to separate the power supply of the servos but still no luck, so i got upset and delayed the whole thing untill two weeks ago i accidently came up with a topic in this site titled "selecting a proper battery for your robot" which made me realize how noob i am :D, so i decided to go back and finish what i started one year ago and got it working finally i am very happy with the final result :D
3- the servos was laggy, i discovered that removing the capacitors "that some people recommended using it for the servos" solved my problem, and the robot movement is very smooth now, not sure though when/why exactly do i have to attach those caps to the servos if it is working without them?!
Components:
- 1x PIC 16F628A microcontroller
- 1x ping ultrasonic sensor
- 1x standard servo motor for the sensor
- 2x continuous servo motors
- 3x 330 ohm resistors for the signal wire of the servos
- 1x breadboard
- 1x buzzer
- 2x LEDs "red + blue"
- 2x 330 ohm resistors for the LEDs
- 1x 20MHz crystal
- 2x 33 pF capacitors for the crystal
- 1x 9 volts battery for the microcontroller and the sensor
- 1x 7805 voltage regulator for the 9 volts battery
- 1x 10 uF + 1x 0.1 uF capacitors for the voltage regulator
- 4x 1.2 volt NiMH rechargeable AA batteries "2450 mAh" for the servos
- some wires
- hot glue + plastic junk for the body :D
- and most importantly a "good brain" :D
The code "ProtonBasic Compiler":
as you will see, i didn't "actually couldn't" use any timers or interrupts, i may implement them in the future, i managed to code without using them, i spent sometime to organise the code, and currently the robot works perfectly without them :D
'****************************************************************
'* Name : Antika Robot
'* Author : Khalid Fawzy
'* Date : 01-Jan-13
'* Version : 1.0
'* Notes : This is my first attempt to make a robot, i hope
'* that someone may find this code useful.
'****************************************************************
Device = 16F628A
Xtal = 20
All_Digital = True 'To be able to use PORTA with IR Sensor
'-------[I/O Definitions]-----------------------------------------------
Dim Ping As PORTB.3 'the ping sensor
Dim PingServo As PORTB.2 'servo motor for the ping sensor
Dim Servo1 As PORTB.0
Dim Servo2 As PORTB.1
Dim StatusLed As PORTB.4
Dim RedLed As PORTB.5
Dim BeepPort As PORTB.6
Dim IR_Port As PORTA.0
Dim IRpulse_length[10] As Word
Dim IR_ON As Word
Dim hp As Word
Dim lp As Word
Dim xx As Byte
Dim Trigger As Byte '10 uS trigger pluse
Dim Scale As Byte 'raw x 2.00 =uS (2.00 if using 20MHz And 10.00 if 4MHz"
'RawToIn var WORD '1/73.746 (with**)
Dim RawToCm As Word '1/29.034(with**)
Trigger = 1
Scale = 2
'RawToIn = 889
RawToCm = 2257
Dim rawDist As Word 'raw measurement
'inches var word
Dim cm As Word
Dim i As Byte
Dim cmx As Byte
Dim CurrentPath As Byte
Dim BestPath As Byte
'-------[Program Code]---------------------------------------------------
DelayMS 100 'initialization
High StatusLed
High RedLed
DelayMS 300
Low StatusLed
Low RedLed
DelayMS 300
High StatusLed
High RedLed
DelayMS 300
Low StatusLed
Low RedLed
DelayMS 300
High StatusLed
High RedLed
DelayMS 300
Low StatusLed
Low RedLed
DelayMS 300
High StatusLed
cm = 0
cmx = 0
CurrentPath = 0
BestPath = 0
GoSub pingservo_90 'To Make The Ping Looks Forward
Low PORTB.7 'If Low: Disable IR and vise versa
RCIn PORTB.7,1,IR_ON
Start:
If IR_ON <> 0 Then
GoTo IR_Control
Else
GoTo Main
EndIf
'########################################################
'########################################################
IR_Control:
PulsIn IR_Port,0,IRpulse_length[0]
If IRpulse_length[0] < 4000 Then
GoTo Start
EndIf
For xx = 1 To 9 'skip first 10 pulses
PulsIn IR_Port,1,IRpulse_length[0]
Next xx
For xx = 1 To 8 '8 command pulses
PulsIn IR_Port,1,IRpulse_length[xx]
Next xx
PulsIn IR_Port,1,IRpulse_length[0] 'skip last pulse
';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CONVERT_BITS:
lp = 0
hp = 1
For xx = 1 To 8
If IRpulse_length[xx] > 500 Then
lp = lp + hp
EndIf
hp = hp*2
Next xx
LoopUntilNoIR: 'Repeat movement untill no IR
RCIn IR_Port,1,IRpulse_length[0]
Select IRpulse_length[0]
Case <> 0
If lp = 19 Then GoSub Left
If lp = 20 Then GoSub Right
If lp = 23 Then GoSub Forward
If lp = 24 Then GoSub Backward
If lp = 1 Then GoSub Right45
If lp = 2 Then GoSub Right90
If lp = 3 Then GoSub Left45
If lp = 4 Then GoSub Left90
GoTo LoopUntilNoIR
Case = 0
GoSub StopServos
EndSelect
GoTo Start
'#########################################################
'#########################################################
Main:
GoSub Forward_Scan
GoTo Main
Detection:
Low PingServo 'i should stop the ping servo here, but i do not know the right pulse to stop this servo
GoSub StopServos
High BeepPort
DelayMS 50
Low BeepPort
DelayMS 50
High BeepPort
DelayMS 50
Low BeepPort
DelayMS 50
High BeepPort
DelayMS 50
Low BeepPort
GoSub BackwardX
GoSub pingservo_90 'positioning the ping servo in Forward Position to start scanning
DelayMS 5
GoSub pingservo_0 'scanning most right for obstacles
DelayMS 5
GoSub pingservo_45 'scanning 45 degrees to the right for obstacles
DelayMS 5
GoSub pingservo_135 'scanning 45 degrees To the left for obstacles
DelayMS 5
GoSub pingservo_180 'scanning most left for obstacles
DelayMS 5
Select BestPath
Case 1 '0
GoSub Right90
Case 2 '45
GoSub Right45
Case 3 '135
GoSub Left45
Case 4' 180
GoSub Left90
EndSelect
cm = 0
cmx = 0
CurrentPath = 0
BestPath = 0
GoSub pingservo_90
GoTo Start
'------[Subroutines]-----------------------------------------------------
'note that: i tuned the number of loops and delays to suit my needs
Get_Sonar:
Low Ping 'make trigger 0-1-0
PulsOut Ping, Trigger 'activate sensor
PulsIn Ping, 1, rawDist 'measure echo pulse
rawDist = rawDist * Scale 'convert to uS
rawDist = rawDist / 2 'remover return trip
'inches = rawDist ** RawToIn 'convert to inches
cm = rawDist ** RawToCm 'convert to sentimeters
Return
pingservo_0: 'turn to most right
CurrentPath = 1
For i = 1 To 24 '24 long enough to reach destination "425"
Low PingServo
Servo PingServo, 425 '425 = farthest right...got it with trial & error :D
DelayMS 15 'the delay controls servo speed
Next i
GoSub Get_Sonar
If cm > cmx Then
cmx = cm
BestPath = CurrentPath
EndIf
Return
pingservo_45: 'turn 45 degrees to right
CurrentPath = 2
For i = 1 To 18
Low PingServo
Servo PingServo, 850
DelayMS 15
Next i
GoSub Get_Sonar
If cm > cmx Then
cmx = cm
BestPath = CurrentPath
EndIf
Return
pingservo_90: 'turn to center position
For i = 1 To 24
Low PingServo
Servo PingServo, 1275
DelayMS 15
Next i
Return
pingservo_135: 'turn 45 degrees to left
CurrentPath = 3
For i = 1 To 24
Low PingServo
Servo PingServo, 1700
DelayMS 15
Next i
GoSub Get_Sonar
If cm > cmx Then
cmx = cm
BestPath = CurrentPath
EndIf
Return
pingservo_180: 'turn to most left
CurrentPath = 4
For i = 1 To 18
Low PingServo
Servo PingServo, 2125
DelayMS 15
Next i
GoSub Get_Sonar
If cm > cmx Then
cmx = cm
BestPath = CurrentPath
EndIf
Return
'moving forward and scanning for obstacles at the same time
Forward_Scan:
For i = 1 To 10
Low PingServo
Low Servo1
Low Servo2
Servo PingServo, 850
Servo Servo1, 1000 ' Send a 1 ms pulse
Servo Servo2, 2000 ' Send a 2 ms pulse
DelayMS 17
Next i
GoSub Get_Sonar
If cm <= 18 Then
GoSub Turn_Right
EndIf
For i = 1 To 10
Low PingServo
Low Servo1
Low Servo2
Servo PingServo, 1275
Servo Servo1, 1000
Servo Servo2, 2000
DelayMS 15
Next i
GoSub Get_Sonar
If cm <= 20 Then
GoTo Detection
EndIf
For i = 1 To 10
Low PingServo
Low Servo1
Low Servo2
Servo PingServo, 1700
Servo Servo1, 1000
Servo Servo2, 2000
DelayMS 17
Next i
GoSub Get_Sonar
If cm <= 18 Then
GoSub Turn_Left
EndIf
For i = 1 To 10
Low PingServo
Low Servo1
Low Servo2
Servo PingServo, 1275
Servo Servo1, 1000
Servo Servo2, 2000
DelayMS 15
Next i
GoSub Get_Sonar
If cm <= 20 Then
GoTo Detection
EndIf
Return
Turn_Right: 'turn right until no obstacle detected
High RedLed
Low Servo1
Low Servo2
Servo Servo1, 1000
Servo Servo2, 1000
DelayMS 20
GoSub Get_Sonar
DelayMS 10
If cm <= 18 Then
GoTo Turn_Right
EndIf
GoSub StopServos
Low RedLed
Return
Turn_Left: 'turn left until no obstacle detected
High RedLed
Low Servo1
Low Servo2
Servo Servo1, 2000
Servo Servo2, 2000
DelayMS 20
GoSub Get_Sonar
DelayMS 10
If cm <= 18 Then
GoTo Turn_Left
EndIf
GoSub StopServos
Low RedLed
Return
StopServos:
Low Servo1
Low Servo2
Servo Servo1, 1500 ' 1.5 ms
Servo Servo2, 1500 ' 1.5 ms
DelayMS 20
Return
BackwardX: 'move backward when detecting obstacles
High RedLed
For i = 1 To 10
Low Servo1
Low Servo2
Servo Servo1, 2000 ' Send a 2 ms pulse 'Servo command is independent in OSC speed, always 1us
Servo Servo2, 1000 ' Send a 1 ms pulse
DelayMS 30
Next i
GoSub StopServos
Low RedLed
Return
Left45: 'turn the robot To 45 degrees to left
High RedLed
For i = 1 To 9
Low Servo1
Low Servo2
Servo Servo1, 1000
Servo Servo2, 1000
DelayMS 20
Next i
GoSub StopServos
Low RedLed
Return
Left90: 'turn the robot To most left
High RedLed
For i = 1 To 20
Low Servo1
Low Servo2
Servo Servo1, 1000
Servo Servo2, 1000
DelayMS 20
Next i
GoSub StopServos
Low RedLed
Return
Right45: 'turn the robot To 45 degrees to right
High RedLed
For i = 1 To 9
Low Servo1
Low Servo2
Servo Servo1, 2000
Servo Servo2, 2000
DelayMS 20
Next i
GoSub StopServos
Low RedLed
Return
Right90: 'turn the robot to most right
High RedLed
For i = 1 To 20
Low Servo1
Low Servo2
Servo Servo1, 2000
Servo Servo2, 2000
DelayMS 20
Next i
GoSub StopServos
Low RedLed
Return
Final notes:
- this is my 1st attempt, i know the body should be better, i may upgrade it in the future.
- i used the QL-2006 programmer and ProtonBasic compiler to program the microcontroller, my total code is 1138 words from a possible 2048 words for this PIC chip "55.57%".
- electronics & programming are my hobby, i do not work in those fields :)
and now the comedy show :D
a very basic obstacle detection/avoidance robot
- Actuators / output devices: Servos
- Control method: autonomous
- CPU: PIC 16f628a
- Power source: 1x 9 volts for the PIC + the sensor, 4x 1.2 volt NiMH rechargeable AA batteries for the servos
- Programming language: ProtonBasic
- Sensors / input devices: Ping Ultrasonic Sensor
- Target environment: indoor