10
\$\begingroup\$

I'm trying to understand why placing resistors between Vcc and the data/clock lines helps my waveform be square, when I'm communicating between Arduino and an EEPROM chip. If resistors are not placed in the circuit, the waves look like shark fins. The circuit still functions, but they're definitely odd-looking waves.

For background, this question arose after wiring up an Arduino to a Microchip 24LC256 (EEPROM) using I2C. Upon inspecting the signals with my oscilloscope (trying to debug something unrelated) I noticed the waves looked, well, horrible. They looked like shark fins to me (is there a more accepted EE phrase for this?). I checked several times to make sure my probe scopes were tuned/compensated correctly, and verified I didn't get such behavior on other circuits. This is what the wiring looked like:

Original wiring setup

Yellow signal is the SDA line and Blue is SCL

In a chance conversation I told an EE about this -- and they said this isn't uncommon for I2C. He recommended putting a 10k Ohm resistor between Vcc to SCL, and trying a lower resistor between Vcc and SDA. Additionally he recommended reducing the I2C speed to the lowest setting (31KHz for Uno). Sure enough if I put a 10k resistor between Vcc/SCL and a 4.7k resistor between Vcc/SDA -- they look nice and square. I also lowered the speed from normal down to 31KHz but that made a much smaller (if any) impact.

Unfortunately I never got a chance to ask why! I'm a noob to electronics but I'm very curious why a resistor placed like this causes them to be better looking square waves? This photo below is after using resistors, but before picking the 'optimal' resistor values for the best looking square waves. I think it looks much better.

enter image description here

I looked for explanations on Stack Exchange but to no avail. These seemed (potentially) similar to my issue: Problem with I2C EEPROM communication (his waves look similar to what mine looked like, but the answer didn't address my question) I2C interfacing between two chips (this one also seemed fairly promising but didn't dig into the "why") Strange I2C signals emitted from FPGA (this seemed related to something else... though similar in that her waves look "ugly")

Thanks for the help!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Long story short (and oversimplified): it's supposed to be square and it's the lack of resistor that was causing it to be non-square. Or actually, the resistance was too high and the extra resistance lowered it (because parallel) far enough to fix the rise time. Look into RC times. \$\endgroup\$
    – Mast
    Commented Jul 16, 2018 at 6:02

2 Answers 2

12
\$\begingroup\$

I2C is a bus that uses open drain outputs. An open drain is like a switch connected between the output and ground. It will not work without pullup resistors because there is nothing to make it go high.

If the pullup resistors are too high in value it won't work (or won't work reliably) because the resistor won't charge the capacitance of the inputs, the output, the wire and maybe a scope probe fast enough. If they are too low then the output won't be strong enough to pull it down.

You notice that on your scope measurement the outputs go low very quickly but are sluggish to rise to logic level 1.

If the code on your Arduino is using the internal pullup resistors on the ATMega to bit-bang an I2C interface then they are probably too high in value (tens of K ohms, and not well-specified) to work reliably, so they need to be paralleled with external resistors.

Personally, I would have written the code to not use the internal pullups (by default) to avoid the situation of the bus "almost" not working, and force the user to use the resistors or deliberately choose to use the internal ones. It's possible they're acceptable if the chips are very close together, low speed (100K) is used and no scope probes (especially in x1) are attached.

I've seen a very similar situation occur where 47K resistor networks were accidentally installed rather than 4.7K.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thanks Spehro, this is very helpful. I'm not sure if the "wire" library on the Arduino makes use of the internal pull-up resistors by default, but I'm not doing anything explicit in my code to utilize them. I agree that I'd rather have those resistors chosen deliberately rather than relying on it in code. Might help prevent such situations as these. Sorry, one quick follow-up question: Why would having scope probes (esp in x1) impact that? \$\endgroup\$
    – Thomas
    Commented Jul 15, 2018 at 18:32
  • \$\begingroup\$ Scope probes in x1 mode add maybe 30-40pF to the capacitance, which can more than double what is already there due to the other factors. In x10 the added load is more like 1/10 of that. \$\endgroup\$ Commented Jul 15, 2018 at 18:45
5
\$\begingroup\$

I2C is not supposed to work at all without pull-up resistors; they are explicitly required in the design of the bus.

So in effect, your question is moot - do it wrong, and bad things happen.

If you really want to understand exactly what is happening it is likely that you are getting some kind of weak pull-up effect from a leakage current or possibly even an internal pullup resistor that is around 10 times larger than the I2C bus resistor should be. This causes that exponential RC rising waveform - the classic one of a capacitor charging through a resistor. With a proper value pull-up resistor it still happens, but quickly enough that the exponential looks vertical on the scope.

Whatever current source is bringing the line high in the absence of a true pull-up resistor, it is weak (ie, the circuit is very high-impedance) so it is also extreme susceptible to capacitive coupling from the clock line, hence you see the tops of the data line waveform showing artifacts when the clock switches.

Use the required pull-up resistors. Put a supply bypass capacitor across your chip. Keep wiring runs as short as possible. Follow the rules, and you avoid the problems that characteristically come from breaking them.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks, Chris. I suppose this is a danger of blindly following an online tutorial where pull-up resistors are not used. Thank you for the explanation (and yes, I did want to know what the underlying reason was for what was happening). \$\endgroup\$
    – Thomas
    Commented Jul 15, 2018 at 18:17
  • \$\begingroup\$ @Thomas - unfortunately, the world of online Arduino tutorials is as much a collection of what not to do as what one should - including even some of the official ones from Arduino. That's not to say they can't be useful, but you often have to wade through and reject three or four bad ones to find something that actually works and usefully exercises whatever chip it was hoped pulling out an Arduino could help quickly evaluate. \$\endgroup\$ Commented Jul 15, 2018 at 18:19

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