Teensy 3.1, MPU6050 and I2C

Status
Not open for further replies.

Minimoy

Member
Hello everybody,
I'm still working on my quadcopter (adapting the code I wrote for Arduino Due, to a Teensy 3.1 version). I hope you'll be able to help me with the strange problem I discovered today. I was stuck with an incomprehensible problem, for about 4 weeks or even more... Then, today I finally discovered that my code was working perfectly... but not every time... So, I was able to identify where the problem comes from, but I really don't have any idea why this thing could possibly happen.


My problem comes from the I2C. I try to read an MPU6050 chip (to estimate the angles of my quadcopter). As I said earlier, my code works sometimes. It fact it works only just after uploading the code to the Teensy. If I unplug the power, and plug it back, it is impossible to read the sensor anymore. And what is strange is that I don't have any error message like if the device wasn't found on the bus... Thus, to sum up, if I restart the Teensy, I have an I2C error.

Now, I'll try to add as much information as I have for you to help me. I am sure that the MPU6050 board is working properly, because I have no problem using it with my Arduino Due. I also tried to add the 4.7kOhm pull-up resistors to the SDA and SCL pins, as advised on several topics. For the code, I am using the same libraries as for my Arduino Due. I am using Arduino 1.0.5-r2 IDE and TeensyDuino. If I compile with "compile verbose", I get these lines which hold my attention:
D:\Mes documents\Arduino\libraries\I2Cdev\I2Cdev.cpp:64:14: warning: #warning Using current Arduino IDE with Wire library is functionally limiting. [-Wcpp]
D:\Mes documents\Arduino\libraries\I2Cdev\I2Cdev.cpp:65:14: warning: #warning Arduino IDE v1.0.1+ with I2CDEV_BUILTIN_FASTWIRE implementation is recommended. [-Wcpp]
D:\Mes documents\Arduino\libraries\I2Cdev\I2Cdev.cpp:66:14: warning: #warning This I2Cdev implementation does not support: [-Wcpp]
D:\Mes documents\Arduino\libraries\I2Cdev\I2Cdev.cpp:67:14: warning: #warning - Timeout detection (some Wire requests block forever) [-Wcpp]

D:\Google Drive\Temps-libre\Geekeries\Arduino\arduino-1.0.5-r2\libraries\Wire\Wire.cpp: In member function 'uint8_t TwoWire::requestFrom(uint8_t, uint8_t, uint8_t)':
D:\Google Drive\Temps-libre\Geekeries\Arduino\arduino-1.0.5-r2\libraries\Wire\Wire.cpp:345:10: warning: variable 'tmp' set but not used [-Wunused-but-set-variable]


Does anybody have an idea where does this problem come from ? The only idea I have is that maybe I don't have the correct libraries for the Teensy. But if this is not the problem, I am really completely lost.

Thanks in advance for your precious help !
 
Last edited:
Up !
Nobody has any idea about why the I2C can work just after upload, but not after a power restart ?

Any food for thought is appreciated ! And if you need more information, I'll do all my best.
Thanks in advance.
 
I have had trouble with the i2c.h library I used to use, then when I switched to Wire.h all my commo problems with MPU sensors went away. Of course, now I use i2c_t3.h on the Teensy 3.1 with no problems at all. I second the recommendation.

Also, I got some help constructing proper read and write calls. For example,

Code:
 void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.write(data); // Put data in Tx buffer
Wire.endTransmission(); // Send the Tx buffer
}
uint8_t readByte(uint8_t address, uint8_t subAddress)
{
uint8_t data; // `data` will store the register data
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
Wire.requestFrom(address, (uint8_t) 1); // Read one byte from slave register address
data = Wire.read(); // Fill Rx buffer with result
return data; // Return data read from slave register
}
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{
Wire.beginTransmission(address); // Initialize the Tx buffer
Wire.write(subAddress); // Put slave register address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
uint8_t i = 0;
Wire.requestFrom(address, count); // Read bytes from slave register address
while (Wire.available()) {
dest[i++] = Wire.read(); } // Put read results in the Rx buffer
}

works well for the MPU6050 in my sketch kept in this repository.

You might have to change one or two things if you switch to i2c_t3.h.
 
Last edited:
Hmm... I'm not sure I can be of much help here but I have had similar problems with my Teensy3.1 and MPU-6050 (GYU### breakout)
I'm using the i2cdev library https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

My problem almost sounds like the opposite (but maybe just language difference).
*Sometimes* when I would reprogram the Teensy, the MPU would fail to initialize on the next reboot and interrupt void setup.
I never trouble shooted the issue, just put up with the frustration of unplugging and sometime removing the battery!

I can say that the problem has not happened in a long time, and there are two things I suspect may have helped.
- I've added a lot of capacitance to support driving my several Watt LEDs.
- I rarely use any delays in my programs, I felt like delays were a stronger cause of the problem.
- Initially I had a bad solder connection that worked but got worse until it failed completely.

I can also say I don't have the 4.7k resistors (it wired straight to 19,18).

See if you can add a little (or a lot!) capacitance to you master power rails. Maybe 100uF? Maybe less, by comparison I'm working with 5-7 1000uF caps but again this is to suppress feed-back / cross-talk from 4 - 700mA PWM LED drivers. Let us know if you make progress!
 
