I2C communication (write/WriteBytes returns None, Readbytes returns 0xff) using pyOnionI2C #I2C #OMEGA2



  • Using Python (pyOnionI2C): I am unable to communicate with I2c bus each and every time it returns:

    • on write it returns status as None

    • On Read it returns 0xff whether i am using any devAddr, addr

    I have omega2, python-light, RTC chip plugged into i2c, pyOnionI2C.
    0_1500369341203_i2cdetect_omega2.JPG
    using Shell script i am getting the same issue as below:
    0_1500369468190_2.i2cdetect_omega2.JPG

    below issue found(same) when i run python code available on github for i2c as an example.
    0_1500369686405_3.i2cdetect_omega2.JPG
    #I2C #OMEGA2



  • @Arshad-Alam said in I2C communication (write/WriteBytes returns None, Readbytes returns 0xff) using pyOnionI2C #I2C #OMEGA2:

    RTC chip

    Working on i2c interface as well; I get an identical return from i2cdetect for a completely different chip (digital potentiometer). Typically it should just return one address!

    I disconnected the i2c wires from the breadboard and still get identical (junk) output, so I'm wondering if it might be an error state? Hardware or software though?



  • As a follow-up, I got I2C working through specifically addressing the chip as specified in the docs, but i2cdetect never, even now, returned accurate information. i2cdetect response such as this (30-37, 50-5f) useless for troubleshooting; does not indicate anything about state of i2c bus.

    Thanks to the OP for downvoting my last comment, I hope you downvote this one as well.



  • @Sam-Smith This is an old topic, but can you describe how you eventually were able to read the i2c ?

    I have a PCF8574 break-out board, but if i'm correct, this chipset isn't supported (yet).
    So maybe your solution can help me...



  • Here's a python program that reads a BME280

    #!/usr/bin/python
    #--------------------------------------
    #    ___  ___  _ ____
    #   / _ \/ _ \(_) __/__  __ __
    #  / , _/ ___/ /\ \/ _ \/ // /
    # /_/|_/_/  /_/___/ .__/\_, /
    #                /_/   /___/
    #
    #           bme280.py
    #  Read data from a digital pressure sensor.
    #
    #  Official datasheet available from :
    #  https://www.bosch-sensortec.com/bst/products/all_products/bme280
    #
    # Author : Matt Hawkins
    # Date   : 25/07/2016
    #
    # http://www.raspberrypi-spy.co.uk/
    #
    #--------------------------------------
    # Adapted by ASandford for Onion Omega2 24/01/2018
    #
    # To install the Python module, run the following commands:
    # opkg update
    # opkg install python-light pyOnionI2C libonioni2c
    #--------------------------------------
    
    
    import time
    from OmegaExpansion import onionI2C
    from ctypes import c_short
    from ctypes import c_byte
    from ctypes import c_ubyte
    
    DEVICE = 0x76 # Default device I2C address
    
    i2c     = onionI2C.OnionI2C()
    
    def getShort(data, index):
      # return two bytes from data as a signed 16-bit value
      return c_short((data[index+1] << 8) + data[index]).value
    
    def getUShort(data, index):
      # return two bytes from data as an unsigned 16-bit value
      return (data[index+1] << 8) + data[index]
    
    def getChar(data,index):
      # return one byte from data as a signed char
      result = data[index]
      if result > 127:
        result -= 256
      return result
    
    def getUChar(data,index):
      # return one byte from data as an unsigned char
      result =  data[index] & 0xFF
      return result
    
    def readBME280ID(addr=DEVICE):
      # Chip ID Register Address
      REG_ID     = 0xD0
      (chip_id, chip_version) = i2c.readBytes(addr, REG_ID, 2)
      return (chip_id, chip_version)
    
    def readBME280All(addr=DEVICE):
      # Register Addresses
      REG_DATA = 0xF7
      REG_CONTROL = 0xF4
      REG_CONFIG  = 0xF5
    
      REG_CONTROL_HUM = 0xF2
      REG_HUM_MSB = 0xFD
      REG_HUM_LSB = 0xFE
    
      # Oversample setting - page 27
      OVERSAMPLE_TEMP = 2
      OVERSAMPLE_PRES = 2
      MODE = 1
    
      # Oversample setting for humidity register - page 26
      OVERSAMPLE_HUM = 2
      i2c.writeByte(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)
    
      control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
      i2c.writeByte(addr, REG_CONTROL, control)
    
      # Read blocks of calibration data from EEPROM
      # See Page 22 data sheet
      cal1 = i2c.readBytes(addr, 0x88, 24)
      cal2 = i2c.readBytes(addr, 0xA1, 1)
      cal3 = i2c.readBytes(addr, 0xE1, 7)
    
      # Convert byte data to word values
      dig_T1 = getUShort(cal1, 0)
      dig_T2 = getShort(cal1, 2)
      dig_T3 = getShort(cal1, 4)
    
      dig_P1 = getUShort(cal1, 6)
      dig_P2 = getShort(cal1, 8)
      dig_P3 = getShort(cal1, 10)
      dig_P4 = getShort(cal1, 12)
      dig_P5 = getShort(cal1, 14)
      dig_P6 = getShort(cal1, 16)
      dig_P7 = getShort(cal1, 18)
      dig_P8 = getShort(cal1, 20)
      dig_P9 = getShort(cal1, 22)
    
      dig_H1 = getUChar(cal2, 0)
      dig_H2 = getShort(cal3, 0)
      dig_H3 = getUChar(cal3, 2)
    
      dig_H4 = getChar(cal3, 3)
      dig_H4 = (dig_H4 << 24) >> 20
      dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)
    
      dig_H5 = getChar(cal3, 5)
      dig_H5 = (dig_H5 << 24) >> 20
      dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)
    
      dig_H6 = getChar(cal3, 6)
    
      # Wait in ms (Datasheet Appendix B: Measurement time and current calculation)
      wait_time = 1.25 + (2.3 * OVERSAMPLE_TEMP) + ((2.3 * OVERSAMPLE_PRES) + 0.575) + ((2.3 * OVERSAMPLE_HUM)+0.575)
      time.sleep(wait_time/1000)  # Wait the required time
    
      # Read temperature/pressure/humidity
      data = i2c.readBytes(addr, REG_DATA, 8)
      pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
      temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
      hum_raw = (data[6] << 8) | data[7]
    
      #Refine temperature
      var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
      t_fine = var1+var2
      temperature = float(((t_fine * 5) + 128) >> 8);
    
      # Refine pressure and adjust for temperature
      var1 = t_fine / 2.0 - 64000.0
      var2 = var1 * var1 * dig_P6 / 32768.0
      var2 = var2 + var1 * dig_P5 * 2.0
      var2 = var2 / 4.0 + dig_P4 * 65536.0
      var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
      var1 = (1.0 + var1 / 32768.0) * dig_P1
      if var1 == 0:
        pressure=0
      else:
        pressure = 1048576.0 - pres_raw
        pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
        var1 = dig_P9 * pressure * pressure / 2147483648.0
        var2 = pressure * dig_P8 / 32768.0
        pressure = pressure + (var1 + var2 + dig_P7) / 16.0
    
      # Refine humidity
      humidity = t_fine - 76800.0
      humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
      humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
      if humidity > 100:
        humidity = 100
      elif humidity < 0:
        humidity = 0
    
      return temperature/100.0,pressure/100.0,humidity
    
    def main():
    
      (chip_id, chip_version) = readBME280ID()
      print "Chip ID     :", chip_id
      print "Version     :", chip_version
    
      temperature,pressure,humidity = readBME280All()
    
      print "Temperature : ", temperature, "C"
      print "Pressure : ", pressure, "hPa"
      print "Humidity : ", humidity, "%"
    
    if __name__=="__main__":
       main()
    root@Omega-0E97:~#
    
    The output I get is :
    
    root@Omega-0E97:~# ./OObme280.py
    Chip ID     : 96
    Version     : 0
    Temperature :  23.9 C
    Pressure :  1012.20485776 hPa
    Humidity :  43.5635548431 %
    
    


Looks like your connection to Community was lost, please wait while we try to reconnect.