isinstance problem

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
atmuc
Posts: 18
Joined: Fri Nov 13, 2020 11:44 am
Location: Istanbul

isinstance problem

Post by atmuc » Fri Nov 13, 2020 1:29 pm

isinstance returns false for I2C. Is it a bug?

i2c: I2C(0, scl=22, sda=21, freq=400000)
i2c type: <class 'I2C'>
is instance I2C: False
is instance Pin: True

Code: Select all

pinSCL = Pin(22,Pin.OUT)
pinSDA = Pin(21,Pin.OUT)
i2c2 = I2C(0, scl=pinSCL, sda=pinSDA)
print("i2c:",i2c2)
print("i2c type:",type(i2c2))
print("is instance I2C:", isinstance(i2c2, I2C))
print("is instance Pin:", isinstance(pinSCL, Pin))

User avatar
atmuc
Posts: 18
Joined: Fri Nov 13, 2020 11:44 am
Location: Istanbul

Re: isinstance problem

Post by atmuc » Fri Nov 13, 2020 4:34 pm

it returns false with the image esp32-idf4-20200902-v1.13.bin, it returns true with the image esp32-idf4-20201112-unstable-v1.13-160-g8a917ad25.bin

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: isinstance problem

Post by kevinkk525 » Fri Nov 13, 2020 6:49 pm

Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

User avatar
atmuc
Posts: 18
Joined: Fri Nov 13, 2020 11:44 am
Location: Istanbul

Re: isinstance problem

Post by atmuc » Fri Nov 13, 2020 7:21 pm

I didn't understand the solution from your link. Do I have to use soft I2C?

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: isinstance problem

Post by kevinkk525 » Fri Nov 13, 2020 10:13 pm

It might not be an obvious solution to your question. The way the I2C classes are handled has changed.
From your code you have been using hardware I2C all the time.

If you check the changes in ports/esp32/modmachine.c from that commit you can see that before this commit the I2C() was the SoftI2C so your code returned false because with id 0 you created a hardware I2C. After that commit I2C() is a HardwareI2C so your code returns true.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: isinstance problem

Post by jimmo » Sat Nov 14, 2020 5:10 am

atmuc wrote:
Fri Nov 13, 2020 7:21 pm
I didn't understand the solution from your link. Do I have to use soft I2C?
kevinkk525 wrote:
Fri Nov 13, 2020 10:13 pm
If you check the changes in ports/esp32/modmachine.c from that commit you can see that before this commit the I2C() was the SoftI2C so your code returned false because with id 0 you created a hardware I2C. After that commit I2C() is a HardwareI2C so your code returns true.
The other commit that explains this is https://github.com/micropython/micropyt ... 7232b2d101

Kevin's right but just to elaborate a bit to hopefully make the situation a bit clearer.

Before this change, machine.I2C was a soft I2C implementation, however it had some special magic (not very Pythonic -- you could only do this with metaclasses) that if you created it with an ID, then it actually gave you back an instance of the port-specific hardware I2C implementation. (There's no way from Python to get this type, other than to use type() on an existing instance).

So in v1.13

Code: Select all

i = machine.I2C(sda=, scl=, ...) --> software i2c, i is an instance of machine.I2C
i = machine.I2C(id, ...) --> hardware i2c, i is an instance of a hidden hardware I2C type
This is why instanceof returns false. Despite being constructed via machine.I2C, it's actually a different type.

The commit I linked to, followed by the one Kevin linked to makes it so that the behavior is inverted (and v1.14 onwards) and adds a new "machine.SoftI2C" (replacing the old machine.I2C), and then "machine.I2C" is now that port-specific hardware i2c type.

Code: Select all

i = machine.I2C(sda=, scl=, ...) --> software i2c, i is an instance of machine.SoftI2C
i = machine.I2C(id, ...) --> hardware i2c, i is an instance of machine.I2C
So... you don't need to change your code to use software I2C. But now (as of soon-to-be-released v1.14) you have the ability to tell the two types apart.

User avatar
atmuc
Posts: 18
Joined: Fri Nov 13, 2020 11:44 am
Location: Istanbul

Re: isinstance problem

Post by atmuc » Sat Nov 14, 2020 8:00 am

Thanks. it works now. This code makes esp32 crazy. I have to erase and flush esp32 after this code run on it.

Code: Select all

i2c= I2C(0, scl=18, sda=19, freq=400000)
print("i2c:",i2c)
i2c.init(pinSCL,pinSDA)
print("i2c:",i2c)

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: isinstance problem

Post by jimmo » Sun Nov 15, 2020 4:34 am

atmuc wrote:
Sat Nov 14, 2020 8:00 am
Thanks. it works now. This code makes esp32 crazy. I have to erase and flush esp32 after this code run on it.
Ah yeah that definitely won't work. init() will end up calling into the software implementation (which isn't initialised). This is a bug -- I will raise it on github.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: isinstance problem

Post by jimmo » Sun Nov 15, 2020 4:39 am


Post Reply