'IOError: [Errno 5] Ошибка ввода / вывода' при использовании SMBus для аналогового чтения через RPi

Я искал ответ для ошибки, упомянутой в названии, но впервые я еще не получил ответ. Мы попытаемся заставить мой Raspberry pi читать аналоговые данные, но когда я запускаю код в окне терминала, он выдает мне "IOError: [Errno 5] Ошибка ввода / вывода".

Код, который я использую для чтения аналоговых данных, показан ниже. Я использую 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

Я понимаю, что это может быть из-за версии, измененной в 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

Любая помощь приветствуется. Это основной блок в моем большом проекте, который я пытаюсь выполнить. Итак, чем быстрее я получу работу, тем лучше я смогу построить свое приложение. Спасибо

10 ответов

Причиной этого может быть то, что вы работаете удаленно (SSH). После отключения удаленного сеанса ваша программа все еще работает и может попытаться распечатать или взаимодействовать с консолью, которая больше не доступна. Это то, что случилось со мной.

Несмотря на то, что эта ветка старая, я хочу поделиться своим мнением, надеясь, что кому-то еще может помочь, поскольку во всех постах, с которыми я столкнулся, не упоминалось об этом потенциальном исправлении.

Я столкнулся с аналогичной проблемой, но с другим оборудованием (MCP23017 и ЖК-дисплей).

В течение некоторого времени я решил, что проблема не в программном, а в аппаратном обеспечении. В частности, подтягивающие резисторы на линиях SCL и SDA.

RPI (3 в моем случае) имеет резисторы 1,8 кОм, а на моем ЖК-дисплее также установлены некоторые подтягивающие резисторы (~2,2 кОм). Запуск ЖК-дисплея никогда не вызывал проблем, но MCP23017 случайным образом исчезал из шины и появлялся снова при запуске сканирования с помощью команды "i2cdetect -y 1".

Удаление дополнительных подтягивающих резисторов на ЖК-дисплее устранило проблему, и теперь все работает отлично.

Эти ошибки могут быть вне контроля программиста, вызванные случайным, но обычным событием.

Один из подходов состоит в том, чтобы попробовать пару раз, прежде чем следовать с ошибкой

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

Причиной этого может быть то, что вы выталкиваете 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 с более строго определенными уровнями напряжения и таймингами.

Я столкнулся с этой проблемой при управлении 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

С тех пор у меня не было проблем с прерывистыми ошибками ввода-вывода.

Я знаю, что эта тема довольно старая, но та же ошибка произошла с 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.

У меня была аналогичная проблема при удаленном чтении файла 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)

Выпуск старый, но на мой взгляд очень актуальный!

Решение (для RPi 3B+) - установить режим ALT0 для GPIO на контактах 3 и 5 (физических). Это можно сделать с помощью инструмента командной строки gpio:

gpio mode 8 alt0
gpio mode 9 alt0

8 и 9, так как это нумерация, используемая wiringpi для физических контактов 3 и 5. И это как раз проблема... он использует wiringpi.
http://wiringpi.com/wiringpi-deprecated/

В моем коде на Python я мог бы создать системный вызов этих двух команд (для меня это работает!)

Однако мне нужно решение, в котором не используются устаревшие библиотеки или инструменты.

Кто угодно?

В моем случае был оператор печати, который вызывал эту проблему, я просто удалил этот оператор печати, и теперь эта проблема для меня решена.

У меня была такая же проблема в связи RasPi -> ATMEGA, и я решил ее на подчиненном устройстве. Это сообщение об ошибке появляется, если ваш ведомый не отвечает.

Я попробовал следующий код на RasPi с ведомым устройством I2C, подключенным к шине I2C и настроенным с адресом 0x8:

от smbus импорт SMBus

I2C_Bus = SMBus (1)

SLAVE_ADD = 0x8

I2C_Bus.write_byte (SLAVE_ADD, 0xAA)

Если ведомый I2C хорошо настроен для подтверждения, он должен работать!

Другие вопросы по тегам