我正试图将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]))