Shop OBEX P1 Docs P2 Docs Learn Events
I2C and eeprom woes — Parallax Forums

I2C and eeprom woes

jboylesjboyles Posts: 7
edited 2008-05-15 04:45 in Propeller 1
This is my first electronics project, and therefore first with the propeller. I will apologize in advance if the problem is painfully obvious.

I'm using the prop proto board in part as an I2C master to monitor 4 external LM92 temperature sensors and 1 PCF8591 ADC which is reading from a ASDX gage pressure sensor, 0-1 psi. The temperature sensors are running at 3.3V, and the ADC and pressure sensor are running at 5 V. To handle the voltage difference, I used the N-channel enhancement mosfets (IRF510) as bi-directional level shifters as described both in this forum and in the I2C specification. I'm using 4 trimpots (data and clock for 3.3V and 5V buses), all set to 4.7 k for pull-ups. I'm using P29 for SDA and P28 for SCL. To connect to the external sensors, I'm using cat-5e cable to rj-45 jacks, then cat-5e cable to the devices. I have the four striped wires tied to ground as the I2C spec recommends twisting each line with ground to avoid crosstalk. The striped wires are not connected at the devices to avoid ground loops. I do not have a capacitance meter, so I'm not sure what the bus capacitance is. The cables are roughly 1', 3', 3', 3', and 4'.

When I load a program into RAM, I use the Basic_I2C_Driver to scan the bus, and it finds 6 devices with the 5 expected addresses from my devices, and one with the address %1010_0000 which must be the eeprom. Funny thing is, if I try and load the program into the eeprom, I get an eeprom programming error. Additionally, if I try and reset the prop so that it is forced to load a program from eeprom, it does nothing. If I unplug my cat-5 cables from the rj-45 jacks, then the eeprom can be programmed and programs can be loaded from it. Of course, I can't talk to my devices anymore. Any ideas what may be going on?

While typing this it occurred to me that the 10k pull-up resistors for the eeprom may be too large given my bus capacitance. Would this make sense based on what I've seen? I'm guessing the easiest solution is to simply use pins other than P29 and P28 for my I2C bus.

Thanks for the help!

Comments

  • jboylesjboyles Posts: 7
    edited 2008-05-14 02:55
    Spoke too soon about finding all the devices. I could've sworn I saw it find 6 devices, but when I use the devicePresent function, one of the devices is not there, and it is not showing up on the scan anymore (only 5 devices). Not surprisingly, it's the device on the 5 V side of the bus. I can swap around which of my 5 devices is on that side, and that's the one that's always missing. Has anyone used the mosfet approach, and is the IRF510 a suitable mosfet for this? If not, which specific mosfets would be good?
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-14 03:05
    First of all, the IRF510 MOSFET is not suitable for this sort of level shifter. It requires too high a gate voltage to conduct.

    You don't need pullups on the 3.3V side of the I2C bus since the Protoboard already has them on both SCL and SDA.

    Have you carefully checked the connections on the cables and to the various sensors?

    If the Basic_I2C_Driver can find the various devices, but other Propeller code cannot, it may be a speed problem. Try shorter cables or lower pullup values on the 5V side.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-14 03:10
    I've got a setup with just a 1K series resistor in the SCL and SDA leads from the Prop / EEPROM at 3.3V to 3 x PCA9554 I/O Expanders at different addresses running off 5V. It's only a few inches of wiring rather than several feet, but the 1K resistors work fine. There are 10K pullups on the 5V side.
  • jboylesjboyles Posts: 7
    edited 2008-05-14 03:27
    Ok, I was worried about the IRF510s, but I'm not familiar with mosfets at all, and they were the only ones at the store that were even the right type. I don't think I need enough components to justify an order from digikey, so I'll try using the 1K series resistor instead of the mosfet approach.

    I definitely won't be able to shorten the cables as the sensors need to be at fixed locations. All the connections seem to be fine, and like I said, the 3.3 V side of the bus is fine- I'm able to see them on the scan, with the devicePresent, and I'm able to read the temperatures correctly. I'm pretty sure the 5 V side is fine too as far as connections go, but I can't tell since the mosfets won't conduct.

    Since I can't change the 10K pull ups present on the proto board and can't shorten my wires, wouldn't it be easiest to use different pins for SDA and SCL? I'm still not sure I get why the eeprom won't work with my devices all connected, yet the devices work (other than the 5 V side due to the mosfet issue). Would the additional (and unnecessary) pull ups I added on the 3.3 V side not affect the eeprom? Like I said, the eeprom works with the devices disconnected, which suggests to me that it's the change in bus capacitance that's responsible. The other possibility that comes to mind is an address collision, but that's not the case with my devices.

    Thanks again!
  • JavalinJavalin Posts: 892
    edited 2008-05-14 11:05
    Hello,

    What code (is it public?) are you using for the LM92?

    For 3.3v / 5v devices - most of the time you can just use a 1k in line resistor between the 5v and the 3.3v section, and a 4.7k pull-ups on the to lines or either 5v or 3.3v

    James
  • JonathanJonathan Posts: 1,023
    edited 2008-05-14 13:12
    You might try Beau's i2c level shifter. I was dealing with an i2c ADC recently, and it was cranky with any other circuit I tried. It's very simple, an npn transistor and diode.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
    467 x 220 - 2K
  • jboylesjboyles Posts: 7
    edited 2008-05-14 13:38
    Javalin said...
    Hello,

    What code (is it public?) are you using for the LM92?

    For 3.3v / 5v devices - most of the time you can just use a 1k in line resistor between the 5v and the 3.3v section, and a 4.7k pull-ups on the to lines or either 5v or 3.3v

    James

    I'm using the Basic_I2C_Driver along with a bit of spin code I wrote:

    PRI getTemp(addr) : temp | sign, byte1,byte2
      'gets temp register from the LM92's, temp is 16 bit, 2's complement with LSB = 0.0625 °C, bits 2-0 are status bits
      'stores temp as integer temp x 10000
    
      i2cbus.start(scl)
      i2cbus.write(scl,addr) 'request read of LM92 temp
      byte1 := i2cbus.read(scl,i2cbus#ACK) 'read first byte
      byte2 := i2cbus.read(scl,i2cbus#ACK) 'read second byte
      temp := byte1 << 8 'shift left to make room for next byte
      temp |= byte2
      sign := temp >> 15 'get sign bit
      temp &= $7ff8 ' mask sign and status bits 
      temp >>= 3 'shift right to remove status bits
      if sign == 0
        temp *= 625
      else 'shouldn't need have neg temps, but added for completeness
        temp := -2_560_000 + 625 * (temp-1) 'temp is 2's complement
      i2cbus.stop(scl) 
    
    



    I don't doubt that this could be optimized, but the LM92's can't be read any faster than once per second, and speed isn't an issue in my application. Also notice that I'm storing temp as an integer even though it's really measured to the ten thousandth.

    I will try the 1K series resistor approach when I get a chance to work on it some more- sadly the only soldering iron I have at home is borrowed, and it's as big around as my finger.
  • jboylesjboyles Posts: 7
    edited 2008-05-14 13:40
    Jonathan said...
    You might try Beau's i2c level shifter. I was dealing with an i2c ADC recently, and it was cranky with any other circuit I tried. It's very simple, an npn transistor and diode.

    I'll have to try that out. Do the npn and diode give you the same effect as the n-channel enhancement mosfet?
  • JavalinJavalin Posts: 892
    edited 2008-05-14 13:42
    thanks jboyles. I've been trying on and off to get mine working - seems to be either 19 degrees or 392 degrees...!

    James
  • JonathanJonathan Posts: 1,023
    edited 2008-05-14 14:23
    J,

    I imagine the effect is roughly the same as mosfets, after all the objective is a level shifter.

    What I do know is that with the above circuit, I got this ADC that wouldn't work right with any other circuit I tried to work just great on a protobaord using the dedicated i2c pins. With other circuits I got erratic results, for example the ADC reading a max count of 3000 or so. So other circuits did communicate with the chip, just not correctly. Looking at it all on a scope, I never really figured out why, but then I have limited equipment and comprehension. [noparse]:)[/noparse]

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
  • jboylesjboyles Posts: 7
    edited 2008-05-14 16:03
    Jonathan said...
    J,

    I imagine the effect is roughly the same as mosfets, after all the objective is a level shifter.

    What I do know is that with the above circuit, I got this ADC that wouldn't work right with any other circuit I tried to work just great on a protobaord using the dedicated i2c pins. With other circuits I got erratic results, for example the ADC reading a max count of 3000 or so. So other circuits did communicate with the chip, just not correctly. Looking at it all on a scope, I never really figured out why, but then I have limited equipment and comprehension. [noparse]:)[/noparse]

    Jonathan

    Jonathan,

    One quick clarification- should the resistor from the transistor base to the 3.3 V be the same value as the pull up resistors? I'm using 4.7k pull ups, so should I have a 4.7k resistor from base to 3.3V?

    Thanks,

    Jeffrey
  • JonathanJonathan Posts: 1,023
    edited 2008-05-14 16:37
    I'm not qualified to say, I can only tell you what I did. I used the values as shown. The pullup on the far left is the one on the protoboard. So, all you need is the 3.3V 10K base pullup and the 5V pullup, plus of course the transistor and diode.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
  • jboylesjboyles Posts: 7
    edited 2008-05-15 03:57
    Javalin said...
    thanks jboyles. I've been trying on and off to get mine working - seems to be either 19 degrees or 392 degrees...!

    James

    Hi James-

    Let me know how it goes. I had a few screw ups along the way with interpreting output, mostly not realizing that the status bits were coming through as well. I found the temperature register diagram on page 11 and the timing diagram at the top of page 13 of the datasheet particularly helpful. One thing I noticed that should be changed with my code is that, according to the datasheet, the master "typically" uses a NAK to signal to the LM92 that it has read the last byte. Not sure why this is the convention, and I can't tell any difference between using ACK (as in my posted code) and changing it to NAK for the second byte. Maybe typically means it doesn't really matter?

    Jeffrey
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-15 04:45
    It does matter. The NAK tells the I2C slave device that it should not try to transmit another byte when the next clock pulse comes along. The stop sequence should reset the device, but some devices may require the NAK to properly reset the state machine.
Sign In or Register to comment.