Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 23 of 23

Thread: Teensy LC - MPU6050 I2C. How to pullup +3.3V?

  1. #1
    Junior Member
    Join Date
    Nov 2017
    Posts
    9

    Teensy LC - MPU6050 I2C. How to pullup +3.3V?

    Hello,
    I recently switched from an Arduino UNO to a Teensy LC for my project which makes use of the MPU6050 accelerometer. After some testing I realized that the output of the sensor is very inconsistent when using the teensy (I tested this with a default example sketch), the same sensor works fine with the Arduino.

    So I went back to pjrc and found following quote (regarding I2C communication):
    "Teensy LC & 3.0-3.6 requires pullup resistors to +3.3V. The on-chip pullups are not used. 4.7K resistors are recommended for most applications."

    Thats probably what I'm missing but I'm a bit confused. First of all, what exactly is a pullup resister? Is it a part I have to buy? Can I build one my own using resistors? I looked it up and (I think) I understand what they are needed for but in the past I simply hooked pins that needed a pullup to ground, which feels kinda wrong to do on a +3.3V pin.

    Apart from that I'm powering my circuit with that pin... so yeah I'm lost.
    Hope somebody can explain this to me (preferebaly as if I'm 5 ).

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    There are a lot of good references on Pull-up or Pull-down resistors on the web. Example: https://learn.sparkfun.com/tutorials/pull-up-resistors

    With I2C, especially with the data line (SDA), you may have several components on the line that will try to control the output level (high or low).
    To put it simply, with nothing else driving the circuits you need some default voltage on it. In these cases you need a 3.3v signal on the line.
    So you connect a resistor connected to the SDA data pin and to a +3.3v pin. This will drive the circuit to high when nothing else is driving it low.
    The value of the resistor is a trade off between, how much current runs through it when you drive the circuit low versus how long it takes for the power to run through it to drive the IO pins level high again. And on a 3.3v circuit 4.7k appears to work well.

    May I2C devices already have a PULL up resistor on them. Often in the range of 10K. But sometimes you need an external one to get the right values, and you can use most any type of resistors. On circuit boards I mostly use surface mounted resistors, but for quick hook ups I use some through the hole types. I have several sitting around, but for ease of use, I have a set of them near by: https://www.sparkfun.com/products/10969

  3. #3
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Thanks alot. I totaly misundertood that one at the first place, things are much clearer now. Unfortunately I still get inconsistent results from the sensor. I added a picture of my setup, maybe I did something wrong. Since I didn't had a 4.7k resistor laying around I chained 2k, 2k, 330, 330, 10, 10, 10 and 10 resistors.
    Click image for larger version. 

Name:	IMG_1796.jpg 
Views:	77 
Size:	123.9 KB 
ID:	12118

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    The 4.7k is a ballpark value... You were probably fine with just the 4K... A lot of setups just use a 10K but that is usually better for 5v systems.

    Might help others if you mentioned which library and exact code you are using. Also maybe a link to the actual board you have.

    The inconsistent results could be due to several things, like the Pull up resistors you mentioned, but also timing.

  5. #5
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,588
    what is the vendor/part number for your MPU6050. From your photo, I think the MPU breakout has onboard pullups (as do most breakout boards for I2c devices), so you may not need to add any external pullups. The other issue is power. if you have been testing with UNO, that is 5v based, so the breakout may or may not require 5v. If breakout requires 5v, that may not be good for your LC. Hopefully, you haven't hooked up any 5v devices to your LC.

    see discussion of GY-521 breakout at https://playground.arduino.cc/Main/MPU-6050
    Last edited by manitou; 11-29-2017 at 04:43 PM.

  6. #6

  7. #7
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,588
    Quote Originally Posted by shanreteid View Post

    The MPU6050 has GY-521 printed on the backside.
    The discussion at https://playground.arduino.cc/Main/MPU-6050 suggests powering the GY-521 with 5v. To be safe you could first just hook up 5v and GND to the breakout (no other wires from the LC), and then with voltmeter, measure the voltage on the SDA and SCL breakout pins. If it shows 3.3v, you are safe to hook the I2C wires to the LC and run your sketch. The schematic http://playground.arduino.cc/uploads...050-V1-SCH.jpg shows pullups to 3.3v on the breakout, so you shouldn't need any other pullups.

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    So it maybe is this unit? https://www.amazon.com/MPU-6050-MPU6.../dp/B008BOPN40

    And if you look at the GY-521 section of the Playgound post it mentions:
    This sensor board has a voltage regulator. When using 3.3V to the VCC the resulting voltage (after the onboard voltage regulator) might be too low for a good working I2C bus. It is preferred to apply 5V to the VCC pin of the sensor board. The board has pull-up resistors on the I2C-bus. The value of those pull-up resistors are sometimes 10k and sometimes 2k2. The 2k2 is rather low. If it is combined with other sensor board which have also pull-up resistors, the total pull-up impedance might be too low.
    Some GY-521 modules have the wrong capacitor (or a bad capacitor) and that result

  9. #9
    Senior Member
    Join Date
    Feb 2017
    Posts
    174
    If your sensor is happier with 5V, you can use this bi-directional level shifter to connect I2C to Teensy at 3.3V:
    https://www.adafruit.com/product/757

  10. #10
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    1,909
    On the picture in post #3, I’m seeing only one pull-up resistor while 2 are needed for I2C, one on the data line and one on the clock line. You might use an oscilloscope to check the signal quality and to adapt the resistance depending on the I2C transmission rate, wire length and parasitic capacitances.

  11. #11
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Thanks for all the answers,
    I dont have a level-shifter neither a multimeter at hand to properly test this atm. I'll check it tomorrow at university and report back here after that.

  12. #12
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,588
    Quote Originally Posted by shanreteid View Post
    Thanks for all the answers,
    I dont have a level-shifter neither a multimeter at hand to properly test this atm. I'll check it tomorrow at university and report back here after that.
    You can use your UNO as a voltmeter. Power the MPU breakout with 5v/grnd from UNO, then jumper breakout's I2C pins to A0 and A1 on UNO, and run a little sketch to print values of analogRead() for A0 and A1. Values around 675 would indicate 3v3, values of 1023 would mean 5v from breakout's SDA and SCL pins

    FYI, here is some I2C pullup info with scope tests of different pullup resistances:
    http://www.gammon.com.au/i2c

  13. #13
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Quote Originally Posted by manitou View Post
    You can use your UNO as a voltmeter.
    Great idea thanks! The values were exactly around 675.
    So I hooked up the sensor to the 5V pin now but the results are still wrong (with or without the external pullup).

    I actually didn't expected the libary to be the problem (since it works fine on my UNO) but I will see if I can find a different one and try it out.

  14. #14
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,588
    take a look at Kris's library https://github.com/kriswiner/MPU6050
    Last edited by manitou; 12-02-2017 at 11:22 AM.

  15. #15
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Quote Originally Posted by manitou View Post
    take a look at Kris's library https://github.com/kriswiner/MPU6050
    I did a quick test but only got 0s for pitch, roll and yaw. I will investigate more tomorrow, I'm done for today.

  16. #16
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Ok I've done some more testing on the UNO now. It appears that the sensor will not work without external pullup on sda and scl if powered with 5V. I read A4 and A5 of the UNO while the program was running and the results were 699 using 10k pullup resistor (~800 with 4k resistor). That should be around 3.4V right? Would this be save to try on the Teensy or do I really need a level-shifter here? I have no experience with those.

    Edit: Kris's libary is a little bit to advanced for my purpose (atm) and I figured that the one from jarzebski does basicly the same at it's core part.
    Last edited by shanreteid; 12-01-2017 at 01:48 AM.

  17. #17
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,588
    So you are saying the sensor will not work running from the UNO without additional pullup resistors? And it used to work OK from the UNO with no additional pullups?

    Your UNO "voltmeter" tests seemed to indicate that the sensor breakout when powered with 5v has pullups to 3.3v. The schematic from the playground URL indicates that the breakout has a voltage regulator to convert 5v to 3.3v and that there are 4.7K pullups to 3.3v on SDA and SCL lines. You could experiment with adding additional pullups to SDA and SCL (as noted in post #10, you need to have pullups resistors for BOTH SDA and SCL). I would try smaller resistance, say 2.2K ohm. Power the sensor with 5v, but the pullups should attach to 3.3v (the MPU is 3.3v device).

    I have only worked with the newer MPU9250

  18. #18
    Senior Member
    Join Date
    Jan 2013
    Location
    San Francisco Bay Area
    Posts
    641
    I've likely used that same MPU6050 breakout board. I got 10 of them off of ebay once.
    https://www.ebay.com/itm/MPU-6050-6D...wAAOSwDwtUm4WP

    I had no problems running it off of 3.3V, although it may have shared the i2c bus with another sensor that probably had 10k pull-up resistor.

    But I'm pretty sure I tested first w/o anything else connected. I don't think you need any other additional pull-up resistors.

    If you are using i2c_t3, you might want to slow the i2c bus down.

  19. #19
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Quote Originally Posted by linuxgeek View Post
    If you are using i2c_t3, you might want to slow the i2c bus down.
    I switched to i2c_t3 now and tried a rate of 100khz and 50khz, the results were still off and the program froze after a few moments. I also tried to set different pins for SDA and SCL (22 & 23 or 16 & 17) but the sketch seems to crash somewhere in the setup method when I do that.

    Since I haven't broken a board yet (afaik) I can't really tell if this behaviour may indicate that something is wrong with my Teensy. I'd expect that the board wouldn't do anything at all if broken to be honest. I actually consider to order myself another Teensy just to check.

  20. #20
    Senior Member
    Join Date
    Jan 2013
    Location
    San Francisco Bay Area
    Posts
    641
    Did you setup i2c_t3 with the I2C_PULLUP_EXT in the begin function?

    I'll try and post a simple sketch later. I might have done more of my testing on 3.2, but I'll try it on LC.

    I doubt there is anything wrong with the breakout board or the LC.

    Also, I've bought some cheap breadboards that were a mess internally and creating lots of problems, so you might want to consider that.
    Last edited by linuxgeek; 12-01-2017 at 08:47 PM.

  21. #21
    Senior Member
    Join Date
    Jan 2013
    Location
    San Francisco Bay Area
    Posts
    641
    Well, I must've forgotten how I wired it. It definitely doesn't work as-is. For testing, look under i2c_t3 menu for the "basic_scanner" sketch. It checks all i2c addresses for an acknowledgement.

    It didn't find anything with the mpu6050 board hooked up. I plugged in another i2c board and it came up. I'll test with some other resistors and see if it comes up.

    Also, remember to wire ADO to GND.

    I bet if you wired 2 of them up it would work. ADO->GND for one, and ADO->3.3V (not sure if that's need to be with a resistor) for the other.

  22. #22
    Senior Member
    Join Date
    Jan 2013
    Location
    San Francisco Bay Area
    Posts
    641
    Ok, just wired up a 2k ohm resistor to 3.3V on SCL and SDA pins. You need a 2k resistor for the SCL pin to 3.3V, and you need another 2k resistor for the SDA pin to 3.3V. Then it came up, and this with a T-LC.

    I just used the 3.3V pin on T-LC to power the MPU6050 board. No 5V needed.

    BTW, the board has 2.2k resistors for pull-ups already, so you need a little more. If you have 2 breakout boards, it would probably be fine.

    Here's my basic code:
    Code:
    #include <i2c_t3.h>
    
    #define MPU6050         3
    
    #ifdef MPU6050
      //3 values, 2 bytes
      uint8_t mpuBytes[3*2];
      int16_t mpuAcXTmp, mpuAcYTmp, mpuAcZTmp;
      int32_t mpuAcX, mpuAcY, mpuAcZ;
    #endif
    
    struct i2cConfig {
      uint32_t clock;     // I2C clock frequency
      uint8_t port;       // I2C bus number
      i2c_pins pins;      // I2C pins
      i2c_pullup pullups; // I2C pullups
      uint8_t address;    // I2C address
    };
    
    #ifdef MPU6050
    struct mpu6050Config {
      char signalName[8];
      uint8_t sampleDivisor = 1;
      uint8_t sensorType = MPU6050;
      uint8_t ID = 0x68;
      uint8_t numSensor=1;
      i2cConfig i2c;
    };
    #endif
    
    #ifdef MPU6050
      mpu6050Config mpu6050Cfg;
    #endif
    
    void setup() {
      while (!Serial && (millis () <= 3000));
      Serial.begin(9600);
      for (int i=0;i<5;i++) {
        Serial.println(i);
        delay(500);
      }
      
     #ifdef MPU6050
        mpu6050Cfg.i2c.port=0;
        mpu6050Cfg.i2c.address=0x68;
        mpu6050Cfg.numSensor=1;
     #endif
    
    Serial.println("setup1");
    i2c_t3(mpu6050Cfg.i2c.port).begin(I2C_MASTER, 0x00, I2C_PINS_16_17, I2C_PULLUP_EXT, I2C_RATE_100); //tLC
    //  i2c_t3(mpu6050Cfg.i2c.port).begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_100); //3.2
    
    Serial.println("setup2");
      #ifdef MPU6050
    //    mpu6050Init(&mpu6050Cfg);
      #endif
    
     writeByteWire(0, 0x68, 0x6B, 0);
    
    Serial.println("setup3");
    }
    
    void loop() {
     #ifdef MPU6050
          readMPU6050(mpu6050Cfg.i2c.port,mpu6050Cfg.i2c.address,&mpuBytes[0]);
          mpuAcXTmp = mpuBytes[0]<<8|mpuBytes[1];
          mpuAcYTmp = mpuBytes[2]<<8|mpuBytes[3];
          mpuAcZTmp = mpuBytes[4]<<8|mpuBytes[5];
          mpuAcX = mpuAcXTmp;
          mpuAcY = mpuAcYTmp;
          mpuAcZ = mpuAcZTmp;
      #endif
    
      Serial.print(mpuAcX);
      Serial.print(",");
      Serial.print(mpuAcY);
      Serial.print(",");
      Serial.print(mpuAcZ);
      Serial.println();
      delay(100);
    }
    
    void readMPU6050(uint8_t i2cPort, uint8_t i2cAddress, uint8_t *dest) {
        readBytesWire(i2cPort, i2cAddress, 0X3B, (3*2), dest);
    }
    
    #ifdef MPU6050
    void mpu6050Init(struct mpu6050Config *cfg) {
          writeByteWire(cfg->i2c.port, cfg->i2c.address, 0x6B, 0);
    }
    #endif
    
    /*
    * read a chunk of data from sensor
    */
    void readBytesWire(uint8_t i2cPort, uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) {  
      i2c_t3(i2cPort).beginTransmission(address);   // Initialize the Tx buffer
      i2c_t3(i2cPort).write(subAddress);            // Put slave register address in Tx buffer
      i2c_t3(i2cPort).endTransmission(I2C_NOSTOP);  // Send the Tx buffer, but send a restart to keep connection alive
      i2c_t3(i2cPort).requestFrom(address, (size_t) count);  // Read bytes from slave register addr`ess 
      for (int i=0;i2c_t3(i2cPort).available();i++) {
        dest[i] = i2c_t3(i2cPort).read();
      }
    }
    
    /**
    * write data to sensor
    */
    void writeByteWire(uint8_t port, uint8_t address, uint8_t subAddress, uint8_t data) {
      i2c_t3(port).beginTransmission(address);  // Initialize the Tx buffer
      i2c_t3(port).write(subAddress);           // Put slave register address in Tx buffer
      i2c_t3(port).write(data);                 // Put data in Tx buffer
      i2c_t3(port).endTransmission();           // Send the Tx buffer
    }
    Last edited by linuxgeek; 12-02-2017 at 12:07 AM. Reason: extra info

  23. #23
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Huge thanks linuxgeek! I wired it the way you did and it works with your sketch. It still doesn't work with the lib I was using before though, so that was probably the cause of all trouble...

    I actually tried to change the lib using i2c_t3 instead of Wire but the sensor keeps giving wrong results no matter what. Not sure whats different there since the lib works fine on my UNO and everything looks right as far as I can tell.

    For anyone interested, these are the only changes I made:
    Code:
    #include <i2c_t3.h> // instead of #include <Wire.h>
    #include <math.h>
    
    #include <MPU6050.h>
    
    bool MPU6050::begin(mpu6050_dps_t scale, mpu6050_range_t range, int mpua)
    {
        // Set Address
        mpuAddress = mpua;
    
        Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_100); // instead of Wire.begin()
    I linked the rest of the libary aswell as the test sketch in post #6.

    For now I wont bother to find out why this lib doesn't work and rather write my own simple one.
    Again thanks to everyone who helped me tracking this down, I learned quite a bit during the process.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •