web-dev-qa-db-fra.com

'IOError: [Errno 5] Erreur d'entrée/sortie' lors de l'utilisation de SMBus pour la lecture analogique via RPi

Je cherchais la réponse à l'erreur mentionnée dans le titre, mais pour la première fois, j'ai encore une réponse. Nous essaierons de faire lire mon Raspberry Pi aux données analogiques, mais quand je lance le code dans la fenêtre du terminal, il me donne "IOError: [Errno 5] Erreur d'entrée/de sortie".

Le code utilisé pour lire les données analogiques est présenté ci-dessous. Je me sers du convertisseur ADC 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

Je comprends que cela pourrait être dû à la version modifiée dans Raspberry Pi et je devrais changer SMBus (0) en SMBus (1). Pour cela, j'ai vérifié ma version de RPi qui n'est pas la version révisée. Mais j'ai quand même essayé d'exécuter le programme en changeant le numéro SMBus, toujours pas de chance.

L'erreur que je reçois est indiquée ci-dessous: 

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

Toute aide est appréciée. C’est le bloc de base de mon plus gros projet que j’essaie d’exécuter. Donc, le logiciel FAS Thinster fonctionne mieux je peux construire mon application ..__ Merci

14
Sudhanshu Dixit

La cause en est peut-être que vous travaillez à distance (SSH). Après avoir déconnecté la session distante, votre programme fonctionne toujours et peut essayer d’imprimer ou d’interagir avec la console, qui n’est plus disponible. Voilà ce qui m'est arrivé.

16
adimitrov

Ces erreurs peuvent être indépendantes de la volonté du programmeur, causées par un événement aléatoire mais habituel.

Une approche consiste à essayer plusieurs fois avant de suivre avec l'erreur:

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
viservolf

Bien que ce sujet soit ancien, je souhaite partager mon espoir de pouvoir réellement aider une autre personne, car tous les messages que j'ai rencontrés ne mentionnaient pas ce correctif potentiel.

Je rencontrais un problème similaire, mais avec un matériel différent (MCP23017 et un écran LCD).

Après avoir poursuivi le problème pendant un certain temps, j'ai constaté que le problème n'était pas un logiciel, mais plutôt un matériel. Plus précisément, les résistances de rappel sur les lignes SCL et SDA.

Le RPI (3 dans mon cas) a 1,8k résistances et mon LCD avait quelques résistances pull up installées (~ 2,2k). L'exécution de LCD n'a jamais posé de problème, mais le MCP23017 disparaîtrait de manière aléatoire du bus et réapparaîtrait lors de l'exécution d'une analyse en émettant la commande "i2cdetect -y 1". 

Le retrait des résistances de rappel supplémentaires sur le LCD a résolu le problème et tout fonctionne parfaitement à présent.

3
Daniel Loranger

La cause en est peut-être que vous déployez les appels read/write plus rapidement que votre matériel ne peut les accepter. Ajoutez donc de petits délais entre les opérations de lecture/écriture:

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.

Une autre possibilité est que le périphérique ne soit pas réellement présent à cette adresse. Donc, si les délais d'attente ne vous aident pas, essayez i2c-tools (devrait être disponible via la gestion des paquets, sauf si vous utilisez une distribution logicielle personnalisée) pour vérifier si le périphérique est réellement disponible GND):

i2cdetect -y [bus number]

Pourquoi i2c? Parce que SMBus est fondamentalement une modification du bus i2c avec des niveaux de tension et des horaires plus strictement définis.

2
plaes

J'ai rencontré ce problème lors de la conduite d'un affichage série 7 segments sur I2C avec un modèle b + rpi. J'ai corrigé le problème en ajustant le débit en bauds pour l'adapter au réglage de l'appareil (9600). Je crois que le défaut est 100000.

Pour changer le débit en bauds, j'ai ajouté la ligne suivante à /etc/modprobe.d/i2c.conf:

options i2c_bcm2708 baudrate=9600

Après le redémarrage, j'ai vérifié que le paramètre avait pris effet avec:

Prompt$ Sudo cat /sys/module/i2c_bcm2708/parameters/baudrate
9600

Depuis lors, je n'ai eu aucun problème d'erreurs d'E/S intermittentes.

1
Micah Larson

Je sais que ce sujet est assez ancien, mais la même erreur s’est produite avec I2C et PCA9685 lorsque j’ai mis des valeurs qui ne se trouvaient pas dans la plage. La façon dont je l'ai compris était simplement de désactiver et d'activer I2C:

  1. Sudo raspi-config
  2. '5. Options d'interfaçage '
  3. 'P5 I2C'
  4. 'Non'
  5. 'D'ACCORD'
  6. Sudo reboot now
  7. Sudo raspi-config
  8. '5. Options d'interfaçage '
  9. 'P5 I2C'
  10. 'Oui'
  11. 'D'ACCORD'
  12. Sudo reboot now

Ensuite, Sudo i2cdetect -y 1 détecte mon module I2C PWM.

0
Matt G.

J'ai eu le même problème dans une communication RasPi -> ATMEGA et je le résous sur l'esclave. Ce message d'erreur se produit si votre esclave ne répond pas.

J'ai essayé le code suivant sur RasPi, avec un esclave I2C connecté sur le bus I2C et configuré avec l'adresse 0x8:

de smbus import SMBus

I2C_Bus = SMBus (1)

SLAVE_ADD = 0x8

I2C_Bus.write_byte (SLAVE_ADD, 0xAA)

Si l’esclave I2C est bien configuré pour reconnaître, cela devrait fonctionner!

0
Alek6