2013-03-06 5 views
9

Podłączyłem Raspberry Pi i Rainbowduino wraz z domowej roboty I²C poziomu shifter i zainstalowany moduł SMBusPython, malina Pi może komunikować się z Rainbowduino, ale co jakiś czas pojawia się komunikat o błędzie wejścia/wyjścia podczas próby polecenia bus.write_i2c_block_data(address, signal, data).Wejście błędu/wyjście przy użyciu Pythona moduł SMBus, malin Pi oraz Arduino

Mówi:

IOError: [Errno 5] Input/output error

Dlaczego tak się dzieje i jak to naprawić lub zignorować te błędy?

+0

Ten błąd nadal występuje. Wydaje się, że jest przypadkowa, kiedy się pojawia. Czasem się to zdarzy i polecenie będzie nadal wysyłane, innym razem nie. Czy może to być spowodowane zakłóceniami? Myślałem, że smbus musi otrzymywać potwierdzenie z urządzenia slave, w przeciwnym razie nie będzie błędu, gdy polecenie zostanie odebrane pomyślnie (więc potwierdzenie jest zakłócane powodując błąd). W przeciwnym razie transmisja jest zakłócana, a więc niewolnik nie wysyła odpowiedniego potwierdzenia. – holmeswatson

+0

Mam ten sam problem ... – otmezger

+0

Nie znalazłem rozwiązania tego problemu, chociaż myślę, że jest spowodowane przez zegar przekrzywienie, więc zmniejszenie szybkości I2C na RaspberryPi może pomóc, chociaż wszystkie implementacje tego wydają się trochę nieporządne. Czasami polecenia przechodzą, ale moduł nadal błędy, a czasem polecenie nie przechodzi i błędy. W związku z tym ustawiłem próbę systemu catch, który próbuje ponownie wysłać polecenie, jeśli wystąpił błąd. Za pomocą tych pakietów wysyłam dwubajtowy numer pakietu.Jeśli Rainbowduino ma już akcję tego pakietu/polecenia, to ją ignoruje, daj mi znać, jeśli potrzebujesz kodu – holmeswatson

Odpowiedz

1

W zależności od posiadanej wersji RPi można użyć bus = SMBus(0) lub bus = SMBus(1), aby zainicjować SMBus.

Mam nadzieję, że rozwiąże to Twój problem.

+1

Nie, mogę uzyskać komunikację I2C, tylko że są pakiety zagubione tak często. – holmeswatson

3

Długo historia krótki wiele osób nękanych przez to, znalazłem bardzo proste obejście jest następujące.

Pozwoli to zignorować błąd i zachować tx/rx-ing, wywołanie i2cdetect wydaje się reinicjalizować autobus, zamiast arduino znika z niego.

i opublikował wyjaśnienie, w jaki znalazłem to rozwiązanie tutaj (oczekiwanie mod zatwierdzenie teraz) http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517

try: 
    bus.write_i2c_block_data(address, signal, data) 
except IOError: 
    subprocess.call(['i2cdetect', '-y', '1']) 
    flag = 1  #optional flag to signal your code to resend or something 

Mimo to pozwala Pi zachować transmitowania złe dane nadal jest wysyłany do Arduino. Najprostszym sposobem na obejście tego problemu było dodanie dodatkowego bajtu sumy kontrolnej na końcu moich bloków danych.

Dodałem każdy bajt wiadomości do zmiennej bajtowej, pozwalając na przewinięcie wartości, a następnie przypisz bajt sumy kontrolnej, niezależnie od wartości niezbędnej do zsumowania całej wiadomości do zera.

Arduino może następnie sprawdzić każdą transmisję przychodzącą, sumując wszystkie bajty. Jeśli komunikat nie sumuje się do zera, jest ignorowany jako błędna transmisja.

Przypisałem również moim komunikatom jednobajtowy identyfikator komunikatu, który wzrasta po każdej udanej transmisji, eliminując możliwość przypadkowego podwójnego wysłania. Ale to może nie być konieczne.

+0

Pracowałem dla mnie .. – Exzile

1

Napisałem to 19 godzin temu, kiedy pomyślałem, że mam naprawę dla problemu IOError: ........................... ..................................................

