在MicroPython中,通过I2C从附加设备读取内存忽略提供的地址



我正试图将Arduino示例项目翻译为M5 Thermal HAT(使用MLX90640)(在M5StickC上),它适用于我的MicroPython(1.18)。

当尝试通过I2C读取数据时,奇怪的事情发生了

创建I2C对象并扫描带有HAT的总线按预期工作:

>>> from machine import Pin, I2C
>>> i2c = I2C(0, sda=Pin(0), scl=Pin(26), freq=800000)
>>> i2c.scan()
[51]

在MLX90680文档中描述的0x8000读取状态寄存器也返回对我来说似乎合理的数据:

>>> list(i2c.readfrom_mem(0x33, 0x8000, 2))
[0, 8]
>>> list(i2c.readfrom_mem(0x33, 0x8000, 2))
[0, 9]

位3表示可用数据,位0似乎在切换页面。

但现在奇迹开始了。

当我试图读取控制寄存器时;在0x800D中,如Adafruit示例(和所有其他示例)所示,它的行为似乎完全像状态寄存器(具有切换第一个位,不应该发生在控制寄存器上):

>>> list(i2c.readfrom_mem(0x33, 0x800D, 2))
[0, 9]
>>> list(i2c.readfrom_mem(0x33, 0x800D, 2))
[0, 8]

经过一些实验和不同的地址和大小,我不得不意识到I2C.readfrom_mem()提供的地址似乎是完全忽略:

>>> 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]

我尝试再次关闭和打开所有设备,使用addrsize和时钟速度的不同值,并尝试附加到棒上的不同HAT(以确保I2C原则上工作正常),但都没有见解。

由于大多数代码示例(例如这个或那个)演示如何通过I2C使用低级别访问I2C(而不是micropythonreadfrom_mem实现)使用MLX90640传感器,我还尝试了离散的写/读方法:

>>> 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]

与所有相同的效果。

我在这里做错了什么?因为我可以从I2C总线读取数据,我想我没有电气性质的问题。(本机Arduino示例也完全在同一设备上工作)。

是否有一些基本的I2C知识我错过了,直到现在?

为什么MicroPython发布的该设备上的所有I2Cread操作似乎都忽略了地址,而其他操作则完全正常?

看起来你错过了停止参数。

micropython I2C writeto

试试这个:

i2c.writeto(0x33, bytes([mem_address>>8, mem_address&0xFF]), False)
i2c.readfrom(0x33, 2)

相应地写入数据:

i2c.writeto(0x33, bytes([mem_address>>8, mem_address&0xFF] + [d,a,t,a]))

最新更新