我已将Raspberry Pi和Rainbowduino与自制的I²C级别移位器连接在一起,并安装了Python模块SMBus,Raspberry Pi可以进行通信使用Rainbowduino,但每次尝试命令bus.write_i2c_block_data(address, signal, data)
时都会收到输入/输出错误消息。
它说:
IOError:[Errno 5]输入/输出错误
为什么会发生这种情况?如何修复或忽略这些错误?
答案 0 :(得分:3)
长话短说很多人都被这个困扰,我发现一个非常简单的工作是以下。
它会让你忽略错误并保持tx / rx-ing,调用i2cdetect似乎以某种方式重新初始化总线而不是arduino从中消失。
我发布了一个关于我如何在这里找到这个解决方案的解释(现在等待mod批准) http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517
try:
bus.write_i2c_block_data(address, signal, data)
except IOError:
subprocess.call(['i2cdetect', '-y', '1'])
flag = 1 #optional flag to signal your code to resend or something
即使这允许Pi继续传输坏数据仍然被发送到arduino。我发现解决这个问题的最简单方法是在数据块的末尾添加一个额外的校验和字节。
我在字节变量中添加了消息的每个字节,允许值翻转,然后将校验和字节分配给将整个消息求和为零所需的任何值。
然后,arduino可以通过对所有字节求和来检查每个传入的传输。如果消息未总和为零,则将其忽略为错误传输。
我还为我的消息分配了一个字节的消息ID,它在每次成功传输后递增,消除了意外双重发送的可能性。但这可能不是必要的。
答案 1 :(得分:3)
我正在使用带有i2c的Raspberry Pi和Arduino UNO创建一个嗡嗡作响的服务器,并遇到了同样的问题。我的设计是当Pi从套接字(通过网络上的一些外部机器)接收连接请求时,它将'1'写入Arduino,Arduino将通过更改全局变量启用循环()循环。在写入Pi之后,将不断从Arduino读取字节以检查按钮状态。当Pi想要停止读取时,发送'0'以停止循环并重置所有计数器和LED。
当写入byte时,Python会随机通过IOError。在使用Arduino的串行监视器上,我注意到收到的最后一个字节是1而不是0,这是pi应该发送的。看了i2cdetect -y 1我注意到地址错了,我尝试了Jon的方法,但正如user3126397提到的那样,坏数据已经被发送,Arduino已经停止了。我尝试了他的modprobe并且只是抑制了错误信息而且Arduino仍然处于暂停状态。
我最初怀疑由于读/写不完整而导致数据变坏,因此添加了一个Serial.println()来检查onReceive()中的参数byteCount。在不改变任何其他代码的情况下,我发现了没有。 IOError之前的成功操作增加了很多。因此,我尝试添加更多println()来测试相关性,并发现失败率急剧增加。最后,我评论了所有的Serial语句,最终我能够在没有错误的情况下使用服务器很多次(我测试了30次,但仍然没有IOError)。
我怀疑,关于user3126397关于重置波特率和我对Serial.println()关系的观察的解决方案,该错误确实是由pi和Arduino之间的同步问题引起的(因为Serial相对较慢并导致更多延迟在程序中,因此增加了失败的机会。
答案 2 :(得分:1)
根据您的RPi,您可以使用bus = SMBus(0)
或bus = SMBus(1)
来初始化SMBus。
我希望这能解决你的问题。
答案 3 :(得分:1)
我在19小时前写过这篇文章,当时我认为我修复了IOError问题: .................................................. ...........................
当使用bus.write_byte与Arduino交谈时,我一直受到相同输入/输出错误的困扰。我尝试了Jon的i2cdetect修复程序,但发现此时代码已经损坏了,坏的数字已经到达Arduino并以某种方式禁用了它。
使用
重置i2c波特率的工作是什么 sudo modprobe -r i2c_bcm2708
sudo modprobe i2c_bcm2708 baudrate=100010
此后不再有I / O错误!!我对可能导致这种明显波特率不匹配的理论非常感兴趣。希望这有帮助!
............................................... ..................................
经过更多测试后,我发现波特率修复确实使错误率下降但没有消除它们。
现在看来很明显,在错误发生后,Jon的i2cdetect调用将初始化RPi以便它可以继续。但是你还必须处理这样一个事实,即坏数据可能被发送到Arduino并且您需要检测并修复它,并且还要重新初始化Wire(在我的情况下是伺服驱动程序),这样即使Pi出错了,数据将继续通过并可用。希望这会有所帮助。
答案 4 :(得分:0)
我最近遇到过同样的问题。当我禁用了teensy的串行接口时,错误完全消失了。
我正在使用一个小型3.2的RPi 2,通过i2c以2.4mhz进行通信,以大约38 Kbps的速率发送33字节的有效载荷。