Skip to content

Commit d05ed75

Browse files
committed
add section about arduino external pull up config
1 parent 4c96808 commit d05ed75

5 files changed

+61
-6
lines changed

i2c-pull-up-resistors-intro.md

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ advisable to check the pull-up resistor configuration.
1313
Where can pull-up resistors be placed:
1414

1515
1. On the development board you are connecting.
16-
2. On the microcontroller.
17-
3. Manually wired on the SDA and SCL lines between the microcontroller and development board, for example, by using a
16+
2. On the micro-controller.
17+
3. Manually wired on the SDA and SCL lines between the micro-controller and development board, for example, by using a
1818
breadboard.
1919

20-
So if your development board or microcontroller has pull-ups built-in, you should be good to go.
20+
So if your development board or micro-controller has pull-ups built-in, you should be good to go.
2121
For example, the ESP32 DevKit 4 has pull-ups built-in, but the STM32 Nucleo does not.
2222

2323
Pull-up resistors are connected from the SDA and SCL lines to the positive supply voltage. Standard resistor values are
2424
4.7 kΩ or 10 kΩ. You may also find an optimal pull-up resistor value for your sensor in the sensor or development board
25-
datasheet.
25+
data sheet.
2626

27-
If there are pull-up resistors on both the board and the microcontroller, the pull-up resistances are in parallel,
27+
If there are pull-up resistors on both the board and the micro-controller, the pull-up resistances are in parallel,
2828
resulting in a lower overall value. This could potentially lead to a pull-up resistance that is too small, causing your
2929
devices to fail to drive the lines to the low level reliably.
3030

@@ -55,4 +55,59 @@ Trace of setup with 2.2kOhm resistors:
5555
reach the maximum voltage anymore (the maximum voltage reached in the trace during communication is approximately 3.1V).
5656

5757
Trace of setup with 18kOhm resistors:
58-
![LogicAnalyzer Snapshot with 18kOhm resistors](images/Nucleo64_I2c_18kOhm_PullUps.png)
58+
![LogicAnalyzer Snapshot with 18kOhm resistors](images/Nucleo64_I2c_18kOhm_PullUps.png)
59+
60+
# Arduino boards
61+
62+
Most of the Arduino boards do have pull-up resistors on the board which will be activated on the I2C pins when you call
63+
`Wire.begin()`. Those have however a high resistance value and are not appropriate for all setups. The internal pull-ups
64+
are likely too weak to recover the line fast enough to a high state, especially with faster I2C bus frequencies than
65+
the default of 100kHz. If pull ups are too weak, it might lead to unreliable or no communication over I2C.
66+
67+
68+
With the internal pull-ups and 100kHz, I2C communication is working. The I2C signal is however not very good as there
69+
is no plateau on the high state, but rise time is still fast enough with 100kHz.
70+
71+
![ArduinoNano_InternalPullUps_100kHz_working](images/ArduinoNano_InternalPullUps_100kHz_working.png)
72+
73+
If we switch to 400kHz, we cannot communicate anymore if the internal pull-ups are turned on. No signal was detected
74+
anymore at all. You see in the screen shot above that if the clock speed would be 4 times faster, signal would have
75+
to be on high state within the reddish box - which is far from 3V.
76+
77+
To solve the problem, you need to deactivate the internal pull up resistors and connect external pull up resistors.
78+
Deactivating the internal pull up resistors is done in the code. Make sure to have those calls after the `Wire.begin()`,
79+
as the begin configures the I2C pins to INPUT_PULLUP. Same is true for the I2C clock, you have to configure it after
80+
the call to begin, as otherwise it will overwrite it with the default of 100kHz.
81+
82+
The code below was tested on a Arduino Nano. It turns off the internal pull ups and configures I2C fast mode with 400kHz
83+
bus frequency. For other boards, you might need to adapt the pin names (here A4, A5).
84+
85+
```
86+
Wire.begin();
87+
Wire.setClock(400000L);
88+
pinMode(A4, INPUT);
89+
pinMode(A5, INPUT);
90+
```
91+
92+
Choosing the correct pull-up resistor value is important. Further, short cables are also important for a good I2C signal,
93+
as the capacitance of the cable also influences the rise time.
94+
95+
For an example how to wire external pull ups between SDA respectively SCL and VDD using a bread board please check out
96+
the examples in the [README](README.md).
97+
98+
Following screenshots show the decrease in I2C signal quality depending on resistor values.
99+
You can see that with the strong pull-up with 2.2kOhm resistor the signal looks quite rectangular.
100+
With 8.3kOhm the pull-up is still just strong enough, but the signal has no plateau anymore.
101+
Resistors of 18kOhm are too weak to pull-up the line fast enough into high state and the communication is not working anymore.
102+
103+
I2C bus frequency 400kHz, external pull-up resistors 2.2kOhm, good signal, communication is working:
104+
105+
![I2C bus frequency 400kHz, external pull-up resistors 2.2kOhm](images/ArduinoNano_External2.2kOhm_400kHz_working.png)
106+
107+
I2C bus frequency 400kHz, external pull-up resistors 8.3kOhm, weak signal, communication is working:
108+
109+
![I2C bus frequency 400kHz, external pull-up resistors 8.3kOhm](images/ArduinoNano_External8.3kOhm_400Hz_working.png)
110+
111+
I2C bus frequency 400kHz, external pull-up resistors 18kOhm, signal does not recover to high state, communication is **not** working:
112+
113+
![I2C bus frequency 400kHz, external pull-up resistors 18kOhm](images/ArduinoNano_External18kOhm_400kHz_not_working.png)
84 KB
Loading
84.9 KB
Loading
85.9 KB
Loading
81.7 KB
Loading

0 commit comments

Comments
 (0)