Arduino Nano Every erzeugt Zeichenfehler bei simpler serieller Kommunikation

Wenn ich die Ausgabe reduziere auf nur ein einzelnes "A" pro Durchlauf erhalte ich auch folgende ausgabe:

A

A�

A

A

Es wird also scheinbar dann das \n oder so falsch interpretiert. Ich habe aber auch einen Fall gehabt, der so aussieht:

A

A

�

A

Es kommt also auch bei einem einzelnen Zeichen schon vor.

Dan schreibe mal Seria.begin ganz aus

Wenn der Fehler auch wie im Eingangspost mit write() auftritt und - wie gerade aufgezeigt - mitten in einer Zeichenkette, kannst Du \n wohl ausschließen.

Auch eine fehlerhafte Synchronisation durch "Übersehen" des echten Startbits halte ich für wenig wahrscheinlich: In der Übertragung der 'A' kommen - wenn ich mich nicht täusche - keine aufeinanderfolgenden 7 Nullen vor, die Voraussetzung wären, um eine 0x80 zu produzieren.

Ich kann leider auch mangels Every nicht selbst testen.

Verändert sich das Ergebnis, wenn man

Serial.begin(115200, SERIAL_8N2);

verwendet oder statt 'A' mal 'B' sendet?

Das B wäre binär symmetrisch...

Vielleicht kann man durch gezielte Veränderung des Binärmusters der Ursache näher kommen.

Nein, sowohl mit dem neuen Serial.begin() als auch mit 'B' gibt es diese Fehler

Es wird ein beliebiges Zeichen in der Ausgabe ersetzt.
Wenn es ein A ist, wird es in der Zeichenkette ersetzt, wenn es ein Steuerzeichen ist, wird es zusätzlich sichtbar.

Das Zeilenende ist \\r \\n das \\r wird nicht interpretiert.

Ausgewertet wird \\n - hier ist das \\r ersetzt worden, was meine Theorie bestärkt, dass das im SamD oder auf dem Weg dorthin passiert.

Darum solltest Du das mit einem zweiten Controller testen.

Nachtrag: im HTERM kannst Du doch die Zeilenbreite begrenzen, bis zwangsweise ein Zeilenumbruch kommt.

Las Dir die Werte und Steuerzeichen in HEX ausgeben.

Irgendwann solltest Du sehen, dass ein Steuerzeichen ersetzt wurde.

// EDIT2:

Stell Dein HTerm so ein:

Dann siehst Du, wenn das Steuerzeichen überschrieben wird.

Das heißt, unabhängig von den gesendeten Daten ergibt sich als Fehlerwert 0x80?!

Das klingt weder nach einem verpassten Startbit noch nach einem Problem mit der Abtastfrequenz, dann würde ich unterschiedliche Werte erwarten.

Hattest Du schon mal erfasst, nach wie vielen Charaktern jeweils der falsche Wert ausgegeben wird? Gibt es da ein erkennbares Muster?

In meinen Augen erfolgt das komplett zufällig. Ich habe mal 2 Programmdurchläufe gestartet und mir die Zeile und das jeweilige Zeichen notiert welches zu 0x80 wird:

Durchlauf 1:

Zeile || Zeichen
212 || 9
1466 || 3
1719 || 8
2848 || 8
4102 || 1
4188 || 17

Durchlauf 2:

299 || 9
370 || 5
896 || 7
1265 || 9
2742 || 10
3076 || 11
3167 || 7 & 14

Ja, ich habe das HTERM umgestellt und gesehen, dass ein '\n' durch 0x80 ersetzt wurde. Aber was bedeutet das jetzt? Ich habe zuvor auch schon festgestellt, dass auch die Steuerzeichen davon betroffen sind.

Das bedeutet, dass es willkürlich irgendein Zeichen erwischt und die sichtbare Ersetzung in deiner obigen Zeile Dich auf einen falschen Pfad führt, wenn Du nicht berücksichtigst, dass es auch Steuerzeichen erwischt, was dann zu einem zusätzlichen Zeichen in der Ausgabe führt.

Das kann jetzt viele Gründe haben.

Um das einzugrenzen braucht es aber einen kontrollierbaren zweiten Ausgabeweg.

Alles andere ist reines stochern im Nebel. Wie das geht habe ich geschrieben.

Zur weiteren Eingrenzung den Every an einem anderen Rechner zu hängen, um Einstreuungen über die USB-Spannung auszuschliessen, hast Du sicher schon gemacht.

Hallo,

das Problem kann aktuell irgendwelche Ursachen haben. Eine normale serielle Verbindung ist nun einmal per se nicht abgesichert im Bezug auf Übertragungsfehler. Wenn es mit der Taktabweichung während der Übertragung echte Probleme geben würde, müsste der Fehler laut meiner Meinung häufiger auftreten, mit höherer Baudrate zunehmen und mit niedriger Baudrate abnehmen. Du kannst auch Ganzzahlige Baudraten einstellen, bspw 250000. Dann ist der rechnerische Fehler auf dem µC = 0. Du kannst auch meinetwegen am OSC20MCALIBA rumfummeln bzw. an die Quelle anpassen. Macht laut meiner Meinung nach nur Sinn wenn 2 µC ohne Quarz miteinander reden. Du könntest auch mittels Logik Analyzer die Übertragung anschauen und den Fehler einfangen. Vorher mit Oszi das Signal beurteilen. Also ist die Übertragung noch korrekt und nur der Empfang im µC fehlerhaft o.ä. Die interne RC eines ATmega4809 ist übrigens um einiges genauer wie die der alten ATmegas. Wenn bei 1 Mio Zeichen es 10 falsche sind, dann glaube ich selbst eher an Zufallseffekte. Hast du schon einmal die Serielle/USART auf Fehlercodes abgefragt? Ansonsten bleibt beim Empfänger nur ein Plausibilitätscheck der Daten. Was nicht offensichtlich passt wird verworfen. CRC müsste man wie du schon festgestellt hast auf beiden Seiten einbauen.

Nochwas. Schau dir einmal den Unterschied zwischen \n und 0x80 auf Bitebene an. Welches Bit und am Ende welcher Puls der Bits der USART macht den Unterschied? Danach machste dich schlau wie ein Byte übertragen wird. Vielleicht sieht man hier schon eine Erkenntnis.

Da 0x80 auch bei A oder B rauskommt, also jedes x-beliebige Zeichen mit dem selben Inhalt überschrieben wird, was soll da für eine Erkenntnis auf Bitebene für \n möglich sein?

Zumal das mit dem \n eher \r ist, wie ich oben bereits schrieb, denn das Zeichen wird am Ende der Zeile zusätzlich ausgegeben.

Da die Fehler auch mit dem Code aus dem Post 1 entstehen, kann man Steuerzeichen als Besonderheit ausschliessen:

  Serial.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  delay(100);
}

Gemäß Post 27 sind selbst Fehler mit einem Abstand von 7 Zeichen aufgetreten (Durchlauf 2, Zeile 3167). Das lässt auch die Theorie eines algorithmisch bedingten Abtastfehlers verwerfen.

Ich konnte trotz intensiver Suche im Netz national und international bisher auch keinen weiteren Hinweis auf die Beobachtung von @lz666 finden, was höchst selten vorkommt.

Insofern bleiben die Möglichkeiten:

a) Systematische Fehlersuche
b) Trial and Error
c) Jemanden finden (und fragen), der sich mit dem Nano Every tiefgehend auskennt

zu a) Deinen Vorgehensvorschlag weitertreiben (separaten seriellen Weg, um die MuxTo-Bridget zu umgehen)
zu b)

  • Anzahl der Zeichen variieren, die auf einen Schlag gesendet werden (z.B. 31 oder 33)
  • Sendevorgang auf zwei mal 16 Byte mit einem delayMicroseconds(200) auftrennen und dann delay(100);
  • und delay() mal durch eine millis()-Routine ersetzen

zu c) Viel Glück!!!!!

Da es kein willkürlich gekipptes Bit und auch kein anderes Zeichen ist, muss es etwas wiederkehrendes sein, was aber weder zeitlich noch im Code abgebildet wird.

Da es zudem an allen EVERY auftritt, aber an "normalen" Nanos nicht, liegt es also an einer Besonderheit im Zusammenhang mit der Hardware.
Und da ich noch immer keine Aussage zu einer Ausgabe auf einem Serial1 und auch irgendwie nichts bezüglich des ansteckens des Controller an einen anderen Rechner zu hören bekomme, ist für mich alles ausgereizt.

Von daher... :man_shrugging: