' =========================================================================
'
' File...... tsl1401_follower.bs2
' Purpose... Line follower program for the BOE-Bot, using the TSL1401-DB.'
' Author.... Phil Pilgrim, Bueno systems, Inc.
' E-mail....
' Started... 18 August 2007
' Updated... 28 November 2009
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' This program uses the TSL1401-DB linescan imager daughterboard in
' conjunction with a BASIC Stamp 2 on a BOE-Bot to guide the BOE-Bot along
' dark line made with black tape on a light-colored floor.
' -----[ I/O Definitions ]-------------------------------------------------
ao PIN 0 'TSL1401R's analog output (threhsolded by Stamp).
si PIN 1 'TSL1401R's SI pin.
clk PIN 2 'TSL1401R's CLK pin.
led PIN 3 'LED strobe input.
servopal PIN 12 'ServoPAL control pin.
' -----[ Constants ]-------------------------------------------------------
DARK CON 0 'Value assignd to "which" for dark pixels.
LIGHT CON 1 'Value assigned to "which" for light pixels.
' -----[ Variables ]-------------------------------------------------------
pdata VAR Word(8) 'Pixel data, as acquired LSB first from sensor.
pixels VAR pdata.BIT0 '128-bit pixel array mapped onto pdata.
exp VAR Word 'Exposure (integration) time in 2uSec units.
avg VAR Word 'avg for averaging.
i VAR Byte 'General-purpose index.
cnt VAR Byte 'Result of pixel-count routine.
' -----[ Program Code ]----------------------------------------------------
which CON DARK 'Set for dark line on light floor.
'Change to LIGHT, otherwise.
line CON 22 >> 1 'Line width for 1/2-inch tape.
'Adjust proportionally for other sizes.
INPUT servopal 'Wait for ServoPAL to power up.
DO: LOOP UNTIL servopal
LOW servopal 'Reset the ServoPAL.
PAUSE 100
HIGH servopal
exp = 15 'Set initial exposure (strobe) time.
DO 'Begin the scan-and-process loop.
GOSUB GetPix 'Obtain a pixel scan.
GOSUB AvgPix 'Find the dark pixel count and
'average position.
DEBUG HOME, DEC avg, " ", DEC cnt, CLREOL 'For testing...
IF (cnt < line - 2) THEN 'If count is too low,
exp = exp - 1 + (which << 1) 'Adjust exposure according to line color.
ELSEIF (cnt > line + 2) THEN 'If too high,
exp = exp + 1 - (which << 1) ' adjust the other way.
ENDIF
exp = exp MIN 1 MAX 20 'Make sure exposure time is reasonable.
IF (cnt >= line >> 1 AND cnt <= line << 1) THEN 'If count isn't WAY off, use position.
IF (avg <= 64) THEN 'If line is to the left,
PULSOUT servopal, 718 ' steer left proportional to the error.
PULSOUT servopal, 750 + (avg >> 1)
ELSE 'Else, if line is to the right,
PULSOUT servopal, 750 - (127 - avg >> 1) ' steer right proportional to the error.
PULSOUT servopal, 782
ENDIF
ELSE 'If pixel count is WAY off,
PULSOUT servopal, 2000 ' just stop until we get the
PULSOUT servopal, 2000 ' exposure time right.
ENDIF
LOOP
' -----[ Subroutines ]-----------------------------------------------------
' -----[ GetPix ]----------------------------------------------------------
' Acquire 128 thresholded pixels from sensor chip.
' exp is the exposure time in microseconds.
GetPix:
SHIFTOUT si, clk, 0, [1\1] 'Clock out the SI pulse.
PWM clk, 128, 1 'Rapidly send 150 or so CLKs.
PWM led, 1, exp 'PWM LED low for exposure time.
SHIFTOUT si, clk, 0, [1\1] 'Clock out another SI pulse.
'Read 8 words (128 bits) of data.
SHIFTIN ao, clk, LSBPRE, [pdata(0)\16, pdata(1)\16, pdata(2)\16, pdata(3)\16]
SHIFTIN ao, clk, LSBPRE, [pdata(4)\16, pdata(5)\16, pdata(6)\16, pdata(7)\16]
RETURN
' -----[AvgPix]------------------------------------------------------------
' Find average location of pixels of the type indicated by which (0 = dark;
' 1 = light). For the sake of speed, consider only the even pixels. The
' position will still cover the full range, but the count will be half of
' what it would be if if every pixel were considered.
AvgPix:
cnt = 0
avg = 0
FOR i = 0 TO 127 STEP 2
IF (pixels(i) = which) THEN
avg = avg + i
cnt = cnt + 1
ENDIF
NEXT
IF (cnt) THEN avg = avg / cnt
RETURN