I want to get and change the I²C address of MCP4728 chip. To do this, one has to coordinate I²C communication with another LDAC pin register. After posting the question here, Reading and writing with smbus package, I have realised that the only way to do that is by I²C bit-banging.

The part with I²C communication protocol is easy, as there is plenty of documentation and examples on Internet. However, there is scarce (if any) documentation on Internet about the rest. I therefore decided to start a new question.

  1. How can one bit-bang using Python?

  2. How can one use arbitrary GPIO in open drain mode using Python?

Theoretically, both is achieved by fixing GPIO state to a fixed False and toggle the output enable switch/output register.

Please provide a link to documentation/example or add your own example. It is desirable that as few as possible GPIO libraries are used. Embedding C (if this is the only reasonable solution) is also a possibility.

Thanks a lot!


The problem is finally solved. You can find the library with read/update I2C address for MCP4728 on http://www.pinteric.com/raspberry.html#dac


1) Bit banging just means using software rather than hardware to implement a communications protocol. To bit bang I2C this means to control the SDA and SCL signals in software. SDA is connected to GPIO 2 (pin 3), SCL is connected to GPIO 3 (pin 5). Generally to bit bang you need to set the GPIO high (write 1) or low (write 0). All the Pi GPIO libraries support such control of the GPIO.

2) The Pi GPIO do not have an open drain mode. Fortunately it is easy to simulate for the I2C protocol as the protocol requires pull-up resistors to Vcc to be present.

To simulate open drain

  • to signal low set the GPIO to be an OUTPUT and write 0 to the GPIO.
  • to signal high set the GPIO to be an INPUT (the GPIO will float high to the pull-up, unless overridden by another bus device).
| improve this answer | |
  • I am a bit worried about the possibility that after switching GPIO to OUTPUT mode (for the first time or between signal changes) it might be True for a few milliseconds and damage either chip or Raspberry Pi. – Pygmalion Feb 12 '18 at 18:10
  • I know pigpio sets the level before changing the mode (behind the scenes). You can do the same with RPi.GPIO as you can specify a level when you set the mode to OUTPUT. You would need to check yourself the behaviour of RPIO.GPIO and the wiringPi Python module. – joan Feb 12 '18 at 18:16
  • If I understand you right RPi.GPIO.setup(channel, GPIO.OUT, initial=GPIO.LOW) is safe. One funny question though - would be using internal pull-up resistor RPi.GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP) without using external pull-up command be OK? – Pygmalion Feb 12 '18 at 18:37
  • There is no external pull-up command. Do you mean would the I2C bus work just using the internal pull-ups? I.e. do you want to bit bang on GPIO other than 2 and 3 which have external pull-ups fitted? – joan Feb 12 '18 at 18:43
  • I am sorry for the typo (external pull-up command=external pull-up resistor). Yes, that was my idea, to use arbitrary GPIOs and use internal pull-ups instead of external. – Pygmalion Feb 12 '18 at 18:49

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.