Eingabe/Ausgabe-Fehler mit Python-Modul SMBus, ein Raspberry Pi und ein Arduino
Ich habe angeschlossen ein Raspberry Pi und Rainbowduino zusammen mit einem hausgemachten I2C - level-shifter und installiert Python Modul SMBus der Raspberry Pi, kann die Kommunikation mit dem Rainbowduino, aber jeder so oft bekomme ich eine input/output-Fehlermeldung, wenn Sie versuchen, den Befehl bus.write_i2c_block_data(address, signal, data)
.
Er sagt:
IOError: [Errno 5] Input/output error
Warum passiert es und wie kann ich das beheben oder ignorieren Sie diese Fehler?
- Dieser Fehler ist noch im Gange. Es scheint zufällig zu sein, wenn es Auftritt. Manchmal wird es vorkommen, und der Befehl wird immer noch gesendet werden, zu anderen Zeiten wird es nicht. Dies könnte sein, dass aufgrund von Störungen? Ich dachte das smbus werden müssen, erhalten eine Bestätigung vom slave-Gerät, sonst wäre es ja kein Fehler, wenn der Befehl wurde erfolgreich empfangen (die Bestätigung ist gestört, wodurch der Fehler). Anderenfalls wird die übertragung ist gestört und damit der Sklave nicht, senden Sie eine entsprechende Bestätigung
- Ich bin mit dem gleichen problem....
- Ich habe nicht gefunden, eine Lösung für dieses problem, obwohl ich denke, dass es verursacht wird durch clock-skew, also die Verringerung der I2C-Geschwindigkeit auf dem RaspberryPi helfen kann, obwohl alle Implementierungen, die scheinen ein bisschen chaotisch. Manchmal sind die Befehle durch zu gehen, aber das Modul immer noch Fehler, und manchmal wird der Befehl nicht durch gehen und Fehler. Daher habe ich das setup eine Weile versuchen, catch-system, das versucht, senden Sie den Befehl erneut aus, wenn es zu einem Fehler. Mit diesen Paketen sende ich eine zwei-byte-Paket-Nummer. Wenn der Rainbowduino hat bereits Maßnahmen in diesem Paket/Befehl, dann ignoriert Sie es, lassen Sie mich wissen, wenn Sie brauchen code
- Ich habe eine Lösung mit
bus = SMBus(1)
stattbus = SMBus(0)
(ich bin mit dem 512-MB-RPi). Ich weiß nicht, ob dies die Lösung für dein problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lange Geschichte kurz, eine Menge Leute sind geplagt von dieser fand ich ein sehr einfaches umgehen, ist die folgende.
Können Sie den Fehler ignorieren und halten der tx/rx-ing, Aufruf von i2cdetect scheint neu zu initialisieren (der bus irgendwie statt der arduino verschwinden es.
ich veröffentlichte eine Erklärung, wie ich fand diese Lösung hier (warte-mod-Zulassung jetzt)
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517
Obwohl dies erlaubt den Pi zu halten übermittlung von fehlerhaften Daten noch gesendet werden, um den arduino. Der einfachste Weg ich gefunden, dies zu umgehen, wurde ein zusätzliches check-Summe byte an das Ende meiner Daten-Blöcke.
Fügte ich jedes byte der Nachricht in ein byte-variable, sodass der Wert zu rollover -, dann weisen Sie die check-Summe byte welchen Wert notwendig, um die Summe der ganzen Nachricht zu null.
Dem arduino kann dann überprüfen jede eingehende übertragung durch die Summe aller bytes. Wenn die Nachricht nicht Summe sich auf null, es wird ignoriert, da eine fehlerhafte übertragung.
Ich auch zugewiesen, meine Botschaften, die ein ein-byte-Nachrichten-id die erhöht nach jeder erfolgreichen übertragung, wodurch die Möglichkeit der zufälligen doppelt sendet. Aber das ist nicht wirklich notwendig sein.
Ich bin erstellen einer Summen-server mit einem Raspberry Pi und Arduino UNO mit i2c und festgestellt hat das gleiche problem. Mein design ist, dass, wenn der Pi empfängt eine Verbindungsanforderung von a-Buchse(von externen Rechnern auf dem Netzwerk), es schreibt dann " 1 " an den Arduino und Arduino ermöglichen eine Schleife in loop() ändern, indem Sie eine Globale variable. nach dem schreiben der Pi wird ständig lese byte vom Arduino zu prüfen, drücken Zustand. wenn die Pi will, aufhören zu Lesen es sendet '0' um die Schleife zu stoppen und setzen Sie alle Schalter und LED.
Was passiert, ist, dass Python werden durch IOError zufällig beim schreiben von byte. Auf dem Seriellen monitor mit Arduino habe ich gemerkt, dass das Letzte byte empfangen ist 1 statt 0, das ist das, was der pi sollte geschickt haben. Beim Blick auf i2cdetect -y 1 ich bemerkt, dass die Adresse falsch ist und ich habe versucht, Jons Methode, sondern als user3126397 erwähnt, die falsche Daten gesendet wurde, und der Arduino hat angehalten. Ich versuchte seine modprobe und dass nur unterdrückt die Fehlermeldung und der Arduino ist immer noch im halt-Zustand.
Ich ursprünglich vermuten, dass die Daten Weg sein Sauer wegen unvollständiger Lesen/schreiben und fügte eine Serielle.println() zu überprüfen, das argument byteCount in onReceive(). Ohne änderung jedem anderen code, den ich beobachtet, dass die kein. von erfolgreichen Operationen vor IOError erhöht eine Menge. Daher habe ich versucht mehr hinzufügen println() zu testen, die Korrelation und bemerkt, einen dramatischen Anstieg der Fehler. Schließlich habe ich kommentiert alle Seriellen Anweisungen und landete ich in der Lage zu nutzen, den server ohne Fehler für eine beträchtliche Anzahl von Zeiten(getestet habe ich so 30 mal, und noch immer kein IOError).
Ich vermute, mit Bezug auf user3126397 Lösung zum zurücksetzen der baudrate und meine Beobachtung auf der Seriellen.println() Beziehung, die Fehler verursacht in der Tat durch die Synchronisations-Probleme zwischen dem pi und Arduino(als Serielle ist relativ langsam und bewirkt, dass weitere Verzögerungen im Programm, somit erhöht sich die chance des Scheiterns.
Je nach RPi, Sie könnte verwenden
bus = SMBus(0)
oderbus = SMBus(1)
zum initialisieren des SMBus.Ich hoffe das löst dein problem.
Ich schrieb diese 19 Stunden her, als ich dachte, ich hatte einen fix für das IOError-problem:
.............................................................................
Habe ich immer wieder mit dem gleichen Eingabe/Ausgabe-Fehler bei der Nutzung von bus.write_byte sprechen ein Arduino. Ich versuchte Jons i2cdetect beheben, fand aber, dass zu dieser Zeit in den code der Schaden war bereits angerichtet, schlechte zahlen schon bekommen, um die Arduino-und irgendwie ist es deaktiviert.
Was funktioniert hat, war das zurücksetzen der i2c baudrate, mit
Nachdem diese nicht mehr I/O-Fehler!! Ich wäre sehr interessiert an Theorien auf, was könnte die Ursache dieser scheinbaren baudrate überein. Hoffe, das hilft!
.................................................................................
Gut nach viel mehr Tests, was ich fand, war, dass die baudrate fix machten die rate von Fehlern gehen, aber nicht beseitigen.
Scheint es nun klar, dass Jon ' s i2cdetect rufen Sie bewarb sich direkt nach dem Fehler wird initialisiert den RPi, so dass es fortgesetzt werden kann. Aber Sie haben auch mit der Tatsache auseinandersetzen, dass die schlechten Daten war wahrscheinlich geschickt, um dem Arduino, und Sie müssen, um dies zu erkennen und es zu beheben, und auch neu initialisieren Draht (und in meinem Fall die servo-Treiber), so dass, obwohl Pi bekam eine Fehlermeldung, dass die Daten weiterhin durch zu bekommen und nutzbar sein. Hoffe, das hilft.
Kurzem stieß ich auf das gleiche Problem. Wenn deaktivierte ich den teensy mit der seriellen Schnittstelle, ist der Fehler ganz verschwunden.
Bin ich mit einem RPi 2 mit einem teensy 3.2 Kommunikation über i2c an 2.4 mhz, senden 33-byte payloads mit einer rate von etwa 38 Kbps.