I have made the following data connections between my Edison and an MPU6050 IMU per /message/282040# 282040 this helpful thread:
SCL <-> J17-7 (I2C-6-SCL)
SDA <-> J17-9 (I2C-6-SDA)
I have two questions:
1) I have measured the voltage for both of these lines to be 2.23V. The MPU6050 breakout board is powered with 5V. Both the Edison and the IMU are powered from a 3S LiPo through the J21 jumpers. Is it a problem that the voltage of these lines is not 1.8V? On a more general level, I'm a bit confused about why the voltage for a data line is important.
2) For each of these pins, the function is under Pinmode1. What Python command can I use to assign it as such, as opposed to the default Pinmode0?
Thank you for your help.
Which MPU-6050 Breakout board are you using?
If it is the https://www.sparkfun.com/products/11028 Sparkfun one then it should not be powered from 5V it is a 2.3 V to 3.4 V device.
Pretty much all GPIO on edison is at 1.8V (So a "high" or "1" level signal is 1.8 V, a low or "0" is 0 V).
To interface to anything which uses GPIO at higher voltages requires a level shifter such as TXS0108 or TXB0108 (read the data sheets to see how they work). There are other level shifers about too, or you could even make your own using a few MOSFETs.
If you connect a voltage higher than the Edison's GPIO voltage to the Edison GPIO pins you could permanently damage the Edison.
Could you possibly post a schematic of your connections?
I'm using the http://playground.arduino.cc/Main/MPU-6050 GY-521 breakout board which accepts a 5V input, so I'm not worried there. In response to your advice about the input voltage to the Edison, I made a voltage divider. Please see the following image for the schematic.
For reference, the code I am using is this:
import time, math, mraa, socket, select
import numpy as np
x = mraa.I2c(6)
MPU = 0x68
AcX = np.int16(x.readReg(0x3C) | x.readReg(0x3B)<<8)
AcY = np.int16(x.readReg(0x3E) | x.readReg(0x3D)<<8)
AcZ = np.int16(x.readReg(0x40) | x.readReg(0x3F)<<8)
TMP = np.int16(x.readReg(0x42) | x.readReg(0x41)<<8)
GyX = np.int16(x.readReg(0x44) | x.readReg(0x43)<<8)
GyY = np.int16(x.readReg(0x46) | x.readReg(0x45)<<8)
GyZ = np.int16(x.readReg(0x48) | x.readReg(0x47)<<8)
It looks like the register is not being recognised anyway.
What did you use for the voltage divider?
It needs to work in both directions, so the SDA can be driven by Edison, but also by the device. (in reality the line is pulled up either by Edison or by external pull-up, and then driven LOW by whichever device is trying to transmit. Nothing in I2C ever drives the line HIGH).
The device may also hold SCL low (clock stretching) so IO Voltage translation needs to work in both directions.
I guess the next thing would be to attach an oscilloscope (or a logic analyser) to the SCL and SDA pins at the breakout board, but also at the GY-521 board to see what is working and what isn't.
Here's what I think is going on! Does this look like it could work in both directions?
I had a bit of a go hooking up the board to an oscilloscope but have not observed the characteristic square waveforms.
I'm not surprised. :-)
That voltage divider will only work to, well, divide the voltage. It can't multiply it back to the higher levels required by the external device when the Edison is doing the signalling.
I know it feels like a lot of hard work to get a simple sensor working - but it'll be worth it in the end.
What you need is a dedicated level translator IC, such as TXS0108 or TXS0104. Here's an interesting article, written by experts, on voltage level translation:
http://www.ti.com/lit/an/scea044/scea044.pdf http://www.ti.com/lit/an/scea044/scea044.pdf and another one written by more experts can be found here : https://www.nxp.com/documents/brochure/75017511.pdf https://www.nxp.com/documents/brochure/75017511.pdf
Finally, it might be possible to build a voltage level translator for your needs with some simple discrete components, but it's a bit tricky because the SDA and SCL signals are open-drain, and the signals are bi-directional.
I hope this helps!
I have installed my level translator but it still is not recognising the board. I have some other ideas for troubleshooting that I'd like to get some feedback on.
1. I'm going to try switching the connections from J17-7 to J18-6 and J17-9 to J17-8. In the above code, J17-7 apparently corresponds to mraa.I2c(6). What is the equivalent of the (6) for the J18-6 pin? Is there a source for the pin mapping for the I2C bus? It looks like there are 7 available in the /dev/ directory.
2. Related to (1), I'd like to confirm that it is accessing the Pinmode1 column in my code. Is this just automatic, based on the mraa.I2c command?
3. I have noticed http://www.i-programmer.info/programming/hardware/9124-exploring-edison-i2c-bus.html here and https://terojaakkola.gitbooks.io/intel-edison-notebook/content/i2c_circuit_33v_sensor.html here there are schematics with pull-up resistors. What is the effect of not having them, as in my current configuration? Do I need to add them? If so, what is an appropriate value for the resistance and why?
Check this link: https://github.com/intel-iot-devkit/mraa/blob/master/docs/edison.md, there is the MRAA pin mapping for the Edison breakout board, the J18-6 pin is the I2C-1-SCL, now you can also use this example as reference for your troubleshooting steps: https://github.com/intel-iot-devkit/upm/blob/master/examples/python/mpu60x0.py
About your doubts with pull-up resistors, it depends of the level translator that you are using, because some level translators need it according to the datasheet so please check it. If you want to know more about the pull-up resistors please check this tutorial: https://learn.sparkfun.com/tutorials/pull-up-resistors.
I hope you find this information helpful.
Have a nice day.