簡體   English   中英

使用 SMBus 通過 RPi 進行模擬讀取時出現“IOError: [Errno 5] 輸入/輸出錯誤”

[英]'IOError: [Errno 5] Input/output error' while using SMBus for analog reading through RPi

我一直在尋找標題中提到的錯誤的答案,但我第一次得到了答案。 我們將嘗試讓我的 Raspberry pi 讀取模擬數據,但是當我在終端窗口中運行代碼時,它給了我“IOError:[Errno 5] 輸入/輸出錯誤”。

我用來讀取模擬數據的代碼如下所示。 我使用 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

我知道這可能是因為 raspberry pi 中的版本發生了變化,我應該將 SMBus(0) 更改為 SMBus(1)。 為此,我檢查了我的 RPi 版本,該版本不是修訂版。 但是我仍然嘗試通過更改 SMBus 編號來運行該程序,但仍然沒有運氣。

我得到的錯誤如下所示:

Traceback (most recent call last):
  File "analogread.py", line 7, in <module>
    bus.write_byte(0x48, 0)
IOError: [Errno 5] Input/output error

任何幫助表示贊賞。 這是我嘗試執行的更大項目中的基本塊。 所以,我的東西運行得越快,我就能更好地構建我的應用程序。 謝謝

造成這種情況的原因可能是您正在遠程工作 (SSH)。 斷開遠程會話后,您的程序仍在運行,並且可以嘗試打印或與控制台交互,而后者不再可用。 這就是發生在我身上的事情。

雖然這個帖子很舊,但我想分享我的結果,希望其他人能得到幫助,因為我遇到的所有帖子都沒有提到這個潛在的修復。

我遇到了類似的問題,但硬件不同(MCP23017 和 LCD)。

追了一段時間,發現不是軟件的問題,而是硬件的問題。 特別是 SCL 和 SDA 線上的上拉電阻。

RPI(在我的情況下為 3)有 1.8k 電阻,我的 LCD 也安裝了一些上拉電阻(~2.2k)。 運行 LCD 從來沒有問題,但是當通過發出命令“i2cdetect -y 1”運行掃描時,MCP23017 會隨機從總線上消失並重新出現。

移除 LCD 上額外的上拉電阻解決了問題,現在一切正常。

造成這種情況的原因可能是您推送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.

另一種可能性是該地址中實際上並不存在該設備。 因此,如果超時沒有幫助,請嘗試使用 i2c-tools(應該可以通過包管理使用,除非您使用的是自定義軟件發行版)來檢查設備是否實際可用(有時可能是布線問題,例如忘記了地):

i2cdetect -y [bus number]

為什么是i2c? 因為 SMBus 基本上是對 i2c 總線的修改,具有更嚴格定義的電壓電平和時序。

這些錯誤可能超出了程序員的控制,由隨機但常見的事件引起。

一種方法是在出現錯誤之前嘗試幾次:

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))

我在使用模型 b+ rpi 通過 I2C 驅動7 段串行顯示器時遇到了這個問題。 我通過調整波特率以匹配設備設置 (9600) 來糾正問題。 我相信默認值是 100000。

要更改波特率,我在 /etc/modprobe.d/i2c.conf 中添加了以下行:

options i2c_bcm2708 baudrate=9600

重啟后,我驗證了設置已經生效:

prompt$ sudo cat /sys/module/i2c_bcm2708/parameters/baudrate
9600

從那時起,我就沒有遇到間歇性 I/O 錯誤的問題。

我知道這個話題已經很老了,但是當我輸入不在范圍內的值時,I2C 和 PCA9685 會發生同樣的錯誤。 我想出來的方法只是簡單地禁用和啟用 I2C:

  1. sudo raspi-config
  2. '5。 接口選項'
  3. 'P5 I2C'
  4. '不'
  5. '好的'
  6. sudo reboot now
  7. sudo raspi-config
  8. '5。 接口選項'
  9. 'P5 I2C'
  10. '是的'
  11. '好的'
  12. sudo reboot now

之后, sudo i2cdetect -y 1再次檢測到我的 I2C PWM 模塊。

我在遠程(從服務器)讀取大容量 csv 文件時遇到了類似的問題,我遠程連接到工作站,我試圖從服務器讀取大容量 csv 文件。 我將文件復制到工作站,因此解決了“IOError:[Errno 5] 輸入/輸出錯誤”。 之后我遇到了 MemoryError ,我通過塊讀取解決了它,然后通過pd.concat轉換為數據幀。

代碼如下:

chunk=pd.read_csv(CSV_File_Loc,chunksize=1000000,low_memory=False)

DF_CSV=pd.concat(chunk)

我在 RasPi -> ATMEGA 通信中遇到了同樣的問題,我在從站上解決了這個問題。 如果您的從站沒有響應,則會出現此錯誤消息。

我在 RasPi 上嘗試了以下代碼,在 I2C 總線上連接了一個 I2C 從設備並配置了 0x8 地址:

從 smbus 導入 SMBus

I2C_Bus = SMBus(1)

SLAVE_ADD = 0x8

I2C_Bus.write_byte(SLAVE_ADD, 0xAA)

如果 I2C 從設備配置良好以確認,它應該可以工作!

這個問題很老,但據我所知非常實際!

解決方案(適用於 RPi 3B+)是在引腳 3 和 5(物理)上為 GPIO 設置 ALT0 模式。 這可以通過 gpio 命令行工具完成:

gpio mode 8 alt0
gpio mode 9 alt0

8和9,因為這些是wiringpi用於物理引腳3和5的編號。這正是問題所在......它使用wiringpi。
http://wiringpi.com/wiringpi-deprecated/

在我的 python 代碼中,我可以創建對這 2 個命令的系統調用(對我來說它有效!)

但是,我想要一個不使用不推薦使用的庫或工具的解決方案。

任何人?

就我而言,有導致此問題的打印語句,我剛剛刪除了該打印語句,現在該問題已為我解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM