Shop OBEX P1 Docs P2 Docs Learn Events
BS2 I2C BlinkM read data from slave problem (protocol?) — Parallax Forums

BS2 I2C BlinkM read data from slave problem (protocol?)

MiccimMiccim Posts: 14
edited 2010-05-14 07:01 in BASIC Stamp
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?

' {$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

  • JDJD Posts: 570
    edited 2010-05-13 22:43
    Miccim,

    ·· Can you get it to respond with the 0x00 (broadcast) address?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Respectfully,


    Joshua Donelson
    www.parallax.com
  • MiccimMiccim Posts: 14
    edited 2010-05-14 07:01
    Yes, it does respond to the default address (0x09) and to the general broadcast address (0x00).
    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
Sign In or Register to comment.