RPi3 - Python 3 Uart Fehler nach zufälliger Zeit - UnicodeDecodeError: 'ascii'

  • Hallo Zusammen,


    ich habe nun seit ca. einen Monat n' Problem mit meiner Programmierung bezüglich Python...

    Das Forum und auch Google konnte mir leider nicht weiterhelfen..



    Zum Hintergrund:

    Ich habe ein Steca Tarom Laderegler, welcher mir Daten über eine offene Uart 3.3V Schnittstelle schickt.

    Diese möchte ich mit meinem Rpi3 auslesen.


    Die Daten werden werden jede Minute ASCII Codiert geschickt und sehen ca so aus:

    1;2019/08/05;19:32;12.7;13.4;#;99.0;#;1.2;2.1;#;2.1;1.2;0.8;0.8;33.8;0;F;1;1;0;89.6;43069.2;13.0;5504.1;0;85FD


    Am Ende der Datenausgabe wird immer CR + LF ausgegeben.


    Soweit so gut.


    Nun habe ich in Python folgendermaßen gelöst:



    Das Funktioniert auch soweit und ich kriege auch immer die Aussage, dass er die Daten empfangen hat.


    Nun kommen wir zu dem Problem:

    Nach einer zufälligen Zeit stützt der Thread zusammen und empfängt auch keine Daten mehr. Lustigerweise ist dies immer unterschiedlich. Mal nach 1 Minute, mal nach 1 Std und manchmal läuft dieser auch 5 Tage durch, bis ich wieder den kompletten rpi neustarten muss um wieder eine ausgabe zu erhalten.


    Das Python script läuft über ein Service, sodass dieser automatisch gestartet wird.


    Laut Log erhalte ich immer diese Fehlermeldung:




    Der Fehler mit der Loging info ist mir bekannt, allerdings wenn ich nach dem UART Fehler google, bekomme ich lösungen präsentiert, die meist nur für csv Datein zuständig sind. Wenn ich das .decode weglasse, bekomme ich sofort eine andere Fehlermeldung "TypeError: a bytes-like object is required, not 'str'"



    Vielleicht habt ihr eine Idee woran es liegt.


    Ich bin momentan echt am Verzweifeln und sitze an dieser Fehlermeldung schon > 1 Monat dran, aber nichts bringt mich zu dem gewünschten Ergebnis :wallbash:



    Für jede Hilfe, wäre ich euch dankbar! :danke_ATDE:

    Edited once, last by xMicha ().

  • xMicha

    Changed the title of the thread from “RPi3 - Phyton3 Uart Fehler nach zufälliger Zeit” to “RPi3 - Phyton3 Uart Fehler nach zufälliger Zeit - UnicodeDecodeError: 'ascii'”.
  • Ich mein aber nicht den Massage error sondern mir geht es um den UnicodeDecodeError: 'ascii'


    Der Message Error ist nur eine Sache nebenbei, die aber aktuell keine Prio für mich hat

  • xMicha

    Changed the title of the thread from “RPi3 - Phyton3 Uart Fehler nach zufälliger Zeit - UnicodeDecodeError: 'ascii'” to “RPi3 - Python 3 Uart Fehler nach zufälliger Zeit - UnicodeDecodeError: 'ascii'”.
  • Das ist unterschiedlich mal erhalte ich auch folgendes:


    UnicodeDecodeError: 'ascii' codec can't decode byte 0xa4 in position 36: ordinal not in range(128)

    oder

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xbf in position 43: ordinal not in range(128)


    Der Letzte Datenbit (getrennt durch die Semikolons) entspricht laut Steca einer Checksumme

    Auszug aus der Doku:

    Quote

    Es wird ein CRC 16 gebildet. Name: „CRC-16-CCITT/openUART“ Width: 16 Direction: right shift Polynom: 0x8408 CCITT reversed,

    2Byte Länge, Highbyte, Lowbyte gebildet. Mit Semikolon und ohne CR + LF wird der CRC berechnet.


    Aber mal abgesehen davon sollte durch das Try innerhalb der While-Schleife doch solche Fehler übersprungen werden oder nicht?


    Sprich er hat was falsches eingelesen -> kann dieses nicht codieren -> überspringt das.

    Bei der nächsten Übertragung erhält er dann wieder den String.


    Aber in diesem Fall beendet er den kompletten Thread?!

  • Aber in diesem Fall beendet er den kompletten Thread?!

    Ja, weil eine Exception (AttributeError) geworfen wird, während du eine andere Exception (UnicodeDecodeError) abfängst. Also eine unabgefangene Exception, und das beendet dann den Hauptthread. Ist ja aber


    nur eine Sache nebenbei, die aber aktuell keine Prio für mich hat

    :dau2:

  • Als Notmassnahme: die ganze Response mit and 0x7F auf den Ascii-Bereich begrenzen.


    Als naechstes mal die Schnittstellenparameter genauer ansehen:

    * 7Bit oder 8Bit Chars?

    * Parity?

    * ich glaube man kann den Terminaldriver so einstellen dass er das High-Bit ignoriert

  • Ah ok verstehe.


    Bin ein wenig zu sehr von anderen Programmiersprachen verwöhnt ^^


    Ich hab nun mal die Exception angepasst:


    Code
                    except Exception as e:
                            if hasattr(e, 'message'):
                                    logging.info("---- UART: Unexpected error: {0}".format(e.message))
                            else:
                                    logging.info("---- UART: Unexpected error: {0}".format(e))


    Desweiteren habe ich auf stackoverflow noch was anderes gefunden:

    In Python 3 sollte mal lieber die .decode("ascii") leer lassen sprich -> .decode()



    Danke dir jedenfalls schon einmal für die Hilfe!


  • Das Problem ist halt dabei, dass es mal Tagelang Funktioniert und dann plötzlich wieder nur mal 1-5 Minuten... Also immer unterschiedlich


    Schnittstellenparameter passen überein:

    Baud: 4800

    Datenbits: 8

    Parität Keine

    Stoppbits: 1

    Flusssteuerung: Keine

    Übertragungsinterfall : 60+- 1


    Sonstiges:

    - Daten werden in einer festen, nicht änderbaren Reihenfolge ausgegeben.

    - Es wird keine Bezeichnung der Einheit angegeben, wie z. B. V, A, °C, Ah.

    - Die Werte werden als ASCI-Zeichen übertragen.

    - Die Nachkommastelle wird mit Punkt getrennt. Es wird max. 1 Nachkommastelle angezeigt.

    - Als Trennung wird nach jedem Wert ein Semikolon { ; } ausgegeben.

    - Liegt für eine Information kein Wert vor, so wird {#} ausgegeben. Am Ende der Datenausgabe wird CR + LF ausgegeben.

  • Hallo,


    Quote

    Bin ein wenig zu sehr von anderen Programmiersprachen verwöhnt

    Warum nimmst du dann nicht eine andere Programmiersprache?


    Zu deinem Code:

    _thread ist die low-level Schnittstelle, die man _nicht_ benutzen möchte, die möchtest das `threading` Modul nutzen.

    Die massive Verwendung von `global`zeigt, dass du einen Fehler im Programmentwurf hast. Die Verwendung von `global` ist in 99,9% der Fälle falsch.

    Anstatt einer Liste mit 20+ Einträgen solltest du vielleicht über ein Dict oder NamedTuple nachdenken.


    Gruß, noisefloor