I2C from machine vs I2C from pyb

Discussion related to "under the hood" OpenMV topics.
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

I2C from machine vs I2C from pyb

Postby cagiva » Tue Jan 17, 2017 11:10 am

Besides their API syntax being different, is there any reason when I should favor one over the other.

"from machine import I2C" seems to be often used on boards equipped with an ESP module though.
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Tue Jan 17, 2017 6:05 pm

Use pyb.I2C. I've never tested the machine variant.
Nyamekye,
User avatar
dhylands
Posts: 33
Joined: Sun May 31, 2015 1:27 pm
Location: Shuswap, BC, Canada
Contact:

Re: I2C from machine vs I2C from pyb

Postby dhylands » Tue Jan 17, 2017 7:32 pm

The general direction that MicroPython is moving is to eventually phase out the pyb module and replace it with machine module.

The machine module on the pyboard allows both HW and bit banged I2C to be used.

So right now, its really just a question of which API you want to use.
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Tue Jan 17, 2017 9:15 pm

dhylands wrote:The machine module on the pyboard allows both HW and bit banged I2C to be used."
Dave,

That machine.I2C is actually the one that I would like to use, but I'm having trouble figuring out how to call its constructor.

It seems that there is a new machine.I2C interface currently available on Micropython for the ESP8266; which is not the one available in the OpenMV firmware (2017-01-13). Therefore, I get a "TypeError: can't convert 'int' object to str implicitly" error when I try this:

Code: Select all

import machine
i2c = machine.I2C(machine.Pin(5), machine.Pin(4))
And, I cannot figure out how to assemble this constructor either:

http://docs.micropython.org/en/latest/p ... achine.I2C

Have you used the latter before with the Pyboard or OpenMV board?
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Tue Jan 17, 2017 9:20 pm

Hi, any reason you need the machine module? We're about to update the docs and no effort was put in to document that since we're using pyb.I2C.
Nyamekye,
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Tue Jan 17, 2017 9:37 pm

kwagyeman wrote:any reason you need the machine module?
Hi Kwabena,

I'm trying to adapt the code below for the VL53L0X sensor and if I use the pyb.I2C, then I'll have to change calls like writeto() and readto() with the counterpart mem_write() and mem_read() methods in the pyb.I2C module; which they behave different (i.e. the former sends an ack / nack of the last byte). If I don't have any other option, then I'll do that. However, as Dave indicated; MicroPython will eventually replace the pyb module with machine module so I prefer to use the machine.I2C version.

https://bitbucket.org/thesheep/micropyt ... /vl6180.py
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed Jan 18, 2017 12:12 am

Well, I believe the machine.i2C module is compiled into the binary right now but I can't say we support it. I'm not going to press Ibrahim to update MP right now since everything breaks when we do that. However, it would be nice to have the time available to do the update.

I'm working on getting our release we've been talking about out soon.
Nyamekye,
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Wed Jan 18, 2017 12:34 am

kwagyeman wrote:I'm not going to press Ibrahim to update MP right now since everything breaks when we do that. I'm working on getting our release we've been talking about out soon.
Thanks Kwabena!

Just let me know if you release it internally like you and Ibrahim did for the one that supports the QRCode so I can help testing it before it's officially released. Cheers!
User avatar
dhylands
Posts: 33
Joined: Sun May 31, 2015 1:27 pm
Location: Shuswap, BC, Canada
Contact:

Re: I2C from machine vs I2C from pyb

Postby dhylands » Wed Jan 18, 2017 1:35 am

It looks like the machine.I2C module included in the current OpenMV (my camera shows v1.8-4348-g62d6127) is SW only machine.I2C which follows the esp8266 documentation:
http://docs.micropython.org/en/latest/p ... e.I2C.html
which requires you to provide sda and scl pins.

Newer MicroPython (my board version 1.8.6) you can use:

Code: Select all

i2c = machine.I2C(1)
and it will use the HW I2C. If you pass -1 as the first argument then it needs the sda and scl arguments and becomes a SW I2C.

I was able to do this on my OpenMV:

Code: Select all

>>> import machine
>>> import pyb
>>> i2c = machine.I2C(sda=pyb.Pin('P5'), scl=pyb.Pin('P4'))
>>> i2c.scan()
[39]
0x27 (39) is the i2c device I had plugged into the bus. In 1.8.6.

Once OpenMV gets to 1.8.6 you can change machine.I2C(sda=pyb.Pin('P5'), scl=pyb.Pin('P4')) to be machine.I2C(2) and then it will use HW I2C rather than bitbanged (SW) I2C.
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Wed Jan 18, 2017 3:48 am

Thanks Dave. It works!

Code: Select all

>>> from machine import I2C, Pin
>>> i2c = I2C(sda=Pin('P5'), scl=Pin('P4'))
>>> print(i2c.scan())
[41]
>>> 
Wow, the machine.i2c module is poorly documented for the Pyboard. It actually indicates that the first argument is scl, and the second is sda.

Anyhow, thank again!
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Wed Jan 18, 2017 4:10 am

Dave,

After the function below is called several times, I get this message "OSError: I2C bus error". Do I need to set the freq value in the constructor?

Code: Select all

def _set_reg8(self, address, value):
        data = ustruct.pack('>HB', address, value)
        self.i2c.writeto(self._address, data)
        
def init(self):
        self._set_reg8(0xFF, 0x01);   #OK
        self._set_reg8(0x00, 0x00);  #OK
        self._set_reg8(0xFF, 0x00);   #OK
        self._set_reg8(0x09, 0x00);  #OK
        self._set_reg8(0x10, 0x00);  #OK
        self._set_reg8(0x11, 0x00);  #OK
        self._set_reg8(0x24, 0x01);  #OK
        self._set_reg8(0x25, 0xFF);  #OK
        self._set_reg8(0x75, 0x00);  #OK
        self._set_reg8(0xFF, 0x01);  #OK
        self._set_reg8(0x4E, 0x2C);  #FAIL with "OSError: I2C bus error"
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed Jan 18, 2017 12:46 pm

I'll make sure to include the machine doc in the doc release I'm about to do.
Nyamekye,
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed Jan 18, 2017 12:47 pm

cagiva - check if the packet was acked... if you have a protocol analyzer that would be good to use. Otherwise, use the exception mechanism and try the command again.
Nyamekye,
User avatar
dhylands
Posts: 33
Joined: Sun May 31, 2015 1:27 pm
Location: Shuswap, BC, Canada
Contact:

Re: I2C from machine vs I2C from pyb

Postby dhylands » Wed Jan 18, 2017 3:52 pm

The docs for pyboard's machine.I2C is here: http://docs.micropython.org/en/latest/p ... e.I2C.html (so I'm not sure which docs you were looking at).

I seem to recall that there may have been some bugs related to clock stretching that were fixed recently. Its possible that OpenMV still has the buggy version. Running at a slower frequency might work around the problem.
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Wed Jan 18, 2017 10:10 pm

dhylands wrote:Once OpenMV gets to 1.8.6 you can change machine.I2C(sda=pyb.Pin('P5'), scl=pyb.Pin('P4')) to be machine.I2C(2) and then it will use HW I2C rather than bitbanged (SW) I2C.
I'll have to wait until Kwabena and Ibrahim update their firmware with MP version 1.8 or later. Until then, I'll have to use bitbanged (SW) I2C.

Code: Select all

