d s*_*d s 10 python arduino i2c raspberry-pi smbus
我遇到了问题,在启动通过 I2C 从 Arduino 请求数据的脚本时,pyhton 有时会在我的 raspberry pi 3 上抛出这个 IOError 。
电气连接是完美的,所以这不是问题。此外,我在使用 i2cget -y 1 0x04 时也没有收到任何错误
有时只有 python 脚本很糟糕,我不知道为什么。
这是我的 Arduino 代码:
我注册了一个 onReceive 和一个 onRequestEvent。onReceive 回调将定义应该发送回树莓派的数据类型。onRequest 回调执行响应。
#include <CommonFunction.h>
#include <Wire.h>
#define I2C_ADDRESS 0x4
commonFunc GetCountsEverySecond;
int g_iOnRequestActionCode = 0;
unsigned long g_lSecondsSinceStart = 0;
void setup()
{
Wire.begin(I2C_ADDRESS);
Wire.onRequest(sendDataOverI2CGateway);
Wire.onReceive(defineOnRequestAction);
}
void loop()
{
tickSeconds();
}
void tickSeconds()
{
if (GetCountsEverySecond.TimeTriggerAt(1000))
{
g_lSecondsSinceStart++;
}
}
void sendOperationTimeDataOverI2C()
{
unsigned long longInt = g_lSecondsSinceStart;
byte size = sizeof(longInt);
byte arr[size];
for (int i = 0; i < size; i++)
{
int iBitShift = 8 * (size - i - 1);
if (iBitShift >= 8)
arr[i] = ((longInt >> iBitShift) & 0xFF);
else
arr[i] = (longInt & 0xFF);
}
Wire.write(arr, size);
g_bI2CSending = true;
}
void sendDataOverI2CGateway()
{
switch(g_iOnRequestActionCode)
{
case 0:
sendRainDataOverI2C();
break;
case 1: // send firmware version
sendVersionDataOverI2C();
break;
case 2: // send operation time of arduino in seconds from start
sendOperationTimeDataOverI2C();
break;
default: break;
}
}
void defineOnRequestAction(int iBuffer)
{
while (Wire.available())
{
g_iOnRequestActionCode = Wire.read();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的Python代码。非常简单,但它会引起一些头痛。
import smbus
import time
bus = smbus.SMBus(1)
while True:
data = bus.read_i2c_block_data(0x04,0x02,4)
result = 0
for b in data:
result = result * 256 + int(b)
print(result)
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
执行我的 python 脚本后,有时会出现此错误:
pi@WeatherStation:~/workspace $ sudo python readTimeOperationData.py
Traceback (most recent call last):
File "readTimeOperationData.py", line 5, in <module>
data = bus.read_i2c_block_data(0x04,0x02,4)
IOError: [Errno 121] Remote I/O error
Run Code Online (Sandbox Code Playgroud)
谁能帮我解决这个问题?
干杯迪特尔
d s*_*d s 12
我解决了!!
我从这篇文章中得到了提示: https://www.raspberrypi.org/forums/viewtopic.php ?t=203286
通过添加延迟后bus = smbus.SMBus(1)解决了这个问题。似乎需要一段短暂的延迟才能使 I2C 稳定下来。
工作代码通过调用脚本 100 次进行测试,没有出现任何问题。
import smbus
import time
bus = smbus.SMBus(1)
time.sleep(1) #wait here to avoid 121 IO Error
while True:
data = bus.read_i2c_block_data(0x04,0x02,4)
result = 0
for b in data:
result = result * 256 + int(b)
print(result)
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)