Difference between revisions of "Line Following Sensor"
From RoboWiki
(New page: This page describes the connection of the i2c line following sensor to the Boe-Bot robot. * [http://www.roboticsconnection.com/p-67-line-following-sensor.aspx I2C Line Following Sensor] ...) |
|||
Line 19: | Line 19: | ||
The demonstration software: | The demonstration software: | ||
− | < | + | <source lang="basic"> |
− | </ | + | ' {$STAMP BS2} |
+ | ' {$PBASIC 2.5} | ||
+ | ' | ||
+ | ' ========================================================================= | ||
+ | |||
+ | |||
+ | ' -----[ Program Description ]--------------------------------------------- | ||
+ | ' | ||
+ | ' Generic I2C code for non-BS2p/BS2pe modules. | ||
+ | |||
+ | |||
+ | ' -----[ Revision History ]------------------------------------------------ | ||
+ | ' | ||
+ | ' 18 AUG 2004 - Updated and made routines completely generic | ||
+ | |||
+ | |||
+ | ' -----[ I/O Definitions ]------------------------------------------------- | ||
+ | |||
+ | SDA PIN 0 ' I2C serial data line | ||
+ | SCL PIN 1 ' I2C serial clock line | ||
+ | |||
+ | |||
+ | ' -----[ Constants ]------------------------------------------------------- | ||
+ | |||
+ | Ack CON 0 ' acknowledge bit | ||
+ | Nak CON 1 ' no ack bit | ||
+ | |||
+ | |||
+ | ' -----[ Variables ]------------------------------------------------------- | ||
+ | |||
+ | slvAddr VAR Byte ' slave address | ||
+ | devNum VAR Nib ' device number (0 - 7) | ||
+ | addrLen VAR Nib ' 0, 1 or 2 | ||
+ | devAddr VAR Word ' address in device | ||
+ | |||
+ | i2cData VAR Byte ' data to/from device | ||
+ | i2cWork VAR Byte ' work byte for TX routine | ||
+ | i2cAck VAR Bit ' Ack bit from device | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ' -----[ EEPROM Data ]----------------------------------------------------- | ||
+ | |||
+ | |||
+ | ' -----[ Initialization ]-------------------------------------------------- | ||
+ | |||
+ | Reset: | ||
+ | |||
+ | devNum = 0 ' device address %000 | ||
+ | slvAddr = $50 | ||
+ | addrLen = 0 ' no internal addresses | ||
+ | |||
+ | DEBUG CLS, | ||
+ | "Line Sensor Demo" ' setup output screen | ||
+ | |||
+ | |||
+ | ' -----[ Program Code ]---------------------------------------------------- | ||
+ | |||
+ | DO | ||
+ | GOSUB Read_Byte ' read switches | ||
+ | |||
+ | ' report | ||
+ | DEBUG CRSRXY, 0, 2, "In.... ", BIN5 i2cData | ||
+ | PAUSE 100 | ||
+ | LOOP | ||
+ | END | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ' -----[ Subroutines ]----------------------------------------------------- | ||
+ | |||
+ | |||
+ | |||
+ | ' -----[ High Level I2C Subroutines]--------------------------------------- | ||
+ | |||
+ | ' Random location write | ||
+ | ' -- pass device slave address in "slvAddr" | ||
+ | ' -- pass address bytes (0, 1 or 2) in "addrLen" | ||
+ | ' -- register address passed in "devAddr" | ||
+ | ' -- data byte to be written is passed in "i2cData" | ||
+ | |||
+ | Write_Byte: | ||
+ | GOSUB I2C_Start ' send Start | ||
+ | i2cWork = slvAddr & %11111110 ' send slave ID | ||
+ | GOSUB I2C_TX_Byte | ||
+ | IF (i2cAck = Nak) THEN Write_Byte ' wait until not busy | ||
+ | IF (addrLen > 0) THEN | ||
+ | IF (addrLen = 2) THEN | ||
+ | i2cWork = devAddr.BYTE1 ' send word address (1) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | ENDIF | ||
+ | i2cWork = devAddr.BYTE0 ' send word address (0) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | ENDIF | ||
+ | i2cWork = i2cData ' send data | ||
+ | GOSUB I2C_TX_Byte | ||
+ | GOSUB I2C_Stop | ||
+ | RETURN | ||
+ | |||
+ | |||
+ | ' Random location read | ||
+ | ' -- pass device slave address in "slvAddr" | ||
+ | ' -- pass address bytes (0, 1 or 2) in "addrLen" | ||
+ | ' -- register address passed in "devAddr" | ||
+ | ' -- data byte read is returned in "i2cData" | ||
+ | |||
+ | Read_Byte: | ||
+ | GOSUB I2C_Start ' send Start | ||
+ | IF (addrLen > 0) THEN | ||
+ | i2cWork = slvAddr & %11111110 ' send slave ID (write) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | IF (i2cAck = Nak) THEN Read_Byte ' wait until not busy | ||
+ | IF (addrLen = 2) THEN | ||
+ | i2cWork = devAddr.BYTE1 ' send word address (1) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | ENDIF | ||
+ | i2cWork = devAddr.BYTE0 ' send word address (0) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | GOSUB I2C_Start | ||
+ | ENDIF | ||
+ | i2cWork = slvAddr | %00000001 ' send slave ID (read) | ||
+ | GOSUB I2C_TX_Byte | ||
+ | GOSUB I2C_RX_Byte_Nak | ||
+ | GOSUB I2C_Stop | ||
+ | i2cData = i2cWork | ||
+ | RETURN | ||
+ | |||
+ | |||
+ | ' -----[ Low Level I2C Subroutines]---------------------------------------- | ||
+ | |||
+ | ' *** Start Sequence *** | ||
+ | |||
+ | I2C_Start: ' I2C start bit sequence | ||
+ | INPUT SDA | ||
+ | INPUT SCL | ||
+ | LOW SDA | ||
+ | |||
+ | Clock_Hold: | ||
+ | DO : LOOP UNTIL (SCL = 1) ' wait for clock release | ||
+ | RETURN | ||
+ | |||
+ | |||
+ | ' *** Transmit Byte *** | ||
+ | |||
+ | I2C_TX_Byte: | ||
+ | SHIFTOUT SDA, SCL, MSBFIRST, [i2cWork\8] ' send byte to device | ||
+ | SHIFTIN SDA, SCL, MSBPRE, [i2cAck\1] ' get acknowledge bit | ||
+ | RETURN | ||
+ | |||
+ | |||
+ | ' *** Receive Byte *** | ||
+ | |||
+ | I2C_RX_Byte_Nak: | ||
+ | i2cAck = Nak ' no Ack = high | ||
+ | GOTO I2C_RX | ||
+ | |||
+ | I2C_RX_Byte: | ||
+ | i2cAck = Ack ' Ack = low | ||
+ | |||
+ | I2C_RX: | ||
+ | SHIFTIN SDA, SCL, MSBPRE, [i2cWork\8] ' get byte from device | ||
+ | SHIFTOUT SDA, SCL, LSBFIRST, [i2cAck\1] ' send ack or nak | ||
+ | RETURN | ||
+ | |||
+ | |||
+ | ' *** Stop Sequence *** | ||
+ | |||
+ | I2C_Stop: ' I2C stop bit sequence | ||
+ | LOW SDA | ||
+ | INPUT SCL | ||
+ | INPUT SDA | ||
+ | RETURN | ||
+ | </source> | ||
Results: | Results: | ||
[[Image:LineSensorScreenshot.png]] | [[Image:LineSensorScreenshot.png]] |
Revision as of 20:49, 4 August 2009
This page describes the connection of the i2c line following sensor to the Boe-Bot robot.
- Jon Williams: I2C Fun For Everyone
- Jon Williams: [http://www.parallax.com/dl/docs/cols/nv/vol5/col/nv115.pdf I2C Again – And the Case for Continuos
Improvement]
The connection diagram:
The photo of the connection:
The demonstration software:
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
'
' Generic I2C code for non-BS2p/BS2pe modules.
' -----[ Revision History ]------------------------------------------------
'
' 18 AUG 2004 - Updated and made routines completely generic
' -----[ I/O Definitions ]-------------------------------------------------
SDA PIN 0 ' I2C serial data line
SCL PIN 1 ' I2C serial clock line
' -----[ Constants ]-------------------------------------------------------
Ack CON 0 ' acknowledge bit
Nak CON 1 ' no ack bit
' -----[ Variables ]-------------------------------------------------------
slvAddr VAR Byte ' slave address
devNum VAR Nib ' device number (0 - 7)
addrLen VAR Nib ' 0, 1 or 2
devAddr VAR Word ' address in device
i2cData VAR Byte ' data to/from device
i2cWork VAR Byte ' work byte for TX routine
i2cAck VAR Bit ' Ack bit from device
' -----[ EEPROM Data ]-----------------------------------------------------
' -----[ Initialization ]--------------------------------------------------
Reset:
devNum = 0 ' device address %000
slvAddr = $50
addrLen = 0 ' no internal addresses
DEBUG CLS,
"Line Sensor Demo" ' setup output screen
' -----[ Program Code ]----------------------------------------------------
DO
GOSUB Read_Byte ' read switches
' report
DEBUG CRSRXY, 0, 2, "In.... ", BIN5 i2cData
PAUSE 100
LOOP
END
' -----[ Subroutines ]-----------------------------------------------------
' -----[ High Level I2C Subroutines]---------------------------------------
' Random location write
' -- pass device slave address in "slvAddr"
' -- pass address bytes (0, 1 or 2) in "addrLen"
' -- register address passed in "devAddr"
' -- data byte to be written is passed in "i2cData"
Write_Byte:
GOSUB I2C_Start ' send Start
i2cWork = slvAddr & %11111110 ' send slave ID
GOSUB I2C_TX_Byte
IF (i2cAck = Nak) THEN Write_Byte ' wait until not busy
IF (addrLen > 0) THEN
IF (addrLen = 2) THEN
i2cWork = devAddr.BYTE1 ' send word address (1)
GOSUB I2C_TX_Byte
ENDIF
i2cWork = devAddr.BYTE0 ' send word address (0)
GOSUB I2C_TX_Byte
ENDIF
i2cWork = i2cData ' send data
GOSUB I2C_TX_Byte
GOSUB I2C_Stop
RETURN
' Random location read
' -- pass device slave address in "slvAddr"
' -- pass address bytes (0, 1 or 2) in "addrLen"
' -- register address passed in "devAddr"
' -- data byte read is returned in "i2cData"
Read_Byte:
GOSUB I2C_Start ' send Start
IF (addrLen > 0) THEN
i2cWork = slvAddr & %11111110 ' send slave ID (write)
GOSUB I2C_TX_Byte
IF (i2cAck = Nak) THEN Read_Byte ' wait until not busy
IF (addrLen = 2) THEN
i2cWork = devAddr.BYTE1 ' send word address (1)
GOSUB I2C_TX_Byte
ENDIF
i2cWork = devAddr.BYTE0 ' send word address (0)
GOSUB I2C_TX_Byte
GOSUB I2C_Start
ENDIF
i2cWork = slvAddr | %00000001 ' send slave ID (read)
GOSUB I2C_TX_Byte
GOSUB I2C_RX_Byte_Nak
GOSUB I2C_Stop
i2cData = i2cWork
RETURN
' -----[ Low Level I2C Subroutines]----------------------------------------
' *** Start Sequence ***
I2C_Start: ' I2C start bit sequence
INPUT SDA
INPUT SCL
LOW SDA
Clock_Hold:
DO : LOOP UNTIL (SCL = 1) ' wait for clock release
RETURN
' *** Transmit Byte ***
I2C_TX_Byte:
SHIFTOUT SDA, SCL, MSBFIRST, [i2cWork\8] ' send byte to device
SHIFTIN SDA, SCL, MSBPRE, [i2cAck\1] ' get acknowledge bit
RETURN
' *** Receive Byte ***
I2C_RX_Byte_Nak:
i2cAck = Nak ' no Ack = high
GOTO I2C_RX
I2C_RX_Byte:
i2cAck = Ack ' Ack = low
I2C_RX:
SHIFTIN SDA, SCL, MSBPRE, [i2cWork\8] ' get byte from device
SHIFTOUT SDA, SCL, LSBFIRST, [i2cAck\1] ' send ack or nak
RETURN
' *** Stop Sequence ***
I2C_Stop: ' I2C stop bit sequence
LOW SDA
INPUT SCL
INPUT SDA
RETURN