>>> import machine
>>> i2c=machine.I2C(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'sda' argument required
>>>
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Thu Jan 19, 2017 12:02 am

We're at version 1.8. But, we're not likely to update to the newest version until after the M7 ships. Every time we update a lot of things break. So, that would be done when more or less everything is working to make fixing everything easy.

Oh, note that we've finished prototyping the M7 and have gone ahead and ordered 40 units to build 2 panels to test mass production.
Nyamekye,
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Thu Jan 19, 2017 1:54 am

I meant v1.8.7 or later. I thought you offer to upgrade and do an internal release before M7 is shipped. However, if that is not going to be the case, then our project will have to drop M4 and look for another option. Thanks for clarifying this though.
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Thu Jan 19, 2017 11:03 am

Well, I'd rather not have you dropping the project.

But, from reading the above you found a workable solution in the mean-time right?

We might be also able to just patch that one file.
Nyamekye,
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Thu Jan 19, 2017 11:16 am

No really since I can only use bitbanged SW I2C; which seems to be too slow for us. We would like to try the hardware I2C so it'll be greatly appreciated if you could just patch/upgrade the machine module.

BTW, congratulations on reaching the goal for M7!
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Thu Jan 19, 2017 12:13 pm

Okay, I should just be able to generate a patched version of the firmware for you. Not an official release or anything. I'll do this after we do this release we've been gearing up for. Note: I'm just going to patch the machine.I2C file.
Nyamekye,
User avatar
cagiva
Posts: 78
Joined: Thu Jan 05, 2017 9:23 pm

Re: I2C from machine vs I2C from pyb

Postby cagiva » Thu Jan 19, 2017 12:15 pm

Great, thanks a lot!
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Wed May 10, 2017 11:26 am

Know this is a few months old now but did the machine.I2C file for hardware i2c ever get formally incorporated into the firmware? I could use it since I am porting the Pololu vl53l0x library to micropython as we speak.

Thanks
Mike
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed May 10, 2017 12:11 pm

Ibrahim will know...
Nyamekye,
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Wed May 10, 2017 6:39 pm

cagiva

Did you ever get the code working with the vl53l0x? I am just about ready to give up. I tried modifying the pololu code but having problems so I gave modifying the vl6810 code. Only returns 30mm.
Attachments
tofSensorTest.py
vl53l0x modified codebase
(5.92 KiB) Downloaded 131 times
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed May 10, 2017 7:07 pm

Um, is the I2C not working? I use a bus probe to verify stuff like this.

I know the pyb.I2C class works. There are a few examples with the IDE.
Nyamekye,
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Wed May 10, 2017 7:36 pm

Think bus is working. I do a i2c.scan and it sees the device a the correct address. Pretty sure it the implementation of the api that I did. The pololu conversion just hangs the system, nothing gets printed even when I do a i2c.scan() and it eventually disconnects from the usb. I am attaching it for reference. Not sure what is happening so I can't even debug it. I know I should be ustruct to pack and unpack but I just can't get around the formatting piece of it yet.

Mike
Attachments
tofSensorTest2.py
(43.6 KiB) Downloaded 137 times
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Wed May 10, 2017 9:54 pm

There's really too much code in that file... maybe, roll some simple I2C accesses by hand to check what's working first?

Sorry, I can't really help you as I don't have that sensor.
Nyamekye,
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Thu May 11, 2017 1:18 am

I took your suggestion and start putting coding it in small chucks. Besides having numerous syntax errors that weren't picked up, as well as just plain errors on my part, I kept having a problem with the following error on and off:

MemoryError: allocated xxx bytes
MicroPython v1.8-4376-g4de7fa54 on 2017-03-26; OPENMV3 with STM32F765
Type "help()" for more information

Managed to get rid of it by deleting most of the comments and reduced indents. In each case it appeared I had about 25k free space when I did a mem_free.

Got it running so it gives me a constant value like the class but I have to check I did coded the addresses correctly. Couldn't sleep - so I worked on this all night.

Thanks
Mike
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Thu May 11, 2017 9:33 am

Yeah, there's some script complexity limit with MP but I'm not quite sure on the details. Ibrahim would know more.
Nyamekye,
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Thu May 11, 2017 3:14 pm

I was doing some googling and found that this appears to be a known issue with MP. Other people were having the same issues. Not sure if it was ever fixed though.

I am having a bit of a challenge in converting a few lines of code to python. Was wondering if you could help me out here:

Code: Select all

  uint8_t ref_spad_map[6];   -----------------------------------> Have this defined as a bytearray(6)
  readMulti(GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6);  --------------> using readmem_into to get this

 can't figure out the following lines:
  for (uint8_t i = 0; i < 48; i++)
  {
    if (i < first_spad_to_enable || spads_enabled == spad_count)
    {
      // This bit is lower than the first one that should be enabled, or
      // (reference_spad_count) bits have already been enabled, so zero this bit
      ref_spad_map[i / 8] &= ~(1 << (i % 8));
    }
    else if ((ref_spad_map[i / 8] >> (i % 8)) & 0x1)
    {
      spads_enabled++;
    }
  }
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Thu May 11, 2017 4:25 pm

Code: Select all

for i in range(48): # i = 0 ... 47
    if (i < first_spad_to_enable) or (spads_enabled == spad_count):
        ref_spad_map[i / 8] &= ~(1 << (i % 8))
    elif ((ref_spad_map[i / 8] >> (i % 8)) & 0x1):
        spads_enabled += 1
?
Nyamekye,
User avatar
deshipu
Posts: 74
Joined: Sat Jan 09, 2016 5:36 am
Location: Zürich
Contact:

Re: I2C from machine vs I2C from pyb

Postby deshipu » Thu May 11, 2017 7:53 pm

You want i//8 not i/8 though. Or just i >> 3.
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Thu May 11, 2017 9:21 pm

Thanks all. Knew it could be that easy. Stil working on getting the pololu library working. But in the mean time I found a much shorter version to read the distances from the sensor on GitHub, https://github.com/popunder/VL53L0X using the smbus. Converted to machine.i2c and seems to work for single mode operation. Anyway, I am attaching it in case anyone else comes across this thread.
Attachments
tofSensorTest4.py
(3.24 KiB) Downloaded 182 times
mjs513
Posts: 74
Joined: Sun Apr 30, 2017 12:52 pm

Re: I2C from machine vs I2C from pyb

Postby mjs513 » Fri May 12, 2017 6:59 pm

tofSensorTest3.py
(15.98 KiB) Downloaded 223 times
All,
I want to thank everyone for their help with the vl53. I actually got the Pololu library ported over to micropython but while it is running it says I only have 15K free mem. Nothing left to do anything else. If you would all like I can post it here for any brave souls that may want to make it work better.

Mike

Updated. I added the file here.
User avatar
Stino
Posts: 2
Joined: Tue Apr 28, 2020 6:37 am

Re: I2C from machine vs I2C from pyb

Postby Stino » Tue Apr 28, 2020 7:29 am

Hi,

I'm trying to use your code to get the VL53L1X to work on a PyCom board.
Getting errors as below. Is there anybody that can shed some light onto this?

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 418, in <module>
  File "<stdin>", line 16, in __init__
  File "<stdin>", line 32, in init
  File "<stdin>", line 178, in getSpadInfo
TypeError: function takes 3 positional arguments but 4 were given
I did alter the import pyb module into:

Code: Select all

from machine import I2C, Pin 
Any tips or anything?

Kindest regards,

Stijn
User avatar
kwagyeman
Posts: 4665
Joined: Sun May 24, 2015 2:10 pm

Re: I2C from machine vs I2C from pyb

Postby kwagyeman » Tue Apr 28, 2020 10:48 am

I mean, you have to re-write the driver code. It shouldn't be that hard. Just fix each error one at a time. You just need to read the code and fix it.
Nyamekye,
User avatar
Stino
Posts: 2
Joined: Tue Apr 28, 2020 6:37 am

Re: I2C from machine vs I2C from pyb

Postby Stino » Wed Apr 29, 2020 4:52 am

Hi,

Well, I guess that there is some need of alteration needed. But I'm not that skilled.
I tried to figure all the values out, but don't seem to get my head around it.
Up till now I haven't found what this 4th argument is nor where it comes from.

If I Use your example, I get the errors as described earlier.
I've got an other example aswell that throws a timeout error.
The code is practically the same, only different errors and on the same lines. Spad_info.

Mostly it comes down to this error.

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 418, in <module>
  File "<stdin>", line 16, in __init__
  File "<stdin>", line 32, in init
  File "<stdin>", line 178, in getSpadInfo
TypeError: function takes 3 positional arguments but 4 were given
I got it to work by altering some things but mainly I used this library: https://github.com/openmv/openmv/blob/m ... vl53l1x.py
Still need to figure out the different configurations, but thats an issue of trial and error.

Return to “Technical Discussion”

Who is online

Users browsing this forum: No registered users and 2 guests