I have the Intel Edison on the MBB hooked up to an MPU9250 breakout board (http://www.drotek.com/shop/en/home/466-imu-10dof-mpu9250-ms5611.html this one, though I've used another with same results) via a bog standard logic level converter (http://www.banggood.com/Logic-Level-Converter-Bi-Directional-IIC-4-Way-Level-Conversion-Module-p-938... this in this case, but have tried a different one from Drotek with remarkably even worse results, though in a different way and perhaps in that case attributable to the LLC). My issue is that the I²C lines aren't driven all the way low under certain circumstances.
Here's an oscilloscope screencap after resetting the sensor and just running i2cdetect:
As you can see it works just fine, the addresses (0x68 and 0x77) shows up, and I can do this multiple times with no issue (apart from the less-than-optimal waveform/rise time, but it's good enough and I just want it to work at all at this point).
However as soon as I run a program communicating with the sensor it immediately glitches out somehow. On the high side of the level shifter the whole waveform is simply "moved up" instead of being from 0-3.3V, presumably since the low isn't low enough. Below is a shot from running a program showing when it goes wrong (immediately after running), followed by a close-up of SCL in the faulty state.
As I've mentioned I've tried multiple sensor breakout boards, multiple level converters, and various pull-up configurations... The pull-ups will affect the waveform slightly but so far I haven't been able to fix the main issue. A theory I have is that the collective pull-up resistance is too low so the Edison is unable to pull it low, but even disabling the internal pull-ups and de-soldering the bridge marked "pull-up" on the breakout board leaving only the resistors on the LLC doesn't seem to help.
I'm not an electrical engineer or even very well-versed in this so any insight is helpful.
One option to force the I2C to be driven low is using an Amp Op. You can use the differential amplifier configuration. This circuit lets you subtract a voltage signal from another. So the idea would be to subtract the DC value you want to remove from the original AC signal. In a differential amplifier VO=V2-V1 in the case where the gain of the amplifier is A=1. V2 would be the analog signal from the I2C and V1 would be the DC value you want to correct and remove from the I2C signal.
Try using this approach and let us know your results.
Thanks for the reply! I've read up on opamps (differential amplifiers as suggested) and I think I get how it works. So in practice I can feed the opamp the I²C signal on one input, 0.32V on the other (before the level shifter) and get a range of 0-1.56 out instead of 0.32 to 1.88 as shown in the oscilloscope shot? Does this work for I²C which is bidirectional though? I might be missing something due to my EE inexperience/ignorance. Do changes to the opamp output also change the input (in the original voltage range)? Or would I need some additional circuitry?
Basically yes, if you subtract a DC signal from an AC signal using the differential amplifier configuration you'd be removing the offset of the AC signal. The Op Amp won't change the input if the gain of the circuit is A=1, as mentioned before. You can set A=1 if you use the correct resistor values. Some differential amplifier configurations inverse the signal. Look for the configuration that doesn't reverse the signal so you just have to deal with the offset.
Can you clarify whether it works for a bidirectional digital signal like I²C (remember I'm an EE newbie)? You didn't seem to address the question in your reply. I want to get it right because of limited funds (it's for a university thesis, self-funded) and not having a store nearby so I have to order online, pay exorbitantly for shipping and wait a week... Thanks for your patience!
Meanwhile, any ideas as to why/what actually happens in the first place? It's such a common circuit (Edison - level shifter - sensor breakout) that it clearly shouldn't exhibit this kind of behaviour or need extra circuitry in the form of a differential amplifier in the first place.
The Op Amp doesn't work in a bi directional way. The easiest way to do this is still using pull up resistors. You say in your original post that the pull up resistors you're using are too low. What resistor values are you using? If the value used is too low the pull up configuration will not work.
When you measured the i2C line in the first post were you using a level translator? What do you see if you don't use the level translator and just measure the I2C lines? In another picture, still not using a level translator, connect an I2C device to the I2C lines. Make sure this I2C device is 5V so that you don't need to use a level translator. The Arduino 1 can be used as this I2C device. This will prove if the issue is caused by the Edison itself or because of the external components used.
I'm using the mini breakout board which uses 1.8V logic so I have to use a level shifter, and yes, the screencaps are all using a level shifter and the circuit is exactly the same for all of the shots. Unfortunately I have no 1.8V I²C devices to try, nor an Arduino break-out board to use with 5V. Just running it not connected to anything shows perfectly normal I²C values if I recall correctly and I've now tried to connect an Arduino Nano to the Edison via the same level shifter and it seems to work; but it's just getting a request and sending a few bytes of data back, much less complex than the sensor I'm connected to otherwise.
I say the pull-ups is a theory I have; but it's just conjecture. My reasoning is that if the resistance to VCC is too low the Edison "isn't powerful enough" to drive the line all the way low. I haven't added any pull-ups 'manually'; the Edison has an internal pull-up that's configurable by software (20k standard IIRC, 1-50k options), the level shifter has SMD resistors on both ends marked 103 (so 10k) and the sensor break-out board has built-in pull-ups which I think are also 10k. As I mention I've tried disabling the one on the breakout board and the Edison internal ones but still have the issue. The waveforms change slightly, as they should, so it really is changing the resistance in some way or form. Perhaps the pull-ups aren't the issue at all, I stress that it's just a theory from a relative novice.
So since I²C is bidirectional the op amp suggestion won't work? That's too bad, but thanks! (and I learned something, so that's a win)
Why do you use a level shifter?
Check the D.C. Electrical Characteristics table in the datasheet of MPU9250 https://store.invensense.com/datasheets/invensense/MPU9250REV1.0.pdf https://store.invensense.com/datasheets/invensense/MPU9250REV1.0.pdf
VDDIO can be 1.8V. Just connect the VDDIO pin to the 1.8V pin of the Edison.
When you use a level shifter, pullup resistors must be used on both sides of the level shifter.
Thanks for the suggestion Vincenze, but VDDIO isn't exposed on any of the three different MPU9250/MPU6050 boards I have access to and I don't really have the tools, time or experience to create my own. I'm not particularly keen on soldering wires straight to the MPU9250 as it's a tiny 24 lead QFN package, but I guess I could try to mess around with the breakout board to break some paths and get wires on in the relevant places. It's not a first option though, since really, it should just work with a level shifter. If it's what I have to resort to then I guess I will have to look into if it's feasible on one of the boards. The level shifter does indeed have pull-ups on both sides.
Apparently, your level shifter doesn't work well.
Try to change the pullup resistors to 50-100k ones.
There are many specialized chips for I2C level converting like this one:
https://www.sparkfun.com/products/11955 SparkFun Level Translator Breakout - PCA9306 - BOB-11955 - SparkFun Electronics
Apparently. I've used two different ones that both claim to work just fine with I²C though, and this one does seem to work until all of a sudden it doesn't (second oscilloscope shot). I can't find a breakout board with a chip specialised for I²C without $20+ shipping (and a week long wait) in the EU... At some point it'll be cheaper and faster to just get the equipment to make my own PCB. It's a very well-known and common sensor chip, bog-standard level converter (looks exactly like the https://www.sparkfun.com/products/12009 SparkFun Logic Level Converter - Bi-Directional, though it's not Sparkfun) and the Edison. I don't get how this is happening when it seems to me it should just work. Quite frustrating. Appreciate the feedback though, I'll try to look around a bit more for something specialised for I²C, might have missed some store.
I did find a distributor in my country last night (of the specific Sparkfun board Vincenze linked to, incidentally), it's ordered but will take a few days for shipping with the weekend and all. I'll report back when it arrives and I can test it.
Have a nice weekend,
I've received the https://www.sparkfun.com/products/11955 PCA9306 and tried it with no luck. As expected it's still not driven low, and not only that but it's even higher with this module (with a nicer waveform though).
As you can see low is a full 0.8v. This is from i2cdetect, which worked before and looks reasonable now except too high. When I instead run the test program that actually does stuff, this is what I get:
It seems barely able to drive it low at all from a high state. Not sure what else could make it look like that.
That's four different types of level converters tried, all of which should have worked. The root issue must lie either with the Edison or with the sensor, but I've tried three different sensor boards with identical results (although all ultimately using Invensense IMUs, though they are very common and I've seen nothing about this issue). Is there some mysterious incompatibility between the Invensense IMUs and the Edison, is my particular Edison broken somehow, or is there something faulty with the Edison design?
Any suggestions on how to make the sensors work in light of this?
We want to try and replicate this issue. What image version are you using? Please also provide the test code, diagram of any external circuitry and other details if necessary.
I'm using 2.0 (because I²C is broken in software on 2.1 and 3.0---see ).
The only circuitry is the http://www.drotek.com/shop/en/home/466-imu-10dof-mpu9250-ms5611.html MPU9250 breakout board, https://www.sparkfun.com/products/11955 PCA9306 breakout board, and http://www.banggood.com/MB102-Breadboard-Module-Adapter-Shield-3_3V5V-For-Arduino-Board-p-996801.htm... 3.3V power source on a breadboard, and the Edison (with wires from 1.8V, GND, SDA1 and SCL1 to the breadboard) on the MBB powered by USB. It's wired as expected, but if you wish I can take a photo for verification.
You can test by just running `i2cdetect -y -r 1`; as you can see in the oscilloscope shots even that fails depending on the level converter because the low isn't low. For a step further, I guess the easiest would be running the https://github.com/intel-iot-devkit/upm/blob/master/examples/c%2B%2B/mpu9250.cxx example from UPM. I just (re-)verified it behaves the same as my current code (which uses RTIMULib2, have also run completely custom before).
The UPM example gives the same oscilloscope reading as in my previous post and fails with this:
terminate called after throwing an instance of 'std::runtime_error'
what(): writeReg: I2c.writeReg() failed
Thanks a lot for looking into it!
We have been experiencing a lot of trouble also with the I2C bus. We are seeing similar problems when interfacing a LSM9DS1 IMU chip with VDDIO = 1.8V. We have to play with the pull-ups value (and it is variable from one Edison board to the other, sometimes it does not work at all) because the Edison does not seem to be able to "drive" enough current on the I2C bus. This is a very frustrating situation and it is absolutely impossible to use the Edison for production at this time because of this issue.
The binary logic level within the standard values is:
0 V to 1/3 VDD is LOW
2/3 VDD to VDD
Where VDD = supply voltage
The logic will be considered LOW or Zero if the voltage less that 0.6 volt for 1.8 volt logic and 1.1 volt for 3.3 volt logic.
Indeed (good to have solid numbers to go by). In the case of the transistor (I guess) LLC, we get a low of 1.64V on the 3.3V side (higher than 1.1 so not recognised as low) and with the PCA9306 we get a low of 0.84V on the Edison side (higher than 0.6 so not recognised as low either). No wonder it doesn't work. Question is why the low is so high.