BS2 I2C BlinkM read data from slave problem (protocol?)
I have purchased a fancy BlinkM thingm.com/products/blinkm (it is a small RGB LED with integrated controller, AVR) and now I'm trying it out. It's connected to my BoeBOT with BS2, so I need software I2C. So far so good!
It's working fine when I send info to the BlinkM but I'm having problems reading data from the little nifty device.
After reading http://forums.parallax.com/showthread.php?p=466264 it is still not clear to me.
To read data from the slave (BlinkM) first I have to send the slave address than send "a" (which is the BlinkM command for Get BlinkM address, default is 0x09) than to receive 1 data byte.
I assume that the exact protocol is my problem, please see the BlinkMCmd_read procedure below, I always receive a 0 instead of 9?
Can anyone point me in the right direction?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
BoeBOT with BS2 and PINK module (Netburner) | Latest: BlinkM
It's working fine when I send info to the BlinkM but I'm having problems reading data from the little nifty device.
After reading http://forums.parallax.com/showthread.php?p=466264 it is still not clear to me.
To read data from the slave (BlinkM) first I have to send the slave address than send "a" (which is the BlinkM command for Get BlinkM address, default is 0x09) than to receive 1 data byte.
I assume that the exact protocol is my problem, please see the BlinkMCmd_read procedure below, I always receive a 0 instead of 9?
Can anyone point me in the right direction?
' {$STAMP BS2}
' {$PBASIC 2.5}
' {$PORT COM1}
'
'---- I/O definitions ---------
'What pins BlinkM is connected to, with 4.7k (or 10k) pullup resistors to +5V (=Vdd)
SDA CON 0 ' I2C Data line (d) on P0
SCL CON 1 ' I2C Clock line (c) on P1
SDA_DIR VAR DIR0 ' must match SDA above, 0 is IN, 1 is OUT
'---- constants ----------
BlinkM_addr CON 9 ' or set to zero to address all BlinkMs on your I2C bus
' standard I2C address of BlinkM = 0x09
' BlinkM listens to general call at address = 0x00
Ack CON 0 ' acknowledge = 0
Nack CON 1 ' no acknowledge = 1
'---- variables ----------
I2C_ack VAR Bit ' used by I2CSend, acknowledge from the I2C bus
I2C_data VAR Byte ' used by I2CSend, Data to/from the I2C bus
slave_addr_read VAR Byte ' slave device address for reading
slave_addr_write VAR Byte ' slave device address for writing
BlinkM_cmd VAR Byte ' used by BlinkMSend & BlinkMSend3
'---- program ----------
Main:
slave_addr_write = BlinkM_addr << 1 ' shift left because address is upper 7 bits,
' direction (READ = 1 OR WRITE = 0) is LSB
slave_addr_read = slave_addr_write | %00000001
BlinkM_cmd = "o" ' stop playing boot script, e.g. "{'o'}"
GOSUB BlinkMCmd
GOSUB BlinkMCmd_read
DEBUG "BlinkM address: ", DEC I2C_data, CR
END
'^^^^^^^^^^^^^^ BLINKM SUBROUTINES ^^^^^^^^^^^^^^
BlinkMCmd:
GOSUB I2C_Start ' start procedure
I2C_data = slave_addr_write
' check for clock_hold
GOSUB I2C_TX_byte ' put address on I2C bus
I2C_data = BlinkM_cmd
' check for clock_hold
GOSUB I2C_TX_byte ' send command to device
GOSUB I2C_Stop ' stop procedure
RETURN
BlinkMCmd_read:
GOSUB I2C_Start ' start procedure
I2C_data = slave_addr_write
GOSUB I2C_TX_byte ' send address
BlinkM_cmd = "a" ' BlinkM command for reading BlinkM address
I2C_data = BlinkM_cmd
GOSUB I2C_TX_byte ' send command
GOSUB I2C_Start ' repeated start procedure
I2C_data = slave_addr_read
GOSUB I2C_TX_byte ' put address on I2C bus
DEBUG "read-address.", CR
GOSUB I2C_RX_byte_Nack ' read byte from device
GOSUB I2C_Stop ' stop procedure
RETURN
'^^^^^^^^^^^^^^ BLINKM SUBROUTINES ^^^^^^^^^^^^^^
'---- I2C low level subroutines ----------
I2C_start: ' I2C start procedure
SDA_DIR = %1 ' make SDA an output
HIGH SDA
HIGH SCL
LOW SDA
RETURN
I2C_stop: ' I2C stop procedure
LOW SDA
HIGH SCL
HIGH SDA
RETURN
I2C_TX_byte: ' transmit 1 byte to device
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]I2C_data\8] ' data = 8 bits long
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]I2C_ack\1] ' get acknowledge bit, MSBFIRST, pre-mode
IF I2C_ack =0 THEN DEBUG "Ack - write", CR
IF I2C_ack =1 THEN DEBUG "No Ack - write", CR
RETURN
I2C_RX_byte_Nack:
I2C_ack=Nack
GOTO I2C_RX
I2C_RX_byte:
I2C_ack = Ack
I2C_RX:
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]I2C_data\8] ' receiving 8 bits of data from device
SHIFTOUT SDA, SCL, LSBFIRST, [noparse][[/noparse]I2C_ack\1] ' send acknowledge (Ack or No-ack) to device
RETURN
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
BoeBOT with BS2 and PINK module (Netburner) | Latest: BlinkM

Comments
·· Can you get it to respond with the 0x00 (broadcast) address?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Respectfully,
Joshua Donelson
www.parallax.com
I have tried it out with some of the pre-defined light scripts of the BlinkM.
As long as I send data (I2C) al works like it should.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
BoeBOT with BS2 and PINK module (Netburner) | Latest: BlinkM