Python 使用 SMBus 通过 RPi 进行模拟读取时出现“IOError: [Errno 5] 输入/输出错误”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30325351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'IOError: [Errno 5] Input/output error' while using SMBus for analog reading through RPi
提问by Sudhanshu Dixit
I have been looking for the answer for the error mentioned in the title but for the first time i haavent got an answer yet. We ll im trying to make my Raspberry pi read analog data but when i run the code in terminal window it gives me 'IOError: [Errno 5] Input/output error'.
我一直在寻找标题中提到的错误的答案,但我第一次得到了答案。我们将尝试让我的 Raspberry pi 读取模拟数据,但是当我在终端窗口中运行代码时,它给了我“IOError:[Errno 5] 输入/输出错误”。
The code im using to read analog data is shown below. Im using PCF8591 ADC converter.
我用来读取模拟数据的代码如下所示。我使用 PCF8591 ADC 转换器。
from smbus import SMBus
bus = SMBus(0)
print "read a/d press ctrl + c to stop"
bus.write_byte(0x48, 0)
lastval = -1
while True:
reada = bus.read_byte(0x48)
if(abs(lastval-reada) > 2):
print(reada)
lastval=reada
I understand it might be because of the version changed in raspberry pi and i should change SMBus(0) to SMBus(1). For this i checked my RPi version which is not the revised one. But still I tried to run the program by changing the SMBus number, still no luck with it.
我知道这可能是因为 raspberry pi 中的版本发生了变化,我应该将 SMBus(0) 更改为 SMBus(1)。为此,我检查了我的 RPi 版本,该版本不是修订版。但是我仍然尝试通过更改 SMBus 编号来运行该程序,但仍然没有运气。
The error I get is shown below:
我得到的错误如下所示:
Traceback (most recent call last):
File "analogread.py", line 7, in <module>
bus.write_byte(0x48, 0)
IOError: [Errno 5] Input/output error
Any help is appreciated. This is the basic block in my bigger project which im trying to execute. So, the fas thinster i get thing working the better i can build my application. Thank you
任何帮助表示赞赏。这是我尝试执行的更大项目中的基本块。所以,我的东西运行得越快,我就能更好地构建我的应用程序。谢谢
回答by viservolf
These errors might be beyond programmer's control, caused by a random, yet usual, event.
这些错误可能超出程序员的控制,由随机但常见的事件引起。
One approach would be to try a couple of times before following with the error:
一种方法是在出现错误之前尝试几次:
def try_io(call, tries=10):
assert tries > 0
error = None
result = None
while tries:
try:
result = call()
except IOError as e:
error = e
tries -= 1
else:
break
if not tries:
raise error
return result
try_io(lambda: bus.write_byte(0x48, 0))
回答by plaes
The cause to this might be that you're pushing out the read/write
calls faster than your hardware can accept them. So add small delays between read/write operations:
造成这种情况的原因可能是您推送read/write
调用的速度比硬件可以接受的速度快。因此,在读/写操作之间添加小的延迟:
from time import sleep
from smbus import SMBus
bus = SMBus(0)
bus.write_byte(0x48, 0)
sleep(0.2) # Wait for device to actually settle down
lastval = -1
while True:
reada = bus.read_byte(0x48)
if(abs(lastval-reada) > 2):
print(reada)
lastval=reada
sleep(0.2) # This might be not needed.
Another possibility is that device is not actually present in this address. So if the timeouts don't help, try out i2c-tools (should be available via package management, unless you're using a custom software distribution) to check whether the device is actually available (sometimes it could be a wiring issue like forgotten GND):
另一种可能性是该地址中实际上并不存在该设备。因此,如果超时没有帮助,请尝试使用 i2c-tools(应该可以通过包管理使用,除非您使用的是自定义软件发行版)来检查设备是否实际可用(有时可能是布线问题,例如忘记了地):
i2cdetect -y [bus number]
Why i2c? Because SMBus is basically a modification of i2c bus with more strictly defined voltage levels and timings.
为什么是i2c?因为 SMBus 基本上是对 i2c 总线的修改,具有更严格定义的电压电平和时序。
回答by Alek6
I had the same problem in a RasPi -> ATMEGA communication and I resolve it on the slave. This error message occurs if your slave doesn't respond.
我在 RasPi -> ATMEGA 通信中遇到了同样的问题,我在从站上解决了这个问题。如果您的从站没有响应,则会出现此错误消息。
I tried the following code on RasPi, with an I2C slave connected on the I2C bus and configured with the 0x8 address :
我在 RasPi 上尝试了以下代码,在 I2C 总线上连接了一个 I2C 从设备并配置了 0x8 地址:
from smbus import SMBus
从 smbus 导入 SMBus
I2C_Bus = SMBus(1)
I2C_Bus = SMBus(1)
SLAVE_ADD = 0x8
SLAVE_ADD = 0x8
I2C_Bus.write_byte(SLAVE_ADD, 0xAA)
I2C_Bus.write_byte(SLAVE_ADD, 0xAA)
Providing the I2C slave is well configured to acknowledge, it should work!
如果 I2C 从设备配置良好以确认,它应该可以工作!
回答by adimitrov
The cause to this might be that you're working remotely (SSH). After you disconnect the remote session, your program is still working and could try to print or interact to console, which is not available any more. This is what happened to me.
造成这种情况的原因可能是您正在远程工作 (SSH)。断开远程会话后,您的程序仍在运行,并且可以尝试打印或与控制台交互,而后者不再可用。这就是发生在我身上的事情。
回答by Daniel Loranger
While this thread is old, I want to share my resuly hoping someone else might be helped as all posts I came across did not mention this potential fix.
虽然这个帖子很旧,但我想分享我的结果,希望其他人能得到帮助,因为我遇到的所有帖子都没有提到这个潜在的修复。
I was encountering a similar issue, but with different hardware (MCP23017 and an LCD).
我遇到了类似的问题,但硬件不同(MCP23017 和 LCD)。
After chasing the problem for some time, I found the problem was not software, but rather hardware. Specifically the pull up resistors on the SCL and SDA lines.
追了一段时间,发现不是软件的问题,而是硬件的问题。特别是 SCL 和 SDA 线上的上拉电阻。
The RPI (3 in my case) has 1.8k resistors and my LCD had some pull up resistors installed as well (~2.2k). Running the LCD never had a problem, but the MCP23017 would randomly disappear from the bus and reappear when running a scan by issuing command "i2cdetect -y 1".
RPI(在我的情况下为 3)有 1.8k 电阻,我的 LCD 也安装了一些上拉电阻(~2.2k)。运行 LCD 从来没有问题,但是当通过发出命令“i2cdetect -y 1”运行扫描时,MCP23017 会随机从总线上消失并重新出现。
Removing the extra pull up resistors on the LCD fixed the problem and all works perfectly now.
移除 LCD 上额外的上拉电阻解决了问题,现在一切正常。
回答by Micah Larson
I experienced this problem when driving a 7-segment serial displayover I2C with a model b+ rpi. I corrected the problem by adjusting the baud rate to match the device setting (9600). I believe the default is 100000.
我在使用模型 b+ rpi 通过 I2C驱动7 段串行显示器时遇到了这个问题。我通过调整波特率以匹配设备设置 (9600) 来纠正问题。我相信默认值是 100000。
To change the baud rate, I added the following line to /etc/modprobe.d/i2c.conf:
要更改波特率,我在 /etc/modprobe.d/i2c.conf 中添加了以下行:
options i2c_bcm2708 baudrate=9600
After reboot, I verified the setting had taken effect with:
重启后,我验证了设置已经生效:
prompt$ sudo cat /sys/module/i2c_bcm2708/parameters/baudrate
9600
Since then, I've had no problems with intermittent I/O errors.
从那时起,我就没有遇到间歇性 I/O 错误的问题。
回答by Matt G.
I know this topic is quite old but the same error occured with I2C and PCA9685 when I put values that were not in range. The way I figured it out was just simply disabling and enabling I2C:
我知道这个话题已经很老了,但是当我输入不在范围内的值时,I2C 和 PCA9685 会发生同样的错误。我想出来的方法只是简单地禁用和启用 I2C:
sudo raspi-config
- '5. Interfacing options'
- 'P5 I2C'
- 'No'
- 'OK'
sudo reboot now
sudo raspi-config
- '5. Interfacing options'
- 'P5 I2C'
- 'Yes'
- 'OK'
sudo reboot now
sudo raspi-config
- '5。接口选项'
- 'P5 I2C'
- '不'
- '好的'
sudo reboot now
sudo raspi-config
- '5。接口选项'
- 'P5 I2C'
- '是的'
- '好的'
sudo reboot now
After that, sudo i2cdetect -y 1
detects my I2C PWM module back again.
之后,sudo i2cdetect -y 1
再次检测到我的 I2C PWM 模块。
回答by karelv
The issue is old, but according to me very actual!
这个问题很老,但据我所知非常实际!
The solution(for RPi 3B+) is to set ALT0 mode for the GPIO at pin 3 & 5 (physical). This can be done with the gpio command line tool:
解决方案(适用于 RPi 3B+)是在引脚 3 和 5(物理)上为 GPIO 设置 ALT0 模式。这可以通过 gpio 命令行工具完成:
gpio mode 8 alt0
gpio mode 9 alt0
8 and 9 as these are the numberings used by wiringpi for physical pin 3 & 5.
And this is exactly the issue... it uses wiringpi.
http://wiringpi.com/wiringpi-deprecated/
8和9,因为这些是wiringpi用于物理引脚3和5的编号。这正是问题所在......它使用wiringpi。
http://wiringpi.com/wiringpi-deprecated/
In my python code I could create a system call to those 2 commands (for me it works!)
在我的 python 代码中,我可以创建对这两个命令的系统调用(对我来说它有效!)
However I would like a solution which does not use deprecated libs or tools.
但是,我想要一个不使用不推荐使用的库或工具的解决方案。
Anyone?
任何人?
回答by Mark Chaudhary
In my case there was print statement that was causing this issue, I just removed that print statement and now that issue has been resolved for me.
就我而言,有导致此问题的打印语句,我刚刚删除了该打印语句,现在该问题已为我解决。