In this project I use a home brewed laser sensor coupled with a Ping))) as sort of a poor man’s LIDAR. But I couple it with a Pololu beacon so the robot can find its way home. The red laser and the beacon’s IR didn’t interfere which was something I was worried about.
Hello.
That is a very nice project. Thank you for sharing it with us. Keep us the good work!
By the way, did you use any other Pololu parts in your project, and do you have your build documented somewhere?
-Derrill
Thanks. The beacon was the only Pololu part for this build, but I have two other projects which I could write up. One uses wixels, the other a Baby Orangutan and the Pololu mini-IMU.
For technical details. I used an existing design for the laser sensor described here: forums.parallax.com/showthread.p … r-Bulk-Buy So that’s not my own design, but it was a scratch build.
The Boe-bot, gripper, and Ping))) sensor are all stock Parallax parts. The only other secret sauce was the coding which took about five hours. I used a BS2 and PBasic which is probably considered obsolete, but it’s a no drama programming environment and I find it easy to knock out projects. Here’s the code if anyone wants it.
' ==============================================================================
'
' File...... FetchTargetAndFindBeacon.BS2
' Purpose... Find a target using the Ping))) and laser, then returns to
' the beacon
' Authors... Martin Heermance.
' E-mail.... mheermance@gmail.com
' Started... 2014 September 6th
' Updated... 2014 September 7th
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' ==============================================================================
' ------------------------------------------------------------------------------
' Program Description
' ------------------------------------------------------------------------------
' A program to locate a target using a laser, then return to the Pololu beacon
' ------------------------------------------------------------------------------
' Revision History
' ------------------------------------------------------------------------------
' 2014-09-XX Initial creation and ongoing development.
' ------------------------------------------------------------------------------
' I/O Definitions
' ------------------------------------------------------------------------------
Laser PIN 0 ' Laser input
BLeft PIN 6 ' Beacon to left indicator
BBack PIN 7 ' Beacon in back indicator
BRght PIN 8 ' Beacon to right indicator
BFront PIN 9 ' Beacon in front indicator
Buzzer PIN 10 ' pin for output sound
RMotor PIN 12 ' Pin for right servo
LMotor PIN 13 ' Pin for left servo
Gripper PIN 14 ' Pin for gripper servo
Ping PIN 15 ' Pin for PING))) Sensor
' ------------------------------------------------------------------------------
' Constants
' ------------------------------------------------------------------------------
'--------[Calibration Constants, must be adjusted for your specific robot]------
GripperOpened CON 500 ' PULSOUT pulse width to open gripper servo
GripperClosed CON 960 ' PULSOUT pulse width to close gripper servo
' These values need tweaking for each robot's servos.
SpeedF75L CON 840 ' Fast forward left
SpeedF50L CON 808 ' Med forward left
SpeedF25L CON 775 ' Slow forward left
Speed000L CON 750 ' stop left
SpeedR25L CON 710 ' slow reverse left
SpeedR50L CON 690 ' med reverse left
SpeedR75L CON 650 ' fast reverse left
SpeedF75R CON 650 ' Fast forward right
SpeedF50R CON 690 ' med forward right
SpeedF25R CON 720 ' slow forward right
Speed000R CON 750 ' Stop right
SpeedR25R CON 775 ' slow reverse right
SpeedR50R CON 810 ' med reverse right
SpeedR75R CON 850 ' Fast reverse right
'---------[Other Global Constants]----------------------------------------------
NULL CON 750 ' Pulse width for 1.5ms stop pulse.
Trigger CON 5 ' trigger pulse = 10 uS
Scale CON $200 ' raw x 2.00 = uS
RawToIn CON 889 ' 1 / 73.746 (with **)
IsHigh CON 1 ' for PULSOUT
IsLow CON 0
Success CON 0 ' Constant for zero success
ErrorBeaconLost CON -1 ' Constant for lost on move
ErrorTooClose CON -2 ' Constant for farther than max
RIGHT CON 0 ' Subscripts into arrays.
LEFT CON 1
FRONT CON 2
BACK CON 3
COM_SPEED CON 84 ' 9600 baudnon-inverted.
' ------------------------------------------------------------------------------
' Variables - for simplicty I use exactly the same variables in all modules.
' ------------------------------------------------------------------------------
' General purpose volatile variables which are modified by subroutines or tasks
ACC VAR Word
' Loop index variables and for argument passing.
X VAR Word
Y VAR Word
Z VAR Word
' DirReads is a nibble array
DirReads VAR Nib(4)
' State variables which are modified to reflect changes of robot state.
RSpeed VAR Word ' Holds current r motor pulse
LSpeed VAR Word ' Holds current l motor pulse
GripState VAR Word ' Holds current gripper pulse
' ------------------------------------------------------------------------------
' Initialization
' ------------------------------------------------------------------------------
' ------------------------------------------------------------------------------
' Program Code
' ------------------------------------------------------------------------------
' Pause at start of program to let user set down robot.
FREQOUT Buzzer, 1000, 2500
GripState = GripperOpened
GOSUB Halt ' stop robot
GOSUB FindTarget
GOSUB Fetch
GripState = GripperClosed
GOSUB Halt
GOSUB FindBeacon
END
' ------------------------------------------------------------------------------
' Subroutines
' ------------------------------------------------------------------------------
' slowly rotate until the laser target finds target
FindTarget:
RSpeed = SpeedF25R
LSpeed = SpeedR25L
DO
' Each iteration refresh the servos
GOSUB PulseServos
IF (Laser = IsLow) THEN
GOSUB Halt
FREQOUT Buzzer, 1000, 2500
RETURN
ENDIF
LOOP
' moves towards the target and stops when it is in range
Fetch:
Y = 0
DO
Y = Y + 1
' Every so often check that we still see the target
' If not then turn TO face it
IF (Y > 35 AND Laser = IsHigh) THEN
GOSUB FindTarget
Y = 0
ENDIF
' slowly move forward to the desired distance to the target
RSpeed = SpeedF50R
LSpeed = SpeedF50L
GOSUB PulseServos
' Exit if we're close to the target
GOSUB PingDistance
IF (X < 3) THEN
GOSUB Halt
RETURN
ENDIF
LOOP
' PingDistance - reads the distance to the target.
' Inputs:
' Outputs:
' X - distance in inches.
PingDistance:
Ping = IsLow ' make trigger 0-1-0
PULSOUT Ping, Trigger ' activate sensor
PULSIN Ping, IsHigh, X ' measure echo pulse
X = X */ Scale ' convert to uS
X = X / 2 ' remove return trip
X = X ** RawToIn ' convert to inches
RETURN
' Turn the robot on its axis by the amount in signed byte Arg at speed Veloc.
' Inputs:
' Arg - number of brads to turn. > 0 turns left; Arg < 0 turns right.
' Veloc - peak speed where 0 is stop and 15 is fast.
' Outputs:
' X - 0 success, -1 beacon lost, -2 closer than min
Turn:
RETURN
' Stop moving
Halt:
RSpeed = Speed000R
LSpeed = Speed000L
' Called to refresh the servos.
PulseServos:
PULSOUT RMotor, RSpeed
PULSOUT LMotor, LSpeed
PULSOUT Gripper, GripState
PAUSE 20
RETURN
' ReadBeacon - scans the beacon pins, removes spurious noise and returns value.
' Inputs:
' none
' Outputs:
' ACC - most common direction
' Z - number of occurances
ReadBeacon:
FOR Y = RIGHT TO BACK
DirReads(Y) = 0
NEXT
FOR Y = 0 TO 6
IF BFront = IsLow THEN
DirReads(Front) = DirReads(Front) + 1
ENDIF
IF BRght = IsLow THEN
DirReads(Right) = DirReads(Right) + 1
ENDIF
IF BLeft = IsLow THEN
DirReads(Left) = DirReads(Left) + 1
ENDIF
IF BBack = IsLow THEN
DirReads(BACK) = DirReads(BACK) + 1
ENDIF
NEXT
' Have a bias towards LEFT to initiate beacon search
ACC = LEFT
Z = DirReads(LEFT)
FOR Y = RIGHT TO BACK
' If this direction is more common than current max, make it max
IF DirReads(Y) > Z THEN
ACC = Y
Z = DirReads(Y)
ENDIF
NEXT
RETURN
' Find the beacon, althouh at the present no exit condition is specified
FindBeacon:
' slowly rotate until the beacon locater spots its target
RSpeed = SpeedF25R
LSpeed = SpeedR25L
DO
' Each iteration refresh the servos
GOSUB PulseServos
GOSUB ReadBeacon
IF (ACC = Back) THEN
' quickly do a 180
RSpeed = SpeedR75R
LSpeed = SpeedF75L
Y = 40
ELSEIF (ACC = Right) THEN
' rotate until the beacon is front
RSpeed = SpeedR50R
LSpeed = SpeedF50L
Y = 20
ELSEIF (ACC = Left) THEN
' rotate until the beacon is in front
RSpeed = SpeedF50R
LSpeed = SpeedR50L
Y = 20
ELSEIF (ACC = Front) THEN
' Move towards beacon
RSpeed = SpeedF75R
LSpeed = SpeedF75L
Y = 1
ENDIF
DO UNTIL Y = 0
GOSUB PulseServos
Y = Y - 1
LOOP
LOOP
I just remembered that I’m using the Pololu QTR-8RC reflectance sensor array on this robot as well. Here’s a video of an earlier version of this project using the line sensor to remove the target from a ring.
Thank you adding for that video. I see you posted about another one of your robots on our forum. We love seeing how our products are used in these great robots!
-Derrill