I2C troubleshooting

I’ve been reading up on I2C and have looked at the hardware I2C example in the wiki. It looks simple enough and the driver does a nice job of relieving the developer of knowing the nitty gritty timing details for the I2C protocol.

However, I am trying to interface with an I2C pressure sensor, and am having trouble getting it to communicate. I’ve attached the communication diagram.

What doesn’t make sense to me is that it seems like it’s non-standard or something. The driver code implies that we’ll send some number of bytes to the slave, and the slave will respond with a certain number of bytes. I just need to create the I2CTransactions of an appropriate size, and then send Execute them via the I2CDevice object.

The diagram implies that the R/W bit just has to be set for the sensor to respond with 2 bytes of data. The only way I can see doing this is to send over one byte, where the first 7 bits are the sensor’s ID, and the last bit is set to 1. The device’s default ID is 0x78, so I tried to send 0x79. Actually, I’ve run a loop where I sent 0-255, and each time I got a timeout error. So perhaps there is data coming back but it’s not formatted properly?

I’ll put the SCL and SDA lines on my logic analyzer, and maybe I’ll see something worth following up with another post. If anyone could offer me some opinions or suggestions for troubleshooting this, I’d really appreciate it!

UPDATE: I decided to scope out the clock signal directly from the Fez Panda II (I disconnected the sensor completely), and have attached the waveform. It’s all over the place! Is this normal with I2C? I also dropped my speed down to 100kHz, which is the minimum recommended speed for my sensor.

Apparently, you can’t add multiple images as attachments. :slight_smile: I’ve reattached the communication diagram to this post since my last post update overwrote it.

Your analyzer maybe set to low sampling rate. Try a lower I2C clock maybe?

I2C is handled in hardware so it will be perfect clock

Ok, I found one dumb mistake. I accidentally knocked off the ground wire for my logic analyzer, then proceeded to hook it up to another part of the circuit. Now my SCL signal looks great. I’ll hook up the circuit again and try one more time.

Well, now my sensor seems to be communicating, which is good. However, I don’t get anything intelligible from it (just zero). I’ve attached the logic analyzer output, which shows some data going back and forth. I send the device one byte and get back two bytes. What’s weird is that between START and STOP I expect to see 27 clock pulses (according to the sensor manual), but I count 28. After the NACK, there is an extra one.

I’ll keep poking away at this. Since I’m no longer getting errors from I2CDevice.Execute(), I guess things are technically “working”.

Depending on your device, you might have to send it a StartMeasuring command. Which device is it?

I’ve attached the I2C communication document. Where I’m having trouble is in the command sent to the sensor – its documentation implies that there is no command. Instead, I’m supposed to set the R/W bit in the byte immediately after sending Start. It doesn’t look like the I2CDriver in .NETMF allows this. Maybe I’m missing something?

One thing that’s currently stumping me is in the addressing of this device. As the sensor’s comm spec says, the sensor’s ID is 1111000bin. (this is wrong, I must have been way confused when I wrote it —>)Well, to me that’s actually 01111000, which is 0x3C. I saw them use 0x78 in a sample (the only useful info in that particular code), which is 11110000(<— no it’s not, that’s 0xF0. Embarrassing mistake!). I can “talk” to the device (i.e. not get errors) only when I use 0x78 for the device address. The problem I see now is that sending 0x1111000 immediately after start specifies I2C’s 10 bit addressing mode. My I2C protocol analyzer (OpenBench Logic Sniffer) also thinks that we’re now talking to a 10 bit slave.

So I’m just confused why I2C allows 0x1111000 immediately after Start, when this could also be used to switch to 10 bit addressing mode.

Perhaps I should have just special ordered the SPI version of this sensor. :slight_smile:

You just need to use a Read transaction.

Do you get any ack back from the device? The return of the Execute command gives you the total number of bytes read/written. It should be 3 in your case.

If it isn’t then you might have the address wrong. Some datasheet specify the address as 8 bits, ie with read/write bit. Others specify it as 7 bits.

This driver requires the address without the ReadWrite bit as it is appended depending on if it is a Read transaction or Write Transaction. So try 0x3C for your address.

Lol. You posted while I was composing my post.

So then yes, try 0x3c as the address, this is 0b0111100R.

Their 0x78 is the base address that already includes the Write bit.

Thanks, I’ll try that out. Hopefully it works. I’ve been reading the I2C specification, and it sounds like they’ve used one of the 8 reserved addresses, which is a real bummer. This technically will screw up the results from my protocol analyzer, but hopefully not I2CDriver. I’ll keep playing with it!

Hey, it’s working! Thank you!!! The trick was that the I2CDevice allows me to just specify a read transaction that needs 2 bytes back. But the address to specify is still 0x78.

Cool. Glad it works… :slight_smile:

Just for completion’s sake, maybe this will help someone else learning about I2C. I’ve attached an image showing a correct data transmission.

and here’s the overlay from the I2C protocol analyzer

And just to help out further, there’s an I2C description that talks about 7-bit vs 8-bit addresses over here [url]http://wiki.tinyclr.com/index.php?title=I2C_-_EEPROM[/url] The constructor of the I2CDevice.Configuration MUST take the 7-bit address.