I2C从机不会定期应答,除非调用了新脚本



我已将ATtiny1627编程为I2C从机,以响应read_i2c_block_data()函数。基本上,它接收指示返回哪个变量的命令,并用代表float的4个bytes来回答。Raspberry Pi 4是I2C主机,必须每500ms读取一次数据,但以下代码不起作用:

主.py

import time
from smbus import SMBus
from struct import unpack
i2c = SMBus(1)
for i in range(10):
#address: 0x0A, command: 0x54, get 4bytes
bytes = i2c.read_i2c_block_data(0x0A, 0x54, 4)
[result] = unpack('f', bytearray(bytes))
print(result)
time.sleep(.5)

运行main.py的结果是:

>sudo python3 main.py
100
100
nan
nan
nan
nan
nan
nan
nan
nan

奇怪的是,如果代码如下,它可以完美地工作:

测试.py

from smbus import SMBus
from struct import unpack
i2c = SMBus(1)
bytes = i2c.read_i2c_block_data(0x0A, 0x54, 4)
[result] = unpack('f', bytearray(bytes))
print(result)

和main2.py

import os, time
for i in range(10):
os.system('sudo python3 test.py')
time.sleep(.5)

运行main2.py:

>sudo python3 main2.py
100
100
100
100
100
100
100
100
100
100

这不是最佳的,因为我不能容易地将数据从test.py传输到main2.py以进行处理。我尝试过其他组合,但结果不令人满意:

  • test.py中定义方法并将其导入main2.py不起作用
  • 使用多处理并为每个循环创建一个新进程是行不通的
  • 使用with SMBus(1) as i2c:会引发AtributeError: __enter__,因为类未命中这些方法

我认为这与from smbus import SMBus有关,因为它是唯一一个在调用sudo python3 test.py时重新执行但在将方法导入main2.py时没有重新执行的命令。

我是不是错过了像read_i2c_block_data()这样在x秒后没有发送启动信号或类似的东西?

我建议不要使用bytes作为变量名,因为它内置在python中。

但从您的代码中还不清楚问题是什么。您不应该像第二个示例那样每次都重新初始化i2c总线。

您是否尝试过以高于500ms的速率读取,但只返回非零值?即:

import time
from smbus import SMBus
from struct import unpack
i2c = SMBus(1)
current_vals = 0
while current_vals <= 10:
raw = i2c.read_i2c_block_data(0x0A, 0x54, 4)
[result] = unpack('f', bytearray(raw))
if result != "nan":
current_vals += 1
print(result)
time.sleep(.1)

最新更新