Byłem nękany tym samym błędem wejścia/wyjścia podczas korzystania z bus.write_byte rozmawiającego z Arduino. Próbowałem naprawić i2cdetect Jona, ale odkryłem, że do tego czasu w kodzie zostały uszkodzone, złe numery zostały już dostarczone do Arduino i jakoś go wyłączyły.

Co zrobił praca została resetowania baudrate I2C, stosując

sudo modprobe -r i2c_bcm2708 
    sudo modprobe i2c_bcm2708 baudrate=100010 

Po tym nie więcej błędów I/O !! Byłbym bardzo zainteresowany teoriami na temat tego, co może powodować tę widoczną niezgodność szybkości transmisji. Mam nadzieję że to pomoże!

.............................................. ...................................

Po wielu testach odkryłem, że szybkość transmisji sprawiła, że ​​tempo błędów spadło, ale nie wyeliminowało ich.

Teraz wydaje się jasne, że wywołanie i2cdetect Jona zastosowane zaraz po błędzie zainicjuje RPi, aby mogło być kontynuowane. Ale musisz także poradzić sobie z tym, że złe dane zostały prawdopodobnie wysłane do Arduino i musisz to wykryć i naprawić, a także ponownie zainicjować Wire (a w moim przypadku sterownik servo), tak, że nawet jeśli Pi ma błąd , że dane będą nadal dostępne i będą możliwe do wykorzystania. Mam nadzieję że to pomoże.

3

Tworzę serwer z serwerem Raspberry Pi i Arduino UNO z i2c i napotkałem ten sam problem. Mój projekt polega na tym, że gdy Pi otrzymuje żądanie połączenia z gniazda (przez niektóre zewnętrzne urządzenia w sieci), zapisuje "1" do Arduino, a Arduino uruchomi pętlę w pętli(), zmieniając zmienną globalną. po napisaniu Pi będzie ciągle odczytywał bajt z Arduino, aby sprawdzić stan przycisku. kiedy Pi chce przerwać czytanie, wysyła "0", aby zatrzymać pętlę i zresetować wszystkie liczniki i diodę LED.

Co się dzieje, że Python będzie losowo przez IOError podczas pisania bajtów. Na monitorze szeregowym z Arduino zauważyłem, że ostatni otrzymany bajt ma wartość 1 zamiast 0, co właśnie powinien wysłać pi. Po obejrzeniu i2cdetect -y 1 zauważyłem, że adres jest nieprawidłowy i próbowałem metody Jona, ale jak wspomniał użytkownik3126397, złe dane zostały wysłane i Arduino zatrzymało się. Próbowałem jego modprobe i to tylko tłumiło komunikat o błędzie, a Arduino jest nadal w stanie zatrzymania.

Początkowo podejrzewałem, że dane zanikły z powodu niepełnego odczytu/zapisu i dlatego dodano Serial.println(), aby sprawdzić argument byteCount w onReceive(). Nie zmieniając żadnego innego kodu zauważyłem, że nie. udanych operacji, zanim IOError znacznie się zwiększył. Dlatego próbowałem dodać więcej println(), aby przetestować korelację i zauważyłem dramatyczny wzrost awarii. Na koniec skomentowałem wszystkie seryjne stwierdzenia i mogłem wiele razy używać serwera bez błędów (testowałem coś około 30 razy i wciąż nie mam IOError).

Podejrzewam, że w odniesieniu do rozwiązania user3126397 dotyczącego resetowania prędkości transmisji i mojej obserwacji w relacji Serial.println(), błąd ten jest rzeczywiście spowodowany problemami z synchronizacją pomiędzy pi i Arduino (ponieważ Serial jest relatywnie wolny i powoduje więcej opóźnienie w programie, a tym samym zwiększa szanse na niepowodzenie.

0

niedawno natknąłem się na ten sam problem. Kiedy wyłączony interfejs seryjny teensy za błędy zniknęły całkowicie.

Używam RPI 2 z nastolatka 3.2 komunikująca się za pośrednictwem i2c o częstotliwości 2,4 mhz, wysyłająca 33-bajtowe ładunki z szybkością około 38 Kb/s.

Powiązane problemy