简体   繁体   English

使用Python模块SMBus,Raspberry Pi和Arduino输入/输出错误

[英]Input/output error using Python module SMBus, a Raspberry Pi and an Arduino

I have connected a Raspberry Pi and Rainbowduino together with a homemade I²C level shifter, and installed the Python module SMBus , the Raspberry Pi can communicate with the Rainbowduino, but every so often I get an input/output error message when trying the command bus.write_i2c_block_data(address, signal, data) . 我已经将Raspberry PiRainbowduino连接到一个自制的I²C级别移位器,并安装了Python模块SMBus ,Raspberry Pi可以与Rainbowduino进行通信,但是在尝试命令bus.write_i2c_block_data(address, signal, data)时,我经常会收到输入/输出错误消息bus.write_i2c_block_data(address, signal, data)

It says: 它说:

IOError: [Errno 5] Input/output error IOError:[Errno 5]输入/输出错误

Why does it happen and how do I fix or ignore these errors? 为什么会发生这种情况?如何修复或忽略这些错误?

Long story short alot of people are plagued by this, I found a very simple work around is the following. 长话短说很多人都被这个困扰,我发现一个非常简单的工作就是以下几点。

It will let you ignore the error and keep tx/rx-ing, calling i2cdetect seems to reinitialize the bus somehow instead of the arduino disappearing from it. 它会让你忽略错误并保持tx / rx-ing,调用i2cdetect似乎以某种方式重新初始化总线而不是从它消失的arduino。

i posted an explanation of how i found this solution here (waiting mod approval right now) http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517 我发布了一个如何在这里找到这个解决方案的解释(现在等待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

Even though this allows the Pi to keep transmitting bad data is still being sent to the arduino. 即使这允许Pi继续传输坏数据仍然被发送到arduino。 The simplest way I found to get around this was to add an extra check-sum byte to the end of my data blocks. 我发现解决这个问题的最简单方法是在数据块的末尾添加一个额外的校验和字节。

I added up each byte of the message inside a byte variable allowing the value to rollover, then assign the check-sum byte whatever value necessary to sum the whole message out to zero. 我在字节变量中添加了消息的每个字节,允许值翻转,然后将校验和字节分配给整数消息所需的任何值。

The arduino can then check each incoming transmission by summing all the bytes. 然后,arduino可以通过对所有字节求和来检查每个传入的传输。 If the message does not sum out to zero, it is ignored as an erroneous transmission. 如果消息未总和为零,则将其忽略为错误传输。

I also assigned my messages a one byte message id which increments after each successful transmission, eliminating the possibility of accidental double sends. 我还为我的消息分配了一个字节的消息id,它在每次成功传输后递增,消除了意外双重发送的可能性。 But that may not really be necessary. 但这可能不是必要的。

I am creating a buzzing server with a Raspberry Pi and Arduino UNO with i2c and has encountered the same problem. 我正在使用带有i2c的Raspberry Pi和Arduino UNO创建一个嗡嗡的服务器,并遇到了同样的问题。 My design is that when the Pi receives a connection request from a socket(by some external machines on the network), it writes '1' to the Arduino and Arduino will enable a loop in loop() by changing a global variable. 我的设计是当Pi从套接字(通过网络上的一些外部机器)接收连接请求时,它将'1'写入Arduino,Arduino将通过更改全局变量启用循环()循环。 after the write Pi will continuously read byte from Arduino to check for button state. 在写入Pi之后,将不断从Arduino读取字节以检查按钮状态。 when the Pi wants to stop reading it sends '0' to stop the loop and reset all counters and LED. 当Pi想要停止读取时,发送'0'以停止循环并重置所有计数器和LED。

What happens is that Python will through IOError randomly when writing byte. 发生的事情是Python在写入字节时会随机通过IOError。 On the Serial monitor with Arduino I noticed that the last byte received is 1 instead of 0, which is what the pi should have sent. 在使用Arduino的串行监视器上,我注意到收到的最后一个字节是1而不是0,这是pi应该发送的。 Upon looking at i2cdetect -y 1 I noticed the address is wrong and I tried Jon's method, but as user3126397 mentioned, the bad data has been sent and the Arduino has halted. 看了i2cdetect -y 1我注意到地址错了,我尝试了Jon的方法,但正如user3126397提到的那样,坏数据已经被发送,Arduino已经停止了。 I attempted his modprobe and that only suppressed the error message and the Arduino is still in halt state. 我尝试了他的modprobe并且只抑制了错误消息,Arduino仍处于暂停状态。

I originally suspect that the data gone sour because of incomplete read/write and therefore added a Serial.println() to check the argument byteCount in onReceive(). 我最初怀疑由于读/写不完整而导致数据变坏,因此添加了一个Serial.println()来检查onReceive()中的参数byteCount。 Without altering any other code I observed that the no. 在不改变任何其他代码的情况下,我发现了没有。 of successful operations before IOError increased a lot. IOError之前的成功操作增加了很多。 Therefore I tried to add more println() to test the correlation and noticed a dramatic increase in failure. 因此,我尝试添加更多println()来测试相关性,并发现失败率急剧增加。 Finally I commented all the Serial statements and I ended up able to use the server without faults for a considerable number of times(I tested something like 30 times and still no IOError). 最后我评论了所有的Serial语句,我最终能够在没有错误的情况下使用服务器很多次(我测试了30次,但仍然没有IOError)。

I suspect, with regard to user3126397's solution on resetting the baudrate and my observation on the Serial.println() relationship, that error is indeed caused by synchronisation issues between the pi and Arduino(as Serial is relatively slow and causes more delay in the program, thus increases the chance of failure. 我怀疑,关于user3126397关于重置波特率的解决方案以及我对Serial.println()关系的观察,该错误确实是由pi和Arduino之间的同步问题引起的(因为Serial相对较慢并导致程序更多延迟) ,从而增加失败的机会。

Depending on your RPi, you might use bus = SMBus(0) or bus = SMBus(1) to initialize the SMBus. 根据您的RPi,您可以使用bus = SMBus(0)bus = SMBus(1)来初始化SMBus。

I hope this solves your problem. 我希望这能解决你的问题。

I wrote this 19 hours ago when I thought I had a fix for the IOError problem: ............................................................................. 我在19小时前写过这篇文章,当时我认为我已经解决了IOError问题:................................ .............................................

I've been plagued with the same Input/Output error when using bus.write_byte talking to an Arduino. 使用bus.write_byte与Arduino交谈时,我一直受到相同输入/输出错误的困扰。 I tried Jon's i2cdetect fix but found that by this time in the code the damage had been done, bad numbers had already gotten to the Arduino and somehow disabled it. 我尝试了Jon的i2cdetect修复程序,但发现此时代码已经损坏了,坏的数字已经到达Arduino并以某种方式禁用了它。

What did work was resetting the i2c baudrate, using 使用的是重置i2c波特率的工作

    sudo modprobe -r i2c_bcm2708
    sudo modprobe i2c_bcm2708 baudrate=100010

After this no more I/O errors!! 在此之后没有更多的I / O错误!! I'd be very interested in theories on what could cause this apparent baudrate mismatch. 我对可能导致这种明显波特率不匹配的理论非常感兴趣。 Hope this helps! 希望这可以帮助!

................................................................................. .................................................. ...............................

Well after much more testing what I found was that the baudrate fix did make the rate of errors go down but did not eliminate them. 经过更多的测试后,我发现波特率修复确实使错误率下降但没有消除它们。

It now seems clear that Jon's i2cdetect call applied right after the error will initialize the RPi so that it can continue. 现在看来很明显,在错误发生后,Jon的i2cdetect调用将初始化RPi以便它可以继续。 But you also have to deal with the fact that bad data was probably sent to the Arduino and you need to detect this and fix it, and also reinitialize Wire (and in my case the servo driver), so that even though Pi got an error, that the data will continue to get through and be usable. 但是你还必须处理这样一个事实,即坏数据可能被发送到Arduino并且您需要检测并修复它,并且还要重新初始化Wire(在我的情况下是伺服驱动程序),这样即使Pi出错了,数据将继续通过并可用。 Hope this helps. 希望这可以帮助。

I recently came across this same issue. 我最近遇到了同样的问题。 When I disabled the teensy's serial interface, the errors disappeared entirely. 当我禁用了teensy的串行接口时,错误完全消失了。

I'm using an RPi 2 with a teensy 3.2 communicating over i2c at 2.4mhz, sending 33-byte payloads at a rate of about 38 Kbps. 我正在使用一个小型的RPi 2,通过i2c以2.4mhz进行通信,以大约38 Kbps的速率发送33字节的有效载荷。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM