Connect with us

Bit Banging I2C for communication between Raspberry Pi and PFC8591

Discussion in 'Microcontrollers, Programming and IoT' started by John Manuel, Jul 19, 2018.

  1. John Manuel

    John Manuel

    20
    0
    Jun 7, 2018
    I am trying to interface multiple PCF8591 (around 5) to a single Raspberry Pi using I2C protocol. Since a Rpi has only one set of SDA and SCL pins, I am trying to bit-bang to make the other GPIO pins work as SDA and SCL. I am trying to use RPi.GPIO library for making the bit banging code in python.

    I don't understand how to communicate with PCF8591 even after referring to the manual plenty of times. I could not figure out how to receive data from a specific pin from PCF8591 since there are 4 pins available (AIN0, AIN1, AIN2, AIN3). I also want the input voltage as the differential voltage between two pins. It would be very helpful if anyone could tell me the steps to change and access different pins of PCF8591.

    I am attaching the code I am using. I get a reading of '255' throughout whenever I run it. It is working more or less as I could see the SCA and SDA waveforms in an oscilloscope.
    Code:
    import RPi.GPIO as GPIO
    import time
    import matplotlib.pyplot as plt
    
    pin_SCL = 0
    pin_SDA = 0
    signal = []
    
    def plot_graph(time, data, graph_no, label_):
        fig = plt.figure(graph_no)
        axes = fig.add_subplot(111)
        axes.patch.set_facecolor('black')
        plt.plot(time, data, label = label_)
        plt.ylabel('Voltage')
        plt.xlabel('Time')
        plt.legend(loc='upper right')
    
    def set_pin(SCL, SDA):
        global pin_SCL
        global pin_SDA
        pin_SCL = SCL
        pin_SDA = SDA
        GPIO.setup(pin_SCL, GPIO.OUT)
    
    def start():
        GPIO.setup(pin_SDA, GPIO.OUT)
      
        GPIO.output(pin_SCL, GPIO.HIGH)
        GPIO.output(pin_SDA, GPIO.HIGH)
      
        time.sleep(10)
      
        GPIO.output(pin_SDA, GPIO.LOW)
        GPIO.output(pin_SCL, GPIO.LOW)
      
    def send_byte(byte):
        GPIO.setup(pin_SDA,GPIO.OUT)
      
        for i in range(8):
            GPIO.output(pin_SDA,byte & 0b10000000)
            GPIO.output(pin_SCL,GPIO.HIGH)
            GPIO.output(pin_SCL,GPIO.LOW)
            byte = byte << 1
    
    def acknowledge_from_slave():
        GPIO.setup(pin_SDA,GPIO.IN)
      
        GPIO.output(pin_SCL,GPIO.HIGH)
        status = GPIO.input(pin_SDA)
        GPIO.output(pin_SCL,GPIO.LOW)
      
        if(status == GPIO.HIGH):
            print("BYTE NOT RECEIVED")
              
    def acknowledge_from_master():
        GPIO.setup(pin_SDA,GPIO.OUT)
      
        GPIO.output(pin_SCL,GPIO.HIGH)
        GPIO.output(pin_SDA,GPIO.LOW)
        GPIO.output(pin_SCL,GPIO.LOW)
    
    def receive_byte():
        global signal
        byte = ''
      
        GPIO.setup(pin_SDA,GPIO.IN)
      
        for i in range(8):
                GPIO.output(pin_SCL,GPIO.HIGH)
                byte = byte + str(GPIO.input(pin_SDA))
                GPIO.output(pin_SCL,GPIO.LOW)
      
        byte = int(byte,2)
        signal.append(byte)
              
    if __name__ == "__main__":
        global signal
      
        GPIO.setmode(GPIO.BOARD)
        set_pin(38,40)
        start()
        send_byte(0b10010001)
        acknowledge_from_slave()
      
        send_byte(0b00110000)#control byte to tell pcf8591 work as differential input
      
        acknowledge_from_master()
    
        try:
            while True:
                receive_byte()
                acknowledge_from_master()
              
        except KeyboardInterrupt:
            plot_graph(range(len(signal)),signal,1,'Detected Signal')
    
        plt.show()
        GPIO.cleanup()
    
     
    Last edited: Jul 19, 2018
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,191
    2,693
    Jan 21, 2010
    An i2c bus can have 127 slaves on it. The PCF8591 can only have 1 of 8 addresses set, so you can only have 8 of them connected to a single bus.

    Why not use the single bus the RPI has and whatever standard libraries it has. Surely you can find examples of how to talk to this chip?
     
    John Manuel likes this.
  3. John Manuel

    John Manuel

    20
    0
    Jun 7, 2018
    I need data from all the ADC at the same time instant for my project. I came to know that the master can communicate with only one slave at any time instant and the other slaves have to sit idle at that time instant.

    I actually wanted to know how to access different pins in a single PCF8591.
     
  4. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,191
    2,693
    Jan 21, 2010
    For true simultaneity you need to trigger all the ADCs at the same time, or to hold the inputs at the same time. A series of sample & hold circuits with a common control would allow you to hold at the signals and then read them one by one. It can be even simpler here with an analog mux because you only need a single ADC.

    But banging seems to be the hard way. I understand doing it that way if you have a million units to create; the cost saving in a few chips could outweigh the additional software complexity.
     
    John Manuel likes this.
  5. John Manuel

    John Manuel

    20
    0
    Jun 7, 2018
    Thank you very much for your reply! I have already chosen to travel the harder path it seems and I do not wish to turn back now. I will try the same with a multiplexer later, but as of now, I need to do it with bit banging.

    It would be tremendously helpful if you could tell me what I am doing wrong with the code.
     
  6. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,191
    2,693
    Jan 21, 2010
    I don't see anything to set the timing.

    Have you asked on a specialist forum? (see here)

    It appears you can configure additional I2C ports on the RPI that will be bit-banged by the OS.
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-