I2C Bus Error



  • Hello,

    I have consistently been having the OSError: I2C bus error and have yet to find a fix that works.

    There are a few topics already where people have just updated their pytrack firmware/LoPy firmware to fix the problem. I am on the most recent versions of both of these and still no fix.

    The traceback is:
    File "main.py", line 51, in <module>
    File "pycoproc.py", line 252, in read_battery_voltage
    File "pycoproc.py", line 167, in set_bits_in_memory
    File "pycoproc.py", line 158, in magic_write_read
    File "pycoproc.py", line 117, in _write
    OSError: I2C bus error.

    Line 115 is:
    self.i2c.writeto(I2C_SLAVE_ADDR, data)

    Also Getting it with:
    File "main.py", line 51, in <module>
    File "pycoproc.py", line 252, in read_battery_voltage
    File "pycoproc.py", line 167, in set_bits_in_memory
    File "pycoproc.py", line 158, in magic_write_read
    File "pycoproc.py", line 117, in _write
    File "pycoproc.py", line 129, in _wait
    OSError: I2C bus error.

    Line 117 is:
    self._wait()
    Does anyone have any ideas on what could be going wrong? Sometimes the module can be running for a few hours before it gets an error, sometimes it happens several times in a row.

    Cheers,
    Dylan



  • @livius Thanks, that is now working. I am getting [] while everything is working, and it seems to say "None" just before a "Board not detected" error. No change on anything when receiving an I2C bus error message.

    @ledbelly2142 what do you mean by checking the pins? I've gone as far as removing the LoPy from the Pytrack and having a look haha, but it looks like normal pins to me.

    Hope everyone had a good Christmas and New Years



  • @dylan said in I2C Bus Error:

    Yup, I just tried is again but with capitals, I2C.scan(), got "TypeError: function takes 1 positional arguments but 0 were given"

    because you use class not object (1 argument is needed self - object itself)
    You must create I2C object first to use it.

    from machine import I2C
    
    my_obj = I2C(0, I2C.MASTER, baudrate=100000) #here you create object `my_obj` of class type `I2C`
    

    and then you can use it

    devices = my_obj.scan() #here you got list of devices addresses
    print(devices)
    


  • I'm also still consistently getting the "Exception: Board not detected". Thought I'd just post here rather than make another topic.
    I have re-installed pytrack 0.0.8 twice now, the message in command prompt and all along the way suggests that everything worked perfectly, also updated to the 1.10.2.b1 firmware for LoPy.. I'm using the most recent pycoproc.py/pytrack.py files. My fix has been a terrible one, I just put in machine.reset() before the "Raise Exception('Board not detected')" line, it works but it certainly isn't a great solution.

    Last night my device ran for 4 hours before stopping which was great, but I'm going to be needing weeks to months at a time. I'm so close to being able to send my device out in the field :D.



  • @ledbelly2142 Not sure on the battery voltage pins, but that's what I've been looking at since your last reply, so far this is what I've been looking at:

    def read_battery_voltage(self):
        self.set_bits_in_memory(ADCON0_ADDR, _ADCON0_GO_nDONE_MASK)
        time.sleep_us(50)
        while self.peek_memory(ADCON0_ADDR) & _ADCON0_GO_nDONE_MASK:
            time.sleep_us(100)
        adc_val = (self.peek_memory(ADRESH_ADDR) << 2) + (self.peek_memory(ADRESL_ADDR) >> 6)
        return (((adc_val * 3.3 * 280) / 1023) / 180) + 0.01    # add 10mV to compensate for the drop in the FET
    
    def set_bits_in_memory(self, addr, bits):
        self.magic_write_read(addr, _or=bits)
    
    def peek_memory(self, addr):
        self._write(bytes([CMD_PEEK, addr & 0xFF, (addr >> 8) & 0xFF]))
        return self._read(1)[0]
    
    
    _ADCON0_GO_nDONE_MASK = const(0x02)
    ADCON0_ADDR = const(0x9D)
    ADRESL_ADDR = const(0x09B)
    ADRESH_ADDR = const(0x09C)
    

    Really not sure what the 0x9D parts are meaning, can't see anything else that might be related to what pins the voltage is using.



  • @dylan I don't know if you can move the I2C pins, I moved mine on the breakout board (not the Pysense) with the deep sleep shield. Not sure what pins the pytrack is using for i2c, looks like G8 (P21) SCL and G9 (P22) SDA, but seems like they should not be on the same pin as the voltage reading. What pin are you using to read the battery voltage?

    I don't know how it works with the Pysense board.



  • I'm getting coordinates and a battery voltage reading to be sent at the same time to the TTN etc. I was thinking that maybe they are both using the same pins and that's how sometimes they throw each other out, the error is always for the battery voltage from memory, the voltage reading is taken first in the coding.



  • @ledbelly2142 Yup, I just tried is again but with capitals, I2C.scan(), got "TypeError: function takes 1 positional arguments but 0 were given"



  • @dylan do you have these imports in your main file?

    import machine
    from machine import I2C
    


  • That sounds like it will give me a good start cheers. I put in a line i2c.scan() just before error message so it would come up when there has been an error, but its come back saying "AttributeError: NoneType object has no attribute 'scan' ". How should I be putting in the i2c.scan() to be getting it to work?



  • When I have received this error in the past, it was due to having the wrong i2c address for the device. This may not be your issue, but you can rule it out and check the deive address with

    i2c.scan()
    

    If you don't get anything back, check the pins your I2C connection. I apologize if you already tried this, just a simple thing to check and rule out if you haven't already.


Log in to reply
 

Pycom on Twitter