i2c Nothing Works!!!
zlantz
Posts: 136
Why cant sensors just use something simple like serial UART? I have only ONE i2c device that "works", and that device being the MPU-6050 and that is using the PASM MPU-6050 Driver from Obex.
Now I have also the MPU-9150 (wont work), the bmp180 (x3) (wont work), the bmp085 (x3) (wont work), the hmc5883 (x3) (wont work) and (x7) IR Thermopiles (wont work) and All Modules. I know im not getting shipped multiple broken parts from multiple sources and Everything revolves around i2c.
I have tried every SPIN driver available on obex, and now the PASM drivers as well. Still to this day, I only have ONE working device. All of my other sensors work fine. SPI ok, serial uart, ok. analog to adc ok.
Ive even tried running the BMP threw the MPU's xDA port. I can get the Chip ID, but that is all I can get, everything else appears to be wrong. Ive tried the mpu-9150 obex driver (dont work). ive tried EVERY bmp obex driver (dont work).
I have had made multiple attempts at i2c, even here on the forums. Is there any way to get this stupid protocol to work???!?!??!?!
Now I have also the MPU-9150 (wont work), the bmp180 (x3) (wont work), the bmp085 (x3) (wont work), the hmc5883 (x3) (wont work) and (x7) IR Thermopiles (wont work) and All Modules. I know im not getting shipped multiple broken parts from multiple sources and Everything revolves around i2c.
I have tried every SPIN driver available on obex, and now the PASM drivers as well. Still to this day, I only have ONE working device. All of my other sensors work fine. SPI ok, serial uart, ok. analog to adc ok.
Ive even tried running the BMP threw the MPU's xDA port. I can get the Chip ID, but that is all I can get, everything else appears to be wrong. Ive tried the mpu-9150 obex driver (dont work). ive tried EVERY bmp obex driver (dont work).
I have had made multiple attempts at i2c, even here on the forums. Is there any way to get this stupid protocol to work???!?!??!?!
Comments
I can only tell you that if I had the sensors sitting on my Tachyon Forth system that I would be having them debugged and operating while you watch. Because it's interactive you can scan the bus, delve a little deeper into a device, type in a one-line test and see if it works, etc.
This is a quick scan of my I2C bus through the serial terminal.
.I2CBUS
Fast Device at 0040 BC BC BC BC BC BC BC BC
Fast Device at 00A0 00 00 00 00 00 00 00 00
Fast Device at 00AE FF FF FF FF FF FF FF FF
Fast Device at 00DE FF FF FF FF FF FF FF FF ok
Hardware connections, and if you require pullups on the devices. Then, you have to consider the device address, an if the device address is configurable, is it set correctly at it's input pins. Next, consider your code. I remember going through the i2c learning curve with various devices, and you must tackle the process of tracking down these problems. It gets easier every time. Post your code and maybe someone can spot something. Without code, you will get very little help in this particular case. I use the basic i2c driver for most things that don't require high speed. Once you find a driver that works you just stick with it since a lot of your code will be similar so you can copy and paste blocks into other device needs with small changes. A schematic would be helpful, or even a photo of the setup if it is breadboarded, some info may be obvious just by looking at the setup.
Most parallax boards already have this on P28&P29. But, if you are using different pins, you will need to add those resistors yourself.
Drivers in general do not support clock stretching as it is very rare to find a chip that needs this as it was designed for decades old slow processors acting as slaves mostly. From perusing the sensor datasheets I see no mention of this. Since this is the case the clock line is normally driven high as well as low so no resistor is needed.....wait . However, since you have quite a number of devices on the bus and no telling the length or capacitance of the bus it would be advisable to use a much lower pull-up value on the SDA line, even if there are pull-ups already. Use a value of 2K2 as I2C buses have no problem handling that easily and it will pull-up the line faster. Since you are trying to get these devices to work I would also use a 2K2 on the clock line as well just in case your driver does not drive the line high.
I have tried on both my i2c & gps io (same layout as i2c, on pins 12 & 13). I mentioned before that the Modules come with pullup resistors, so I tried a port with no resistors as well.
I have 2 BMP-180's for testing both ways, one on the i2c bus via the MPU-6050, and one on the GPS Bus (no resistors) (uses module resistors).
They are connected according to the mpu-6050 datasheet (replace Magnetometer with BMP-180 Module).
I mentioned that I have many modules that dont work. Please dont assume they are all hooked up at once. When I test something I prefer to do it one thing at a time. With the exception of now; I am trying to use the MPU-6050 as an inline master to control the bmp since I have been able to get the mpu to work, but only with a PASM driver from obex (i dont know assembly) and cannot get it to work on my own as seen in this code. Which leaves me stuck.
i2c Test Code: i2c Testing.zip
my MPU-6050 Driver that works: MPU-6050.spin (Updated from OBEX Version)
You have:
bmpAddrR = %1110_1110
bmpAddrW = %1110_1111
Yet the reverse should be true. The LSB of the device address distinguishes
between read (1) and write (0) operation, corresponding to address 0xEF (read) and 0xEE (write).
At this stage in your debugging, I'd suggest that you learn everything you can about I2C and one particular device. Then, look at the drivers and see what's happening. I also suggest getting a logic analyzer so that you can see the actual bits being sent. I like the Logic16.
The link provided is another case of someone who could not get anything to work. Don't think you are alone with having trouble with i2c device sanity. In the end it usually comes down to a simple mix of enabling factors, and you are left wondering, what the hey!
I agree with Peter that you may want stiffer pull-ups on your I2C buss with the devices being off-board.
As you may not know Tachyon like Peter does, I wrote a little I2C scanner in Spin (that uses my driver). Running on the PAB the only device address that responds is the boot EEPROM ($A0). You don't have to use the EEPROM buss with my driver; you may specify any two pins.
it started as just bmpAddr = %1110_1110 and was the address found by i2cScanner.
i added separate R & W so i could test them at the same time.
That doesn't work with the driver, because you had defined bmpAddrW as
bmpAddrW = % 1110_1111
That is reverse of what it should be, that final bit sets the i2c for Read rather than for write.
An aside, That particular driver, BASIC_I2C driver does not knock that bit down when it does a write. Although it should, as it defines the xmit=0, but then in the writepage method does this...
ackbit := Write(SCL, devSel | Xmit)
but I think that should be, XMIT = $FE, and...
ackbit := Write(SCL, devSel & XMIT)
You are better off with bmpAddr as you have it with readLocation. The driver takes care of setting the bit high for a Read, and it leaves it low for a Write.
yes, that is how i was able to read the Chip ID (0x55) & coefficents (only part of them), i think i was reading the temp & pressure, but only 3 of the 5 digits. when i held the unit i would see the temp climb, then fall when i let go of it... but pressure, nothing changed that value, and it just bounced around.
You do not have 3v3 next to the Xtal connected (definite no-no)
You don't have bypass caps next to all the prop power pins, or you bring them to one close central point, with one cap. (search the forum for many suggestions/rules - search overclocking)
You don't appear to have bypass caps on the input or output pins of VREG1 (see the datasheets) - they need to be at the pins
In fact, your whole pcb is missing bypass caps at most ICs.
The I2C chips you are using specifically require special considerations, both in layout, and in bypass caps (see their datasheets)
This could explain your problems.
I hope this helps. There are some good app notes put out by some of the chip suppliers (not necessarily from those manufactures you are using).
@Cluso99: Don't start something you can't finish, there are too many things to point out that you may as well design a new pcb in the process Even the placement and designators of the connectors. Now if those with little pcb/hardware experience would post their proposed design to the forum beforehand then the design could be vetted and produced with some confidence.
My mpu-6050 is the ONLY i2c device i have that "works' and does so quite nicely.
SPI devices work 100% (MCP-3208 & RFM23BP (different pcb))
Already on it.. i have 2 newer designs. This one just happens to be on a working ccpm uav prototype that is near completion. Its got a power short as well, my 3.3v reg runs hot (not on new designs). and one of my tracks or joints came loose. it will be replaced very soon, however, this is no reason to not go ahead and finish it, extra parts dangling. Then I will have a crude working model. Still needing altitude / airspeed sensor (2x bmp's) and I would like to get my mpu-9150 working.
Are you intending to send binary values here? If so, why is there no %?
My suggestion would be to start from scratch with one module, re-read the manual and attempt to read just one register only successfully. If you are getting an ack and ID, then you must be addressing the registers incorrectly, that is assuming the device is functioning properly. Bite size chunks.
the reason for the MPU stuff was just a simple test to see if i could get the mpu6050 working on my own (which i cant).
I see i missed a few:
and the results of this code... appears correct-ish. still only getting a maximum of 3 digits on 5 digit values (decimal).
Here is an example
Depends on what gets returned first, lsb or msb. But you get the idea.
I have also tried one straight to the i2c bus (replacing the mpu6050).
As of right now, the one connected to the GPS bus is giving the data back, but it is missing half of all of the values. And I think the problem lies in the read method. it is only doing an 8 bit read when it should be doing a 16 bit read (according to datasheet). but when i use i2c.readregister16, devices are located, but all data is = 0. Now if i switch to "basic_i2c_driver_1.3_Mod" then it will return data.
now i didnt change how the chip id is read because it is only one register location ($D0) so it appears to be still correct.
i also notice there is no " - " sign that was expected in the results. could this be similar to what your saying about the msb / lsb? I was thinking this was were the problem was comming from, but the results are constantly different (with different applications of code) I am not sure which one is correct.
and the main code to this:
and the results of this are as shown:
ok, so I went ahead and tried this:
which is very close to readLocation16's results, but they are all off a bit.
Above Code: readLocation16:
AA AB
AC AD
AE AF