Shop OBEX P1 Docs P2 Docs Learn Events
Propeller I2C Interface Questions (3.3V or 5V) — Parallax Forums

Propeller I2C Interface Questions (3.3V or 5V)

BuildAMachineBuildAMachine Posts: 7
edited 2013-08-07 08:37 in Propeller 1
Hello everyone,

I have recently got my propeller (and therefore a newbie), and plan to use it in an I2C motor controller project, specifically for an Arduino shield

I want to make the shield 3.3v or 5v compatible, and that got me wondering what to do for the I2C.
I have seen other posts relating to the Propeller's 5v tolerance, but I'm still not exactly sure what to do for an I2C interface- if I need to use bus buffers, what to do with the I2C pull-ups, components required, etc.

To cut to the chase, what would be the best method of implementing an I2C interface with the Propeller, in which the logic HIGHs could be either 3.3v or 5v (determined by the Arduino's IORef Pin)?

Thanks in Advance,
BuildAMachine
«1

Comments

  • SRLMSRLM Posts: 5,045
    edited 2013-08-05 22:53
    The I2C protocol specifies a high as being pulled up by a resistor so that makes it easy to interface to a 3.3v to 5v application. Simply put the pullup resistors to 5v and add a 20Kohm or higher series resistor at the prop pin and you should be good to go.

    Edit: This isn't correct. I don't know what I was thinking, sorry for any confusion.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2013-08-06 00:59
    The I2C bus is nifty in that it is 'active low'. There is no logic high. So a high is a pullup, and since there are usually pullups on the propeller for the eeprom, you don't need to add any more. Some boards leave one of them out, so maybe just check there is a 10k pulling up the clock and another 10k pulling up data. Those two resistors connect to 3V3.

    The clever bit is you can supply chips on this bus with either 5V or 3V. Take a MCP23017 which gives you 16 inputs or outputs. Supply it with 5V and all those IO pins are 0V or 5V. Supply it with 3V3 and all the IO pins are 0V or 3V. You can even mix and match chips supplied with different voltages and put them all on the same I2C bus.
  • tonyp12tonyp12 Posts: 1,951
    edited 2013-08-06 08:39
    > 20Kohm or higher series resistor
    Such a high value would create a Voltage divider that would not go below 3.3V when pulled low
    I think 1K would be good
                           5V
                           │
                           ┴
                          10K
                           ┬                           
    Gnd<(P0)-------[1K]----&#9524;----> SDA 
    
    
              3V            5V
              &#9474;   S         &#9474;
              &#9524;   D         &#9524;
             10K  A        10K
              &#9516;   ^         &#9516;                           
    Gnd<(P0)--&#9524;---&#9524;-[1K]----&#9524;---->SDA  
    3v3 and 5v shared i2c (Vdd will pulled up a little, bit minimal)            
    
  • shimniokshimniok Posts: 177
    edited 2013-08-06 09:09
    Beware that some I2C objects on OBEX actually drive the bus actively(!) -- violating the ingenious I2C design and resulting in situations where the slave is pulling low and the master is actively driving high--ie, short through slave's driver transistor. I say that like it's a bad thing... :)

    Would you like to take an early peek at my I2C master code? It respects the open-drain design of I2C (it either pulls the line low or goes hi-z and lets the pull-up pull it high). You specify 100kHz or 400kHz operation. You can have sda and scl on any two unique pins. Finally, it honors I2C clock stretching which means the slave has a way to tell the master to slow down. In working with low speed ATtiny's running I2C implemented via USI, comm won't work reliably without clock stretching. Written in spin/pasm.
  • jazzedjazzed Posts: 11,803
    edited 2013-08-06 09:46
    Just use 3.3V I2C pull-ups if possible.
  • BuildAMachineBuildAMachine Posts: 7
    edited 2013-08-06 11:38
    Thanks to everyone for the help, appreciate it.
    shimniok wrote: »
    Beware that some I2C objects on OBEX actually drive the bus actively(!) -- violating the ingenious I2C design and resulting in situations where the slave is pulling low and the master is actively driving high--ie, short through slave's driver transistor. I say that like it's a bad thing... :)

    Would you like to take an early peek at my I2C master code? It respects the open-drain design of I2C (it either pulls the line low or goes hi-z and lets the pull-up pull it high). You specify 100kHz or 400kHz operation. You can have sda and scl on any two unique pins. Finally, it honors I2C clock stretching which means the slave has a way to tell the master to slow down. In working with low speed ATtiny's running I2C implemented via USI, comm won't work reliably without clock stretching. Written in spin/pasm.

    It would be nice to pick up some some of this code, and even a basic version of this would be would be sufficient as slave code
    tonyp12 wrote: »
    > 20Kohm or higher series resistor
    Such a high value would create a Voltage divider that would not go below 3.3V when pulled low
    I think 1K would be good
                           5V
                           &#9474;
                           &#9524;
                          10K
                           &#9516;                           
    Gnd<(P0)-------[1K]----&#9524;----> SDA 
    
    
              3V            5V
              &#9474;   S         &#9474;
              &#9524;   D         &#9524;
             10K  A        10K
              &#9516;   ^         &#9516;                           
    Gnd<(P0)--&#9524;---&#9524;-[1K]----&#9524;---->SDA  
    3v3 and 5v shared i2c (Vdd will pulled up a little, bit minimal)            
    

    This seems like a very straightforward implementation, but I am wondering would the implementation of the circuit be any different for a 3.3v master?
    (See image)
    Screen Shot 2013-08-06 at 1.51.59 PM.png


    Would it be the same implementation if the Master is running at 3.3v core voltage?

    Thanks in advance
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-08-06 11:43
    Beware that some I2C objects on OBEX actually drive the bus actively(!) -- violating the ingenious I2C design and resulting in situations where the slave is pulling low and the master is actively driving high--ie, short through slave's driver transistor. I say that like it's a bad thing.

    Indeed. Technically, even the Propeller violates the I2C standard on boot-up by driving the SCL line high and low -- this is why you seem some Propeller designs with just one pull-up (on SDA).

    I haven't needed high-speed I2C in any of my apps (yet) but my own Spin code is I2C compliant (active-low for 0, hi-z for 1). If you're really nervous there is a popular circuit that involves a couple pull-ups and a MOSFET. The circuit takes care of bi-directional level translation. I have used this circuit in my own projects.
    296 x 297 - 28K
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-06 16:41
    Ditto Jon's circuit. Forget all the resistor divider stuff. The MOSFET circuit is the correct way to interface 5V I2C chips to the Prop.

    -Phil
  • RaymanRayman Posts: 14,662
    edited 2013-08-06 16:59
    I used a level shifter, PCA9512, to go from 3.3V to 5V...
  • BuildAMachineBuildAMachine Posts: 7
    edited 2013-08-06 17:18
    Rayman wrote: »
    I used a level shifter, PCA9512, to go from 3.3V to 5V...

    That seems like a really neat chip, and if I understood the datasheet correctly, it can both buffer as well as a level shift the I2C (if the Vcc pins are at different logic) - please correct me if I am mistaken

    Is there anything special that I need to do with the "Rise time accelerator" pin - just tie it through a 10k resistor to 3.3v that the Propeller is running on?

    Thanks for the suggestions (an to all previous contributors)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-06 17:20
    jazzed wrote: »
    Just use 3.3V I2C pull-ups if possible.

    This has worked for me with any 5V I2C devices I've used.

    Even if you pull it up to 5V you shouldn't need any other resistors as long as your pull-up resistor is 3.3K or more.

    Edit: See post #15.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-06 17:23
    Ditto Jon's circuit. Forget all the resistor divider stuff. The MOSFET circuit is the correct way to interface 5V I2C chips to the Prop.

    -Phil

    I don't understand why a MOSFET is needed at all? The 5V through a 10K resistor isn't going to hurt the Prop right?

    I figure I must not understand something since you (Phil) and JonnyMac know a lot about this stuff than I do.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-06 18:01
    One problem with the 10K/1K circuit is that SDA does not get pulled all the way to +5V, due to the "short" to 3.3V through the Prop pin's protection diode.

    -Phil
  • BuildAMachineBuildAMachine Posts: 7
    edited 2013-08-06 18:09
    It seems as if the MOSFET idea should solve most of the problems, but I am wondering if the "source" side of the MOSFET can be of equal voltage pull-up to the 3.3v side (the source side is running at 3.3v) - I presume it can, but correct me if I am wrong

    Just another cheap aforementioned method, is it possible get away with simply pulling up the entire bus with 3.3v?

    Thanks,
    BuildAMachine

    P.S. I looked at Adafruit's PWM servo shield, claiming that it can work with a 3.3v or 5v I2C bus, and it can, but you have to solder a jumper- a bit too cheap for me
  • RaymanRayman Posts: 14,662
    edited 2013-08-06 18:09
    That seems like a really neat chip, and if I understood the datasheet correctly, it can both buffer as well as a level shift the I2C (if the Vcc pins are at different logic) - please correct me if I am mistaken

    Is there anything special that I need to do with the "Rise time accelerator" pin - just tie it through a 10k resistor to 3.3v that the Propeller is running on?

    Yes, buffers, level shifts, and makes it hot swappable...

    I don't remember what I did with the rise time accelerator... I wasn't too worried about it since I was talking with Spin and not assembly speed...
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-08-06 18:24
    Hi Duane;
    Duane Degn wrote: »
    I don't understand why a MOSFET is needed at all? The 5V through a 10K resistor isn't going to hurt the Prop right?
    Ya, you may get away with the resistor version.
    But to follow the I2C spec as originated by Phillips the MOSFET circuit, also suggested by Phillips, will legitimately interface to 5V devices.

    Apparently some parts really do require 5V levels and not work with just 3.3V levels.
    Besides the MOSFET circuit is faster because they can accommodate lower valued pullups.
    The PCA9512 is the best method as it also buffers the lines so is even faster.

    BTW, the venerable 2N7000 or 2N7002 also work well in the circuit.

    Duane J
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-06 18:53
    One problem with the 10K/1K circuit is that SDA does not get pulled all the way to +5V, due to the "short" to 3.3V through the Prop pin's protection diode.

    -Phil
    Ya, you may get away with the resistor version.
    But to follow the I2C spec as originated by Phillips the MOSFET circuit, also suggested by Phillips, will legitimately interface to 5V devices.

    Apparently some parts really do require 5V levels and not work with just 3.3V levels.
    Besides the MOSFET circuit is faster because they can accommodate lower valued pullups.
    The PCA9512 is the best method as it also buffers the lines so is even faster.

    Thank you both for clarifying this. MOSFETs good, got it (I think).
  • tonyp12tonyp12 Posts: 1,951
    edited 2013-08-06 18:53
    PCA9306 and from tiny XSON-8 to SOIC that even poor eyes can see
    http://www.mouser.com/Search/Refine.aspx?Keyword=PCA9306&Ns=Pricing%7c0&FS=True

    But if you really want to save space, a 0.5mm spacing with built-in 10k pull-up resistors.
    http://www.mouser.com/ProductDetail/Fairchild-Semiconductor/FXMAR2102UMX/?qs=sGAEpiMZZMsty6Jaj0%252bBBpWyMwR3WqSjX0zrY8jBvBY%3d
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2013-08-06 19:00
    P.S. I looked at Adafruit's PWM servo shield, claiming that it can work with a 3.3v or 5v I2C bus, and it can, but you have to solder a jumper- a bit too cheap for me

    It took me ages to work out the clever way the I2C hardware works. If it is done properly, there is no such thing as a "3.3V or 5V" bus, and then there is no need for series resistors, or more than one pullup resistor.

    I'll try to explain my thinking in my muddleheaded sort of way :)

    Most busses work on voltages. You might define a bus high as being 3V but will 5V zap the chip? Yes it may well if the chip is a SD card or another microprocessor. The I2C bus is different.

    Devices on the I2C bus can only pull the voltage down to zero. They can't put any volts on the bus. This is why it does not matter what voltage any chip on the bus is supplied with. You could use a chip supplied with 12V and could put it on the bus and it would work fine - so long as it obeys the I2C rules. It is only allowed to pull the bus down to zero and never puts any volts on the line.

    I like to think of the drivers for the I2C bus as being a NPN transistor. Maybe they are? Or the old school 7406 buffer with open collectors. The transistor is on or off, and if it is on then it pulls the line to zero and if it is off then the line goes to whatever the voltage is on the pullup resistor. The I2C bus allows multiple devices to pull the line down to zero and it won't do any harm if 20 chips are all pulling the line to zero at the same time.

    The problems arise when the rules are bent. It is concerning to read post #5 that some obex code is putting volts on the I2C bus. Nothing should ever put volts on the bus.

    For talking to another microprocessor eg the schematic in post #7 it would be very worthwhile to check the code and make sure that the disabled state is HiZ and not High.

    The 'best' way is what jazzed says in post #6 - one pullup to 3V3 on each line. And you should not need any more resistors, or buffers or other pullups .

    I should add that I have this working on one of my boards. An I2C bus with an eeprom running on 3V3 and two MCP23017 chips each running on 5V. It really does work just like the manual says!

    re the attached image schematic post #7 where the box is labelled "Master Arduino" - is it possible to post the driver code for that? Just to make sure it is not putting any volts on the bus. If it is done right, you won't need the second 4k7 or the 1k series resistors.

    I hope this all makes sense. It took me a while to figure it all out myself when I got into the I2C bus earlier this year :)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-06 19:08
    But the pull-up resistors "put volts on the bus," and the minimum "high" logic level for any particular device on the bus may depend upon its Vdd. IOW, if the bus is pulled up to 3.3V, that may not be enough to register as a "high" for a device running form 5V. Hence, the need for multiple pull-up supplies and the circuitry (e.g. MOSFETs) to isolate them.

    -Phil
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-08-06 19:09
    It seems as if the MOSFET idea should solve most of the problems, but I am wondering if the "source" side of the MOSFET can be of equal voltage pull-up to the 3.3v side (the source side is running at 3.3v) - I presume it can, but correct me if I am wrong
    The "source" side is the lower voltage side so is supposed to be connected to 3.3V in the case of the Prop.
    (Note! The circuit should NOT connect the "source" side or gate to 5V as the gate may not reliably turn the MOSFET off when its supposed to.)

    The "drain" side must operate at a voltage equal to or greater than the "source" side.
    Of course, if both sides are the same voltage there is no point to using the circuit.
    Just another cheap aforementioned method, is it possible get away with simply pulling up the entire bus with 3.3v?
    Actually yes.
    If all the I2C devices on the bus specify they will work at 3.3V levels, even when running at higher voltages, everything should be fine. This may not always be true though, you must read the fine print in the specs.

    Duane J
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-08-06 19:11
    Dr_Acula wrote: »
    The 'best' way is what jazzed says in post #6 - one pullup to 3V3 on each line. And you should not need any more resistors, or buffers or other pullups .

    I should add that I have this working on one of my boards. An I2C bus with an eeprom running on 3V3 and two MCP23017 chips each running on 5V. It really does work just like the manual says!

    Using 3.3V has always worked for my needs but as Phil and Duane point on in posts #14 and 17, it can cause problems with some chips not seeing the 3.3V as a logic high.

    Edit: I see both Phil and Duane had already replied.
  • BuildAMachineBuildAMachine Posts: 7
    edited 2013-08-06 19:30
    Dr_Acula wrote: »
    re the attached image schematic post #7 where the box is labelled "Master Arduino" - is it possible to post the driver code for that? Just to make sure it is not putting any volts on the bus. If it is done right, you won't need the second 4k7 or the 1k series resistors.
    :)

    The Arduino boards usually consist of AVR (or in the Due's case, and ARM) based microcontrollers, with "Two-wire interfaces" as they call it (use it to avoid paying royalties to use I2C) built into the hardware of the chips- the TWI is directly compatible with the I2C protocol, so I presume that they would be open-collector or open-drain outputs.
  • BuildAMachineBuildAMachine Posts: 7
    edited 2013-08-06 19:42
    After a bit more research, I found that the I2C master microcontroller registers a logic HIGH of 3.5V, and people have had trouble directly interfacing with it by simply pulling up the I2C lines to 3.3v, so that will probably not work the best.

    I will probably go with the PCA9512 or preferably MOSFET shifter,
    It might be cutting it a bit close with the MOSFET shifter if the bus runs at 3.3V (e.g. if the Bus Master's Regulator is somehow running slightly lower than 3.3v, then I don't think that the shifter/buffer will behave as expected)

    I guess from here is only testing,
    The MOSFET shifter seems really elegant and cheap, but the PCA9512 seems like a safe bet
    Whatever works...

    Thanks for all of the input from everyone- really appreciate it :smile:
    BuildAMachine
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-08-06 20:02
    We were commenting on operating 5V I2C devices using 3,3V buses.
    I just checked on the MCP23017 16-Bit I/O Expander.
    The minimum HI input voltage to SCL and SDA:
    Parameter D041 says .8 * VDD or 4V.
    Yes, I know it can work but that is outside the spec.
    What happens if the Prop VDD is a bit low, say 3V, and the MCP23017 is a bit high, say 5.5V.
    Just saying!

    Duane J
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-08-06 20:08
    When I've gone "cheap" in mixed systems I use 4.7K or 10K pull-ups to 5v. These values are high enough to protect the Propeller pins.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2013-08-06 20:11
    The minimum HI input voltage to SCL and SDA:
    Parameter D041 says .8 * VDD or 4V.

    You are right, yikes!

    How could one fix this? 10k pullups to 5V and assume the leakage current is low enough to be ok?
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-08-06 20:17
    It is possible to use a mixed approach. For example, the Parallax #29124 altimeter is can be used either with the 5V BASIC Stamp or with the 3.3V Prop. It has a single channel I2C level shifter like the NXP chip for the bidirectional sda line, but a simple diode resistor combination for its scl input and for the inputs that support the SPI interface and mode selection. The resistor pulls up to the altimeter 3V supply, and the diode faces out to the interface pins of the microcontroller.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-08-06 20:24
    It might be cutting it a bit close with the MOSFET shifter if the bus runs at 3.3V (e.g. if the Bus Master's Regulator is somehow running slightly lower than 3.3v, then I don't think that the shifter/buffer will behave as expected)
    Actually the 2N7000 MOSFET is ideally suited for this application even if you are running the Prop down to 2.7V. See some of my measurements:
    MOSFET_2N7000_Vgs.gif

    The MOSFET is turned on amply hard enough below 2.4V.

    I don't have BSS123 MOSFETs to test so no data.

    Duane J
    942 x 588 - 15K
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-08-06 20:33
    I've had good luck with the TXS0102 from TI, similar to the one mentioned from NXP/Philips. It also has the bus acceleration feature, and along with that comes built in pullup resistors of about 10kΩ, so you don't have to supply them externally. The bus acceleration in effect lowers the pullup resistance briefly during the low to high transition.

    One nice feature of that particular chip is that it has an output enable pin, and when that pin is low all of the signal pins become high impedance. That allows one to build a versatile bus multiplexer. Also it allows a measure of isolation, so that if the power on one I2C device is turned off either intentionally or by some accident, it is possible to isolate or failsafe that part of the I2C bus. Suppose you have several motor controllers on one I2C bus and one them happens to short circuit, or simply gets turned off. If you analyse the simple FET circuit, that one device, pulling low through its protection diodes and its pull-up resistor (now pulli-down) can lock up the entire bus and entail a number of gray hairs. Of course in core µP circuits, that is a rare occurance, but it is something to consider when dealing with an off-board bus.
Sign In or Register to comment.