'IOError: [Errno 5] Ошибка ввода/вывода' при использовании SMBus для аналогового чтения через RPi
Я искал ответ на ошибку, упомянутую в названии, но впервые я получил ответ. Мы попытаемся сделать мой малиновый pi прочитанным аналоговые данные, но когда я запустил код в окне терминала, он дал мне "IOError: [Errno 5] Ошибка ввода/вывода".
Код im, используемый для чтения аналоговых данных, показан ниже. Im с использованием преобразователя ACF PCF8591.
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
Я понимаю, что это может быть из-за версии, измененной в малине 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
Любая помощь приветствуется. Это основной блок в моем более крупном проекте, который я пытаюсь выполнить. Итак, fas thinster я получаю работу, которая работает лучше, я могу создать свое приложение. спасибо
Ответы
Ответ 1
Причиной этому может быть то, что вы работаете удаленно (SSH). После отключения удаленного сеанса ваша программа все еще работает и может попытаться выполнить печать или взаимодействие с консолью, которая больше не доступна. Это то, что случилось со мной.
Ответ 2
Эти ошибки могут быть за пределами контроля программистов, вызванные случайным, но обычным событием.
Один из подходов состоял бы в том, чтобы попробовать пару раз, прежде чем следовать за ошибкой:
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))
Ответ 3
Хотя эта ветка устарела, я хочу поделиться своей надежной надеждой на то, что кому-то может помочь, поскольку все сообщения, которые я натолкнулся, не упомянули об этом потенциальном исправлении.
Я столкнулся с подобной проблемой, но с другим оборудованием (MCP23017 и LCD).
После преследования проблемы в течение некоторого времени я обнаружил, что проблема заключается не в программном обеспечении, а скорее в аппаратном обеспечении. В частности, вытягивающие резисторы на линиях SCL и SDA.
RPI (3 в моем случае) имеет резисторы 1,8 тыс., А на ЖК-дисплее также установлены некоторые резисторы подтягивания (~ 2,2 тыс.). Запуск ЖК-дисплея никогда не возникал, но MCP23017 случайно исчезнет из шины и снова появится при запуске сканирования, выпустив команду "i2cdetect -y 1".
Устранение лишних резисторов на ЖК-дисплее устраняет проблему, и теперь все работает отлично.
Ответ 4
Причиной этому может быть то, что вы выталкиваете вызовы 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 (должны быть доступны через управление пакетами, если вы не используете специальное программное обеспечение), чтобы проверить, действительно ли устройство доступно (иногда это может быть проблема с подключением, например, забытая GND):
i2cdetect -y [bus number]
Почему i2c? Поскольку SMBus в основном является модификацией шины i2c с более строго определенными уровнями напряжения и таймингами.
Ответ 5
Я столкнулся с этой проблемой при управлении 7-сегментным последовательным дисплеем по I2C с моделью b+ rpi. Я исправил проблему, установив скорость передачи в соответствии с настройкой устройства (9600). Я считаю, что по умолчанию 100000.
Чтобы изменить скорость передачи в бодах, я добавил следующую строку в /etc/modprobe.d/i2c.conf:
options i2c_bcm2708 baudrate=9600
После перезагрузки я подтвердил, что настройка вступила в силу:
prompt$ sudo cat /sys/module/i2c_bcm2708/parameters/baudrate
9600
С тех пор у меня не было проблем с прерывистыми ошибками ввода-вывода.
Ответ 6
У меня была та же проблема в сообщении RasPi → ATMEGA, и я разрешаю ее на подчиненном устройстве. Это сообщение об ошибке появляется, если ваш подчиненный не отвечает.
Я попробовал следующий код на RasPi, с ведомым I2C, подключенным к шине I2C и настроенным с адресом 0x8:
от smbus импорт SMBus
I2C_Bus = SMBus (1)
SLAVE_ADD = 0x8
I2C_Bus.write_byte (SLAVE_ADD, 0xAA)
Предоставление ведомого устройства I2C хорошо настроено для подтверждения, оно должно работать!
Ответ 7
Я знаю, что эта тема довольно старая, но такая же ошибка произошла с I2C и PCA9685, когда я добавлял значения, которые не были в диапазоне. Как я понял, это просто отключить и включить I2C:
-
sudo raspi-config
- "5. Варианты сопряжения '
- 'P5 I2C'
- "Нет"
- 'ОК'
-
sudo reboot now
-
sudo raspi-config
- "5. Варианты сопряжения '
- 'P5 I2C'
- 'Да'
- 'ОК'
-
sudo reboot now
После этого sudo i2cdetect -y 1
снова обнаруживает мой модуль sudo i2cdetect -y 1
I2C.