I2C not functioning: LoPy

  • I connected a I2C real-time clock, a NXP PCF 85363A, to the SDA/SCL pins of the LoPy. When executing:
    from machine import I2C
    i = I2C(0, I2C.MASTER)
    i.scan() # correctly finds the device at address 81
    i.readfrom_mem(81, 1, 4) returns a "I2C bus error"

    Analyzing the bus traffic on SDA and SCL with a logic analyzer (Bitscope) makes it clear that the LoPy is not correctly controlling the I2C bus. See screenshot below and compare it with the next screenshot where the same RTC is controlled by another microprocessor and where the I2C read memory operation works correctly.
    0_1501508239239_LoPy I2C read memory.png
    Correct operation (please compare the right-top windows)
    0_1501508397164_I2C read memory.png

    Hope this helps getting this part of the LoPy working. For my application it is rather essential to be able to use the I2C bus. If you needs more diagnostics or tests please let me know.


  • This post is deleted!

  • @robert-hh
    I did not use the expansion board, my LoPy is on a "wired" model (i.e. holed experiment board with soldered wires) so I can in this phase of the battle easily change things without requiring a new layout. For the I2C bus a wire connection of some 3 cm should make no difference with a PCB trace, I think.

    I tried also lower clock rates (down to 10 kHz) but the capacitive load still seems to be too much... Let me check again with a normal oscilloscope probe, like you did.

  • @avbalen On my test I had a pull-up of 4k7, which i consider as normal, and the signals look fine. For me that indicates that the ESP drives the lines properly. I'm not surprised that without pull-up and load by the test device there are problems.
    Are you able to picture the analog signal on good and bad conditions?

  • @robert-hh
    Your formulation hits the nail on the head: "should"... I have worked extensively with I2C effectively from its very beginning and I find it quite strange that the drive capability of the ESP32 on those pins is so low that even attaching a logic probe "floors them out", so to speak. Never happened to me before...

    Does someone with knowledge of the ESP32 know how the SCL/SDA pins are configured on the LoPy? Can the pins be reconfigured so that they have the normal I2C drive capability, see the spec above?

  • @jmarcelino I know, but at 10k the low level should be less, and the rise time a little higher. My interest was, if the ESP32 can pull the line sufficiently low with a typical lower range pull-up.

  • @koenver yes, I used the expansion board.

  • @avbalen Did you use the the expasion board with the Lopy ? I used the expansion board II when i xperimented with the DS3231 and removed the 4k7 ohm pullups...Does anyone have the schematics of that board ? (So i know for sure that there are no pull ups at that expansion board ) ...


  • @robert-hh He used 10K resistors. Still weird but the ESP32 can be a picky beast, very long thread on ESP32 about it

  • @avbalen I made a set-up with 4k7 pullup resistors at P9 and P10 and looked at the signal with an oscilloscope. That looks pretty well. Low level at about 300 mV, rise time a 600ns for data, 200ns for clock. If these 4k7 resistors were the only ones on your I2C bus, I see no reason signalwise for a problem. Leaving them off should get tricky, when you add the probes, as you have seen. 100k||20pF give a time constant of 2 µs. With 100kHz clock (= 5 µs high/low times) that could be at the limit, not taking in to account the capacitance of board and external module.

  • @avbalen said in I2C not functioning: LoPy:

    @koenver @jmarcelino

    That seems strange. I2C should have an active pull-down, which sink at least 3 mA (Standard mode) or 20 mA /Fastmode +) to a level of 0.4 V. So at 3.3V Vdd it should drive a 1k pull-up resistor. So either the device is out of spec, or the port is configured wrong.
    The I2C spec is here: http://www.nxp.com/docs/en/user-guide/UM10204.pdf

  • @avbalen said in I2C not functioning: LoPy:

    Somewhere in the documentation please mention that SDA/SCL should not have pull-ups.

    This depends. It uses week pullup internally so if you have more devices connected it can be required

  • @koenver @jmarcelino
    Removing the two 10 k pull-ups from the SDA and SCL lines did the trick-thanks for the suggestion!
    Now I can do readfrom_mem and writeto_mem from/to the device. Remarkable is that the SDA/SCL lines are quite high impedance at 100 kHz, as connecting the Bitscope logic analyser with 100k/20 pF load on the logic inputs to SDA/SCL causes the I2C bus operations to fail again. So I cannot show a picture of the I2C bus timing from the LoPy, unfortunately.

    To Pycom: Somewhere in the documentation please mention that SDA/SCL should not have pull-ups.

  • @koenver Ps i only uses writeto and readfrom commands ; not the writetomem en readtomem in my ds3231 routines..


  • @avbalen Did you try to use separate writeto()/readfrom() calls instead of readfrom_mem

  • I did a test with a standard ds3231 rtc board and my Lopy. I had the same problems .. as the topic starter. Even at 100khz i got not stable answers for the i2cscan. so i removed the pull up resistors (4k7 ohm) from the ds3221 board. This was the problem.. now it functions perfect even with a 1MHz I2C


  • @jmarcelino
    The PCF85363A is on a small daughterboard that sits on my LoPy motherboard. SDA connected to LoPy SDA, SCL to LoPy SCL. Both with 10k pull-up to Vcc.
    /INT connected to LoPy P10 with a 100 k pull-up. Decoupling cap over the device. Exactly the same setup as on the other board. Not sure you need pull-ups on the I2C lines with the LoPy.

    What puzzels me is that the LoPy sends the correct address but then sends address 0, not the register data. Strange.

  • @avbalen
    Thanks for confirming, you'd be surprised by the number of people how never updated their firmware and are still on 1.0.0...

    There isn't anything particularly special about I2C register devices, for example for RTC I use the DS3231, also works memories, displays, FM chips....

    There are also register based I2C devices on both the Pysense and Pytrack add-on boards working successfully (here's one example), so let's figure out why it doesn't work in your case.

    It would help to have a better picture of your actual setup around this chip, how is the chip connected to the LoPy, is it on a module? Any pull-up resistors? Can you share the schematic?

  • Obviously, I am using the latest firmware, i.e. 1.7.8.b1 at time of writing.

    I assume that standard (i.e. no memory) I2C reads and writes are working as expected. Devices with on-board memory (or registers) like the one I am using are special in the sense that you need to do an address write first before reading or writing the register/memory contents. You can see that in the second screenshot, address = 0x51 (81, the device address) and the next data (0x1) is the register address. The subsequent data (0x83 etc) are the register contents.

    Let me know if you have found (an corrected) something, I can easily check on this device if the software is working as it should be.

  • @avbalen
    What firmware do you have on your LoPy? Check with os.uname()
    Make sure you're on the latest.

    I use I2C with the LoPy all day (literally, I have one doing I2C read+writes 24/7) so it is a bit strange but I'm sure we'll get to the bottom of it :)

Log in to reply

Pycom on Twitter