Reputation: 9808
I'm trying to translate an Arduino example project for the M5 Thermal HAT (using MLX90640) (on an M5StickC) which works for me to MicroPython (1.18).
While trying to read data via I2C strange things happen.
Creating the I2C
object and scanning the bus with the HAT attached works as expected:
>>> from machine import Pin, I2C
>>> i2c = I2C(0, sda=Pin(0), scl=Pin(26), freq=800000)
>>> i2c.scan()
[51]
Reading the status register at 0x8000
as described in the MLX90680 documentation also returns data which seems plausible to me:
>>> list(i2c.readfrom_mem(0x33, 0x8000, 2))
[0, 8]
>>> list(i2c.readfrom_mem(0x33, 0x8000, 2))
[0, 9]
Bit 3 indicates available data and bit 0 seems to toggle pages.
But now the magic begins.
As I try to read the "control register" at 0x800D
as demonstrated in an Adafruit example (and all other examples) it seems to behave exactly like the status register (with a toggling first bit, which should not happen on a control register):
>>> list(i2c.readfrom_mem(0x33, 0x800D, 2))
[0, 9]
>>> list(i2c.readfrom_mem(0x33, 0x800D, 2))
[0, 8]
After a bit of experimenting and playing with different addresses and sizes I had to realize that the address provided with I2C.readfrom_mem()
seems to be totally ignored:
>>> list(i2c.readfrom_mem(0x33, 0x0000, 16))
[0, 9, 0, 191, 121, 159, 0, 0, 32, 97, 0, 4, 3, 32, 3, 224]
>>> list(i2c.readfrom_mem(0x33, 0x1000, 16))
[0, 9, 0, 191, 121, 159, 0, 0, 32, 97, 0, 4, 3, 32, 3, 224]
>>> list(i2c.readfrom_mem(0x33, 0x2400, 16))
[0, 9, 0, 191, 121, 159, 0, 0, 32, 97, 0, 4, 3, 32, 3, 224]
>>> list(i2c.readfrom_mem(0x33, 0x2800, 16))
[0, 8, 0, 191, 121, 159, 0, 0, 32, 97, 0, 4, 3, 32, 3, 224]
I tried turning all devices off and on again, played with different values for addrsize
and clock speeds and tried a different HAT attached to the stick (to make sure I2C is working fine in principal) but all with no insights.
Since most code examples (e.g. this or that) demonstrating how to use the MLX90640 sensor via I2C use low level access to I2C (rather than MicroPythons readfrom_mem
implementation) I also tried a discrete write/read approach:
>>> i2c.writeto(0x33, bytes([0x80, 0x0D]))
2
>>> list(i2c.readfrom(0x33, 2))
[0, 9]
>>> i2c.writeto(0x33, bytes([0x0D, 0x80])) # try swapped byte order
2
>>> list(i2c.readfrom(0x33, 2))
[0, 9]
With all the same effect.
What do I do wrong here? Since I can read data from the I2C bus I guess I don't have a problem of electrical nature.. (also the native Arduino example is fully working on the same device).
Is there some basic I2C knowledge I missed until now?
Why do all I2C read
operations on this device issued by MicroPython seem to disregard the address while others are working totally fine?
Upvotes: 1
Views: 1084
Reputation: 26
It looks like you are missing the stop parameter.
Try this:
i2c.writeto(0x33, bytes([mem_address>>8, mem_address&0xFF]), False)
i2c.readfrom(0x33, 2)
Accordingly to write data you'd write:
i2c.writeto(0x33, bytes([mem_address>>8, mem_address&0xFF] + [d,a,t,a]))
Upvotes: 1