Why does putting resistors between Vcc/SDA & Vcc/SCL in I2C result in a square wave?

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.


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.