Microcontroller Code. Get_IR.bs2. This program receives basic IR pulses. The
program pulses out a certain frequency from the infrared LED, and the receiver ...
Microcontroller Code Get_IR.bs2 This program receives basic IR pulses. The program pulses out a certain frequency from the infrared LED, and the receiver returns a 0 if an infrared pulse is detected (bouncing off an obstacle in front of the robot). ' {$STAMP BS2} ' {$PBASIC 2.5} irDetectFront frequency
VAR VAR
Bit Word
DO frequency=36500 GOSUB getIR
‘emits a 36500 Hz infrared wave
IF (irDetectFront=0) THEN DEBUG “object seen” ELSE DEBUG “no object” ENDIF LOOP getIR: FREQOUT 8,1,frequency irDetectFront=IN9 RETURN
Compass_FindNorth.bs2 This program uses the compass to figure out the microcontroller’s orientation relative to north, and move the microcontroller so it faces north. ' {$STAMP BS2} ' {$PBASIC 2.5} irDetectLeft irDetectRight pulseCount
VAR VAR VAR
Bit Bit Byte
' detects the left ir sensor ' detects the right ir sensor ' counter for turn loops
DinDout Clk En
PIN PIN PIN
6 5 4
' P6 transmit to/from Din/Dout ' P5 sends pulses to HM55B Clk ' P4 controls HM55B's /EN(ABLE)
Reset Measure Report Ready
CON CON CON CON
%0000 %1000 %1100 %1100
' ' ' '
Reset command for HM55B Start measurement command Get status/axis command 11 -> Done, 00 -> no errors
NegMask CON %1111100000000000 ' For 11-bit negative to 16-bits i x y status angle
VAR VAR VAR VAR VAR
FREQOUT 4, 2000, 3000
Bit Word Word Nib Word
' ' ' '
x-axis data y-axis data Status flags Store angle measurement
' Signal program start/reset.
DO FREQOUT 8, 1, 37000 irDetectLeft = IN9 FREQOUT 2, 1, 37000 irDetectRight = IN0 DO WHILE (irDetectRight = 1) OR (irDetectLeft = 1) PULSOUT 13, 650 PULSOUT 12, 850 ‘go forward FREQOUT 8, 1, 37000 irDetectLeft = IN9 FREQOUT 2, 1, 37000 irDetectRight = IN0 ‘check for obstacles LOOP IF irDetectRight = 0 THEN FOR pulseCount = 0 TO 100 PULSOUT 13, 650 PULSOUT 12, 850 NEXT FOR pulseCount = 0 TO 140 PULSOUT 13, 850 PULSOUT 12, 850 NEXT GOSUB Compass_Get_Axes angle = x ATN -y angle = angle */ 360
' Get x, and y values ' Convert x and y to bin radian
IF (angle < 100) OR (angle > 80) THEN drift=0 ENDIF LOOP '
FOR pulseCount = 0 TO 122
get_IR: FREQOUT 8, 1, 37000 ' Store IR detection values in irDetectLeft = IN9 ' bit variables.
FREQOUT 2, 1, 37000 irDetectRight = IN0 RETURN Compass_Get_Axes: ' Compass module subroutine HIGH En: LOW En ' Send reset command to HM55B SHIFTOUT DinDout,clk,MSBFIRST,[Reset\4] HIGH En: LOW En ' HM55B start command SHIFTOUT DinDout,clk,MSBFIRST,[Measure\4] status = 0 ' Clear previous status flags DO HIGH En: LOW En SHIFTOUT DinDout,clk,MSBFIRST,[Report\4] SHIFTIN DinDout,clk,MSBPOST,[Status\4] ' Get Status LOOP UNTIL status = Ready SHIFTIN
DinDout,clk,MSBPOST,[x\11,y\11]
HIGH En IF (y.BIT10 = 1) THEN y = y | NegMask IF (x.BIT10 = 1) THEN x = x | NegMask RETURN
Get_IR_Distance.bs2 This program finds out how far away an obstacle is using information from only the infrared receiver. The program essentially starts with an extremely short‐range frequency, then increases the range of the IR frequency until it sees an object. It then relays this information to the microcontroller. This method of finding distance is expanded in Triangulator.bs2. ' {$STAMP BS2} ' {$PBASIC 2.5} irDetectFront frequency
VAR VAR
Bit Word
DO frequency=43000 GOSUB getIR DO WHILE (irDetectFront=1) AND (frequency>37000) frequency=frequency-100 GOSUB getIR LOOP IF (frequency>=42800) THEN DEBUG "shortest" ELSEIF (frequency>=42000) THEN DEBUG "shorter" ELSEIF (frequency>=39000) THEN
DEBUG "medium" ELSEIF (frequency>=37500) THEN DEBUG "long" ELSEIF (frequency>=37000) THEN DEBUG "longer" ELSE DEBUG "longest" ENDIF DEBUG CR DEBUG ? frequency LOOP getIR: FREQOUT 8, 1, frequency irDetectFront = IN9 RETURN We used this program to chart the range of distances that we could find using infrared, and compiled those distances into the graph below. 44000 Frequency required to detect object (Hz)
43000 42000 41000 40000 39000 38000 37000 36000 0
10
20
30
40
50
60
Object distance from infrared source (cm)
According to the graph, the infrared sensors can only accurately find the distance of an object located between 20 to 38 centimeters away from the robot, making infrared only useful for medium‐range distances.
Triangulator.bs2 This code did not function as we wanted it to, but below we have included the basic math principles that we applied to developing the code. User The basic principle behind triangulation is to create a triangle of which all sides are of a known length. Then, the law of cosines can be applied. a b
d
Using this formula, all the angle measures of the triangle can be calculated, and a vector can be synthesized from the information. Source 1 c Source 2 TransmitterCode.bs2 The transmitter code works to send its compass value to the receiver, which is the Boe‐ Bot. The code sends it continuously. '{$STAMP BS2} '{$PBASIC 2.5} 'Variables DinDout PIN 6 transceives to/from Din/Dout Clk PIN 5 pulses to HM55B's Clk En PIN 4 HM55B's /EN(ABLE)
' P6 ' P5 sends ' P4 controls
Reset CON %0000 ' Reset command for HM55B Measure CON %1000 ' Start measurement command Report CON %1100 ' Get status/axis values command Ready CON %1100 ' 11 -> Done, 00 -> no errors NegMask CON %1111100000000000 ' For 11-bit negative to 16-bits i VAR Bit x VAR Word ' x-axis data y VAR Word ' y-axis data status VAR Nib ' Status flags angle VAR Word '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DO GOSUB Compass_Get_Axes values
' Get x, and y
angle = x ATN -y and y to brads angle = angle */ 360
' Convert x
PULSOUT 1, 1200 'Sync pulse for the receiver SEROUT 1, 16468, [ "!", 0, 0, angle.HIGHBYTE, angle.LOWBYTE ] DEBUG CR ' PAUSE 100 LOOP Compass_Get_Axes: ' Compass module subroutine HIGH En: LOW En SHIFTOUT DinDout,clk,MSBFIRST,[Reset\4] HIGH En: measurement SHIFTOUT status = DO
LOW En command DinDout,clk,MSBFIRST,[Measure\4] 0
' HM55B start
' Status flag checking loop
HIGH En: LOW En SHIFTOUT DinDout,clk,MSBFIRST,[Report\4] SHIFTIN DinDout,clk,MSBPOST,[Status\4] ' Get Status LOOP UNTIL status = Ready ' Exit loop when status is ready SHIFTIN DinDout,clk,MSBPOST,[x\11,y\11] axis values HIGH En IF (y.BIT10 = 1) THEN y = y | NegMask IF (x.BIT10 = 1) THEN x = x | NegMask RETURN
' Get x & y
ReceiverCode.bs2 This program simply prints out the compass readings sent by the transmitter. '{$STAMP BS2} '{$PBASIC 2.5} x VAR Byte y VAR Word z VAR Byte DO SERIN 1, 16468, [WAIT("!"), z, x, y.HIGHBYTE, y.LOWBYTE] DEBUG ? y LOOP
Avoider.bs2 This is the final avoider program we made. It runs forward until it sees an obstacle in its path and then decide whther to move around the abstacle from the right or left. It knows when it reaches the end of the obstacle when one of its side IR sensors stops detecting the obstacle. ' {$STAMP BS2} ' Stamp directive. ' {$PBASIC 2.5} ' PBASIC directive. DEBUG "Program Running!" ' -----[ Variables ]-------------------------------------irDetectLeft VAR Bit irDetectRight VAR Bit pulseCount VAR Byte ' -----[ Initialization ]---------------------------------
FREQOUT 4, 2000, 3000 ' Signal program start/reset. ' -----[ Main Routine ]----------------------------------DO FREQOUT 8, 1, 37000 ' Store IR detection values in irDetectLeft = IN9 ' bit variables. FREQOUT 2, 1, 37000 irDetectRight = IN0 IF (irDetectLeft = 0) AND (irDetectRight = 0) THEN GOSUB Back_Up ' Both IR pairs detect obstacle GOSUB Turn_Left ' Back up & U-turn (left twice) GOSUB Turn_Left ELSEIF (irDetectLeft = 0) THEN ' Left IR pair detects
GOSUB Back_Up ' Back up & turn right GOSUB Turn_Right ELSEIF (irDetectRight = 0) THEN ' Right IR pair detects GOSUB Back_Up ' Back up & turn left GOSUB Turn_Left ELSE ' Both IR pairs 1, no detects GOSUB Forward_Pulse ' Apply a forward pulse ENDIF ' and check again LOOP ' -----[ Subroutine ]------------------------------------Forward_Pulse: ' Send a single forward pulse. PULSOUT 13,650 PULSOUT 12,850 PAUSE 20 RETURN Turn_Left: ' Left turn, about 90-degrees. FOR pulseCount = 0 TO 20 PULSOUT 13, 650 PULSOUT 12, 650 PAUSE 20 NEXT RETURN Turn_Right: FOR pulseCount = 0 TO 20 ' Right turn, about 90-degrees. PULSOUT 13, 850 PULSOUT 12, 850 PAUSE 20 NEXT RETURN Back_Up: ' Back up. FOR pulseCount = 0 TO 40 PULSOUT 13, 850 PULSOUT 12, 650 PAUSE 20 NEXT RETURN
ADC_Code.bs2 This program was designed to help us understand the relationship between the output votage from the receiver pin called the RSSI. The voltage is directly related to the distance between the transmitter and receiver. The RSSI voltage was read through an ADC (analog to digital converter). ' {$STAMP BS2} ' {$PBASIC 2.5} x VAR Byte y VAR Word z VAR Byte adcBits VAR Byte v VAR Byte r VAR Byte v2 VAR Byte v3 VAR Word CS PIN 9 CLK PIN 8 DataOutput PIN 7 DEBUG CLS 'Start display. DO SERIN 1, 16468, [WAIT("!"), z, x, y.HIGHBYTE, y.LOWBYTE] GOSUB ADC_Data GOSUB Calc_Volts v3 = adcBits * 100 / 12 LOOP ADC_Data: LOW CLK LOW CS PULSOUT CLK, 210 SHIFTIN DataOutput,CLK,MSBPOST,[adcBits\8] HIGH CS RETURN Calc_Volts: v = adcBits * 5 / 255 r = (adcBits * 5) // 255 v2 = (r * 100) / 255 RETURN
Display: DEBUG HOME DEBUG "8-bit binary value: ", DEC2 adcBits DEBUG CR, CR, "DVM Reading: " '. new line DEBUG DEC1 v, ".", DEC2 v2, " Volts" '. new line RETURN