The GY-521 breakout boards for the MPU6050 have on-board 2k2 pullup resistors typically; additional pullups usually not needed.
 
Thanks a lot for all your ideas!

I'll first try to add a little delay in my init function, because I have none and maybe I try to read the chip to early (and that's why after uploading, the chip has the time to initialize)

If that doesn't help, I'll look at those libraries. I think it is strange, because the code should never work if my library had a problem... But if you had similar issues, maybe that's the solution!

And finally I'll also look at this capacitance idea if nothing works...


I'll test this during the following days, and I'll let you up to date as soon as I have new results! And thanks again for these ideas!
 
non obvious prototype issues

Bypass Capacitors are one of the Very last... Parts added, more often than not to fix problems that seem to have no rational reason for occurring .
The power supply is actually Much More Important than anything else on/in your project...
If the power supply can't supply enough current... The chances that it will work as expected are poor and most frequently are the cause of a circuit not working as hoped..
Consider a Fourier transform of a square wave...
The rise time is of paramount importance.. Fast edges mean very high current
If there is any inductance in series with the power grid.. Like PCB traces or those CHEEP jumper wires..
I measured one and found 29 Ga wire. 7, 40 ga strands of copper IIRC...
I found it by the flicker in a 4 X 20 LCD backlight that had a 5V source for the backlight using a 20 cm long jumper, the ones with the round rubber molded ends.
I measured a .5V drop @ 300 mA.. THis caused me to measure All of the same type jumper wires with my old slow Tek 2213 and these measurements showed .1 to .4V noise differential's @ "Normal" SPI speeds.
I make all my jumpers and cables now from 24 Ga (AWG).. I bought 500 pins the first time and 1K the second time I ordered parts..
A Crimper cost me ~$22.++ and a stripper cost me ~$12.++. Both are available from Electrodragon... both have saved me countless hours of headscratching...
I don't make anything for recommending this "Store".. I just like the variety and price
I buy 1 to 8 pin shells from ElectroDragon as well as the male and female crimp fittings mainly because they are Molex products and 1/2 or more than the price of Tayda's equivalent parts.
After 40 years of electronics engineering for several different companies.. I learned a very simple concept.
Pads and holes on PCB power supplies are not only cheap initially but there is a Big divide between not populating pads/holes in the power distribution circuitry and being forced to add parts later... To Fix improperly designed/improperly tested PCB's... Been there, Done that.. Many years ago, Never again.
C/C++ is most very new to me... But circuit design is something I don't really have to think about.. After 40+ years... it's what I Breath, Eat and Sleep even though I retired in 2008.
It's been my hobby since I was 8 years old (1954) and now more just to keep my mind active..
When I started there were NO ic's or diodes... really. Selenium and Germanium only..
http://www.electrodragon.com/... There are a bunch of relatively inexpensive parts for sale there... check it out.. It's Not the usual Chinese Crap
Pins: http://www.electrodragon.com/product/100pcs-connector-crimps-head-series/
Shells, Single pin: http://www.electrodragon.com/product/100pcs-dupont-prototype-jumper-cable-terminal-end-1-pin/
Shells, multi pin: http://www.electrodragon.com/product/dupont-prototype-jumper-cable-terminal-end-810-pins-20-pcs/
JST shells, pins and headers: http://www.electrodragon.com/product/xh-2-54-pin-header-holder/
 
Last edited:
Hello everybody ! I'm here for the news, and they are really good !
Thanks a lot for your reply Docedison. I had never thought that so "small details" could be so important... I'll pay attention to this from now on. And again, thank you all for your answers and for your long and complete posts !

I'm nearly laughing now, because I finally found the solution and it is pretty simple... In fact just one line is enough to solve the problem... As I expected, the MPU6050 chip seems not to have enough time to initialize before I start communicating with it. So, basically what I did is just add a delay of 100ms and this works ! Nothing else had to be done and now it seems to work every time.

@onehorse and @Headroom, I have a question for you. What is different with the library you suggested ? Because now my software is working, but do you think that if I rewrite my MPU6050 functions with this library, my code would be more robust ? Or maybe run faster ? What are the advantages of this lib ?


Again, thank you, I am so happy to finally find the solution and to be able to keep up developing instead of looking for a solution !
 
In general, if it's working now You may want get the project to a working state first before beginning to optimize.

The i2c_t3 library allows you to utilize the second i2c bus the Teensy 3.x boards have at higher than the 100KHz I2C bus frequency. The MPU6050 allows also to use the 400KHz I2C bus frequency. I am not sure this can be done with the I2C.h
Library or the normal wire library, but the i2c_t3 library can utilize the I2C bus of theTeensy up to 2.4 MHz.

Just follow the link I posted above. The first post in that thread explains the functions in detail and is kept up-to-date by the author of the library nox771.
For the normal I2C stuff the library is also a drop in replacement for the wire.h library.
 
Thanks for your quick reply. As you say, I'll probably wait a little bit before changing all my library. But I keep your link in notes and I'll for sure come back to this later to have something better !

Thanks for all your help !
 
Status
Not open for further replies.
Back
Top