2
\$\begingroup\$

I have a sensor that I'm trying to read via I2C, but I have some issues with the pull-up resistors and what voltage they would be set to.

My host computer is the Arduino Nano Every while my sensor is the HMC5883L magnetometer.

Below is a block diagram showing my wiring scheme.

I did some research on the Nano Every's processor. The I2C pins are connected to the ATMEGA4809, and it is powered at +5V. Thus, the I2C lines are referenced to a voltage of 5 volts. The HMC5883L module has pull-up resistors on it already for both 5V and 3.3V, but if I wanted to add my own external pull-up resistors, then I would have to reference it to 5V as shown in my block diagram, correct? If I decide to reference it to 3.3 volts (and connecting 3.3 volts from the Nano to the corresponding pin on the sensor,) since the microcontroller is running at 5 volts, what voltage should I connect the pull-up resistors to?

schematic

simulate this circuit – Schematic created using CircuitLab

\$\endgroup\$
3
\$\begingroup\$

Thus, the I2C lines are referenced to a voltage of 5 volts

Nope. They are referenced to a GND.

connecting 3.3 volts from the Nano to the corresponding pin on the sensor

Don't do this! The 3.3V on the sensor is an output.

The HMC5883L module has pull-up resistors on it already for both 5V and 3.3V

While they are indeed pull-up resistors, they are also parts of the built-in level shifter, which allows 3.3V sensor to work with 5V I2C bus.

if I wanted to add my own external pull-up resistors, then I would have to reference it to 5V as shown in my block diagram, correct?

There is no reason whatsoever to add anything externally. However if you do want to do it then yes, you can add pull-up resistors to 5V, but then you have to either remove R3, R4 from sensor board or make sure your additional resistors in parallel with them do not go under a minimum allowed resistance (i.e. your combined pull-up is not too strong). For example additional 10k resistors will result in 5k pull-up, which should be OK for 400kHz bus.

If I decide to reference it to 3.3 volts

Again, there is no reason for this, as sensor side of the level shifter is already pulled-up to 3.3V. The MCU side of the shifters is pulled up to 5V. If you have used any 3.3V MCU then you could have removed all 4 resistors (R1-R4) and two MOSFETs, short the SDA and SCL lines for pass-trough, and finally add external pull-up resistors to 3.3V. But since you are using Nano, its MCU is incompatible with 3.3V I2C bus.

UPDATE:

what you connect to VIN will depend on the MCU's I2C logic level?

YES for Adafruit boards, NO in general. The Adafruit boards are designed to be powered from 5V (VIN), using internal regulator to step down to 3.3V, as you mentioned yourself. So, the board is powered by 5V, however the sensor chip on it is powered by 3.3V.

Now, the VIN_min for HMC5883L chip is 2.16V, for LSM9DS1 it is 1.9V. Theoretically, you can power the boards from these voltages + voltage drop on LDO. Does not mean you have to do it. If you want stable predictable behavior I'd recommend powering the boards from 5V where possible. But keep reading...

Thus, 5V from Nano to VIN and my pull-ups.

Your mistake is to think that VIN has anything to do with pull-ups. The I2C bus voltage (where pull-ups should be connected) is often called VDDIO on the schematics. Many chips have separate input pin for VDDIO (e.g. pin 13 of HMC5883L, pins 1 and 3 of LSM9DS1). It is just so happens that Adafruit connected those pins to VDD from LDO on their boards.

Since they connected VDDIO to internal 3.3V regulator, they could not let you apply higher voltage to sensor I2C pins. So they added level shifters to their boards, with pull-ups to 3.3V on sensor side and pull-ups to VIN on the connector side. This in turn fixed external I2C bus voltage to VIN. So, in this case the VIN does define the bus voltage, but only because Adafruit engineers wired the boards this way.

To summarize:

  • If you are not prepared to hack sensor boards to bypass level shifters you are stuck with their pull-ups, which means external (i.e. connected to MCU) I2C bus voltage will be always equal to VIN.
  • Therefore you should supply VIN with I/O logic level of your MCU. Or 5V in case of Nano, 3.3V in case of Portenta.
  • There is no reason to add any external pull-ups, unless you experience communication errors at 400kHz. Then you can connect external pull-ups to VIN, but try not to go below 10k.
\$\endgroup\$
3
  • \$\begingroup\$ If I may, I'm still lost. Looking at other modules like the LSM9DS1, they have a regulator to step down to 3.3V. Wiring diagram says to connect VIN to 5V or 3.3V. So, in that case, what you connect to VIN will depend on the MCU's I2C logic level? So, with the Nano, it operates at 5V. Thus, 5V from Nano to VIN and my pull-ups. However, say with Portenta H7, operates at 3.3V, 3.3V from Portenta to VIN is the right way to wire it, right? What if you ran 5V from the portenta instead? \$\endgroup\$ Sep 23 at 20:07
  • \$\begingroup\$ @BestQualityVacuum see an update. \$\endgroup\$
    – Maple
    Sep 23 at 21:31
  • \$\begingroup\$ Thanks for the update. Very crystal clear. So, depending on MCU, hook up appropriate voltage to VIN, and only use 3V3 on sensor for output. Got it. Boy I really messed up. \$\endgroup\$ Sep 23 at 21:49
3
\$\begingroup\$

The folks at Adafruit have thought of this for you. If you go to the Adafruit site you linked to for the HMC5883L, they tell you this about the SDA and SCL lines for I2C:

enter image description here

So my interpretation of this is that you can use external pullup resistors to 5V.

The Atmega, on the other hand, has digital high defined as such by the datasheet:

enter image description here

With 5V source, 0.7*VDD is 3.5 V. So your 3.3 V will not register as a high voltage, causing the I2C not to work. So you will need to use 5V for the I2C pullup.

\$\endgroup\$
2
\$\begingroup\$

The controller has an IO-voltage of 5V. It might run with a 3V3 I2C bus, but you'd better stick to 5V. Just use the internal 5V I2C pullups of the sensor board.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.