Shop OBEX P1 Docs P2 Docs Learn Events
I2C control of A/D devices (or controlling other I2C devices) — Parallax Forums

I2C control of A/D devices (or controlling other I2C devices)

Jim S.Jim S. Posts: 13
edited 2005-04-12 00:15 in BASIC Stamp
I need some help on better understanding Basic Stamp’s I2C control.· Specifically, I am planning to control a Philips PCF8591 8-bit A/D device.
(http://www.semiconductors.philips.com/acrobat_download/datasheets/PCF8591_6.pdf )
·
I noticed that Basic Stamp I2C protocol always sends the second byte as a WRITE (device “Address&#8221[noparse];)[/noparse], when I do a I2C READ command (“I2CIN&#8221[noparse];)[/noparse].
·
Trying to READ the PCF8591 (and presumably some other I2C devices) causes the slave device to start sending its data to the master starting with the second byte.· (ref: page 9 of above pdf link)
Does this conflict with the Basic Stamp sending a WRITE on the second byte (while the slave is sending a WRITE)?
·
Does someone have successful experience in controlling the PCF8591, or possibly other I2C A/D’s such as Microchip MCP3021 or Maxim MAX1362.
·
Any help would be appreciated.
·
Jim S.

Comments

  • JonbJonb Posts: 146
    edited 2005-04-11 11:53
    Which Basic stamp are you using?
    And please post your code if you can.

    I've implemented IIC using Parallax code·with an EEPROM and a SRF10, and the routines were pretty much the same.

    ' Byte to be written is passed in i2cData
    ' -- address passed in eeAddr
    

    Write_Byte:
    GOSUB I2C_Start ' send Start
    i2cWork = Wr24515 ' send write command
    GOSUB I2C_TX_Byte
    IF (i2cAck = NAK) THEN Write_Byte ' wait until not busy
    i2cWork = eeAddr / 256 ' send word address (1)
    GOSUB I2C_TX_Byte
    i2cWork = eeAddr // 256 ' send word address (0)
    GOSUB I2C_TX_Byte
    i2cWork = i2cData ' send data
    GOSUB I2C_TX_Byte
    GOSUB I2C_Stop
    RETURN 
    

    ' Byte read is returned in i2cData 
    ' -- address passed in eeAddr
    

    Read_Byte: 
    GOSUB I2C_Start ' send Start 
    i2cWork = Wr24515 ' send write command 
    GOSUB I2C_TX_Byte 
    IF (i2cAck = NAK) THEN Write_Byte ' wait until not busy 
    i2cWork = eeAddr / 256 ' send word address (1) 
    GOSUB I2C_TX_Byte 
    i2cWork = eeAddr // 256 ' send word address (0) 
    GOSUB I2C_TX_Byte 
    GOSUB I2C_Start 
    i2cWork = Rd24515 ' send read command 
    GOSUB I2C_TX_Byte 
    GOSUB I2C_RX_Byte_Nak 
    GOSUB I2C_Stop 
    i2cData = i2cWork 
    RETURN 
    

    ' ------------------------------------------------------------------------------ 
    ' Low Level I2C Subroutines 
    ' ------------------------------------------------------------------------------
    

    ' --- Start --- 
    I2C_Start: ' I2C start bit sequence 
    INPUT i2cSDA 
    INPUT SCL 
    LOW i2cSDA ' SDA -> low while SCL high 
    Clock_Hold: 
    IF (INS.LOWBIT(SCL) = 0) THEN Clock_Hold ' device ready? 
    RETURN 
    
    ' --- Transmit --- 
    I2C_TX_Byte: 
    SHIFTOUT i2cSDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' send byte to device 
    SHIFTIN i2cSDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' get acknowledge bit 
    RETURN 
    
    ' --- Receive --- 
    I2C_RX_Byte_Nak: 
    i2cAck = NAK ' no ACK = high 
    GOTO I2C_RX 
    I2C_RX_Byte: 
    i2cAck = ACK ' ACK = low 
    I2C_RX: 
    SHIFTIN i2cSDA, SCL, MSBPRE, [noparse][[/noparse]i2cWork\8] ' get byte from device 
    SHIFTOUT i2cSDA, SCL, LSBFIRST, [noparse][[/noparse]i2cAck\1] ' send ack or nak 
    RETURN 
    
    ' --- Stop --- 
    I2C_Stop: ' I2C stop bit sequence 
    LOW i2cSDA 
    INPUT SCL 
    INPUT i2cSDA ' SDA --> high while SCL high 
    RETURN
    


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Jonb) : 4/11/2005 12:57:33 PM GMT
  • Jim S.Jim S. Posts: 13
    edited 2005-04-11 12:25
    Jon,

    I have not coded yet.· I noticed your attached code "bit-bangs" the I2C function.· I plan to use the BS2p that has the I2CIN and I2COUT commands (I want to do it the "lazy" way).· If for some reason I am not able to use the I2CIN/I2COUT commnads, then I'll resort to bit-banging SDA and SCL signals and your sample code will be useful.

    Still hoping for someone to shed light on my original question.

    Jim S.
  • JonbJonb Posts: 146
    edited 2005-04-11 13:32
    I use this code on a BS2sx which does not have I2CIN/OUT.

    The code was taken here: http://www.parallax.com/dl/docs/books/sw/exp/sw32.pdf


    I'm sure someone from Parallax will answer your question, but in the meantime there is alot of info by doing a search for "I2CIN".

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Jonb) : 4/11/2005 1:37:34 PM GMT
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-11 13:52
    You can use I2COUT/I2CIN -- I just ran the attached demo (I updated first) on a BS2px.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA


    Post Edited (Jon Williams) : 4/11/2005 1:59:09 PM GMT
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2005-04-11 15:22
    Hi Jon,

    Does this mean that the BS2px is now officially released? And a new version of the IDE to support it?

    Jim, in the I2CIN command on the address bytes after the device ID are both optional. The program Jon posted illustrates this, where it reads the "dummy" byte right after sending the device ID. I think I recall that some of the first BS2p chips, version 1.0, did automatically want to send an address byte, so you might find some literature out there still that says that. Look at the current help file and you will see that they are both optional.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-11 15:25
    Oops... will be shortly.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • Jim S.Jim S. Posts: 13
    edited 2005-04-11 16:55
    Jon and Tracy,

    Thanks for clarifications.· You have given me the confidence so that I can proceed with my pcb design.
    Still little unclear·why "dummy" byte would not cause a conflict.· Once I am ready to test, I'm certain I'll figure it out.

    Jim S.

    ·
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-11 17:09
    As Tracy and I frequently point out, you should always read the component documentation -- even if you've got demo code in your hands.· When you read the documentation and understand how conversion results are sent back, the reason for the dummy variable (which holds an old result that we don't want) will be clear... I hope.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA


    Post Edited (Jon Williams) : 4/11/2005 5:14:06 PM GMT
  • Jim S.Jim S. Posts: 13
    edited 2005-04-11 18:03
    Hi Jon,

    Perhaps I am missing something else here. When I referred to the “conflict” in my last post, I was referring to the fact that (as shown in the Philips “A/D conversion sequence” timing diagram) the second byte (following the ID address and shown as “transmission of previously converted byte&#8221[noparse];)[/noparse] is a WRITE from slave to master, and will therefore conflict with the Basic Stamp second byte which is also a WRITE, but from master to slave, thus to me, it seems that both devices will “talk” on SDA line at the same time. Regardless, I do understand that this “dummy” reading will be discarded.

    Regards,
    Jim
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2005-04-11 19:41
    Jim,

    What second byte from the Stamp are you referring to? Here is Jon's syntax...


    I2CIN SDA, PCF8591, [noparse][[/noparse]dummy, STR aIn\4]

    The only byte sent from the Stamp is the device ID held in the variable PCF8591. Then the I2C command turns around to receive the dummy byte followed by the 4 conversion results from 4 analog channels.

    The I2COUT command sends two bytes after the device ID, one to configure the chip and one to set the analog D/A output level.
    I2COUT SDA, PCF8591, [noparse][[/noparse]D2A_Enable + Auto_Inc, aOut]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Jim S.Jim S. Posts: 13
    edited 2005-04-11 20:42
    Here are excerpts (verbatim) from the Basic Stamp Manual Ver. 2.0, page 137:

    I2CIN Pin, SlaveID, Address {LowAddress}, [noparse][[/noparse]InputData]

    Address: is a variable/constant/expression indicating the desired address within the I2Cchip to receive data from…

    What the above means to me is that the "Address" (second byte following SlaveID) is a WRITE from Basic Stamp to slave device. This also implies that the "dummy" byte ( I2CIN SDA, PCF8591, [noparse][[/noparse]dummy, STR aIn\4] ) is a WRITE from Basic Stamp to slave device (not vice-versa as you’re indicating).

    Again, I don’t mean to dwell on it, but I still think this causes both devices to "talk" on SDA line at the same time.

  • Tracy AllenTracy Allen Posts: 6,658
    edited 2005-04-11 21:01
    That is why you need to download the ver. 2.1 manual! Or refer to the help info online with the program. There it says,\

    "Address is an optional variable/constant/expression (0 – 255) ..."

    where the watchword is "optional". Observe Jon's syntax, which in fact not send an address after the device ID. Only one byte, not two, was sent from the Stamp to the PCF8591.

    The I2C command on the Stamp did evolve from its earliest implementation so that it could handle a wider variety of I2C devices. Notice that the top sticky message on this BASIC Stamp list is where you can download the most recent and up to date HELP file, courtesy of Jon Williams!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-11 23:04
    And FWIW ... I updated and ran that code this morning. The original version was written for the BS2p when at least one Address byte was required -- that is no longer the case so I brought the code up to current standards.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • Jim S.Jim S. Posts: 13
    edited 2005-04-12 00:15
    Tracy and Jon,

    Ah-ha! I finally get it! (Jim, can you say it three times - optional, optional,·optional).

    Thanks for your patience and perseverence with me.
Sign In or Register to comment.