I2C Alternate Pins



  • Hi, I have a board designed where im using P22,P23 for SDA,SCL. Referencing the documentation at https://docs.pycom.io/firmwareapi/pycom/machine/i2c/ it talks about how to use non-default pins, albeit a bit confusingly as the non default example is using the default pins.

    I have tried several variations of the code, boiled down to its simplest posted at bottom.
    The i2c is not redirecting to those alternate defined pins, but remaining active on the default pins, as confirmed on the scope. Any ideas? I have dug into the machine.c file https://github.com/pycom/pycom-micropython-sigfox/blob/Dev/esp32/mods/machine_i2c.c but admittedly know little about micropython, but line 471 seems to be relevent, and at first glance, seems to have the workings of pin remapping implemented.

    Device Firmware = FW1.20.2.R6

    Thanks!

    from machine import I2C
    import time
    
    i2c = I2C(0, pins=('P22','P23'))     # create and use non-default PIN assignments (P22=SDA, P23=SCL) 
    i2c.init(I2C.MASTER, baudrate=20000) # init as a master
    
    # Main Loop:
    ############
    while True:
      print(i2c.scan())
      time.sleep(5)```


  • @Torban-Peterson like many similar objects, the constructor makes an implicit call to init so that:

    i2c = I2C(0, …arguments…)
    

    is equivalent to

    
    i2c = I2C(0)
    i2c.init(…arguments…)
    

    The pins argument is optional, but apparently leaving it out does not mean “leave as is” but “set to default”. So when you specified the pins in the constructor they were used, but then the call to init without pins reset it back to defaults.

    It should work if you either call only the constructor (with the pins) or specify the pins in the init call.

    The documentation is definitely unclear (if not wrong) about that, and I would probably venture that the behaviour of init is not quite what one would expect.



  • Digging into some old example code for the pytracker, I found they implemented the i2c as follows below, and it works. Not sure what to say. Either way the following minimal code has me going. This definitely differs from the example code.

    from machine import I2C
    
    i2c = I2C(0, mode=I2C.MASTER, pins=('P22', 'P21'), baudrate=20000)
    
    while (True):
      print(i2c.scan())
      time.sleep(5)
    


  • @Torban-Peterson all Pycom boards have conflicting pins as there are devices external to the ESP32 which use some pins to communicate with the ESP32. In the case of the GPy you have the LTE modem and the RGB LED for instance.

    But in your case it shouldn’t be an issue.

    I wonder if calling the constructor and then init is actually a good idea, it looks like the init call without the pins argument may reset to the default pins.

    Try either having all the arguments in the constructor (which actually calls init internally), or move the pins argument to the init call.



  • @jcaron Thanks, Have tried the second bus 1, same issue with i2c being broadcast to the default pins 10 and 11, have also tried different pins. Forgot to mention this is a GPY dev board, with no other devices conflicting with those pins, literally on a breadboard with i2c pullups.



  • @Torban-Peterson Since the MCU is an ESP32, you can use any Pin for I2C which can be used as an output. The major limitation with Pycom development modules is, that Pins may be assigned to other on-board devices.



  • @Torban-Peterson you may want to try using a different bus (the first parameter to the constructor), just in case there’s something else using bus 0 and overriding your own settings.


Log in to reply
 

Pycom on Twitter