我已将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)