'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:

  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 снова обнаруживает мой модуль sudo i2cdetect -y 1 I2C.