It happened to be that I run out of pins on ATmega48PA. So I have a pull-down buttons on the pins dedicated for I2C:

enter image description here enter image description here

And now I need to add I2C bus to this device with as much backward compatibility as possibe.

The thing I'm going to implement is to keep buttons as it is with I2C devices on these ping as there are no buttons at all. And I hopefully will have both working.

By saying this I mean the following schematic:

enter image description here

Why am I so sure?

  1. Both I2C and buttons works as "pull low" logic. So there will be no conflicting outputs with excess currents.
  2. My controller will be I2C master. So I will be able to switch pins to GPIO mode, read the buttons ad go back again to I2C mode after that. Or do it vice versa: switch pins to I2C mode when I2C interaction will be needed.

The only thing I will not be able to avoid is that I2C bus become unusable while any button is pressed. I think I can deal with it.

The second thing I am afraiding of is that the button press can be treated by slave as I2C transmission and it will stuck with this wrong data. My only hope is that the slave will "forget" all wrong bits and it will not influence on the further communication.

So my questions is: does anyone experienced with such weird schematic? Did it work?

  • 1
    \$\begingroup\$ What is your slave I2C device or devices? \$\endgroup\$
    – vini_i
    Commented Apr 18, 2019 at 12:33
  • \$\begingroup\$ @vini_i it will be TMP006 temperature sensor. \$\endgroup\$ Commented Apr 18, 2019 at 12:45
  • \$\begingroup\$ How often do you poll it? \$\endgroup\$
    – vini_i
    Commented Apr 18, 2019 at 12:46
  • \$\begingroup\$ @vini_i one a second or so. \$\endgroup\$ Commented Apr 18, 2019 at 12:52
  • \$\begingroup\$ Any reason for such a high update rate? Temperature doesn't often fluctuate quickly enough to necessitate such a rate. Would a 30 or 60 second update be sufficient? \$\endgroup\$
    – vini_i
    Commented Apr 18, 2019 at 12:55

2 Answers 2


Slaves do not always react well to illegal I2C traffic. They should be able to recover from it, but in fact some do not. I have seen slaves lock up after receiving a simple Start-Stop with no traffic in between. Interrupting ongoing I2C traffic can be potentially even more dangerous. So, do not do this unless you know that the slaves can recover from every possible illegal I2C transaction that may be thrown at them. This includes throwing away any partial data that they might get if the transaction is interrupted.

Additionally, make sure that the master can properly sense a button press. If the master supports clock stretching, you cannot use this scheme because a button press may be perceived as clock stretching. A button press could also be perceived as an ACK from the slave; consider what would happen under this circumstance.

Also, if the SDA button was pressed during a long period of 0s being sent, the button press could be missed by the controller.

This scheme is best avoided unless there is absolutely nothing else to do.


It should work as you expect (with caveats). As you pointed out, I2C has the benefit that it is active low and recessive high (it signals by pulling a line to ground against a pull-up resistor). This has the benefit that even chips running at different supply voltages can signal each other on the same bus without issue, so long as the I2C peripheral pins on both devices can support either voltage and both devices share the same 0V (GND) reference. However, like you pointed out, a user pushing either button during an I2C transaction can and will generate data loss or data corruption (it could also halt/hang your chip depending on how I2C fault handling is implemented). If your application is robust to that, maybe it's not an issue.

I would only have the small suggestion that a lower pull-up resistor value might be more typical, say 3.3k instead of the 10k you currently have. If only certain boards will need the I2C function and not the buttons, you could always just mark the buttons DNP (do not place) when assembling that board variant.

Edit 1

One more quick note. In firmware, you may need to write code that manages the process of re-configuring the pins from I2C alternate function versus GPIO function and disabling the I2C peripheral clock. To do that, you would have to know somehow in your application when you want to switch from one mode to the other.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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