Alle meine Mikrocontroller-Geräte, die über UART mit dem PC kommunizieren, verwenden ASCII-Zeichenfolgen zum Senden und Empfangen von Daten (wie in Arduino implementiert). Das habe ich gelernt, als ich angefangen habe, mich mit Elektronik zu beschäftigen, und ich fand es immer genug, bloße Saiten zu senden. Mir ist jedoch aufgefallen, dass die meisten Geräte, auf die ich gestoßen bin, ausgefeilte Binärprotokolle verwenden, die Funktionscodes, Adressen und CRC-Fehlerprüfungen enthalten.
Wann ist grundlegende ASCII-Kommunikation akzeptabel und wann sollte ich etwas Fortgeschritteneres wie Modbus in Betracht ziehen? Verwenden kommerzielle Geräte solche ASCII-Zeichen? Industrie?
microcontroller
serial
communication
uart
protocol
Ich habe keine Ahnung was ich tue
quelle
quelle
Antworten:
ASCII und CRC schließen sich nicht gegenseitig aus. ASCII ist eine Codierung und CRC dient zur Fehlerprüfung.
ALLES kann als ASCII gesendet werden. Wir Alten erinnern uns sicherlich an UUEncoding, das alles in einen ASCII-String verwandelt.
A) Für mich ist es normalerweise eine Frage der Geschwindigkeit und Effizienz. Das Senden einer großen 32-Bit-Zahl per ASCII kann sehr lange dauern, es werden jedoch nur 4 Bytes benötigt, um sie als Binärdaten über ein serielles Protokoll zu senden.
B) Das Senden von ZAHLEN über ASCII bedeutet, dass Sie die Zahl in ASCII konvertieren müssen, was ein klarer zusätzlicher Schritt ist (dies ist ein Teil dessen, was "printf" tut).
Wenn Sie irgendwie Ihren Platz verlieren, Fehler machen, das Format verlieren, den falschen Endian erhalten usw., kann ein binäres Kommunikationsprotokoll sicherlich Fehler machen. Wenn Sie ASCII senden, kann es einfacher sein, Fehler zu beheben, indem Sie einfach in den Datenstrom schauen.
quelle
Hier einige Gedanken dazu:
quelle
Auf der einfachsten Ebene kann man sagen, dass ein einfaches Kommunikationsprotokoll drei Ebenen aufweist: physisch, Transport und Anwendung. (Es gibt Modelle mit mehr als OSI mit 7 oder TCP / IP mit 4. Die Anzahl der Schichten ist im Zusammenhang mit dieser Frage nicht besonders wichtig.)
Die Anwendungsebene ist die Ebene, mit der Sie sich direkt in Ihrem Code befassen, und der Fokus der Frage. Für die Transportschicht ist das Byte, das Sie in send_data an sie übergeben haben, nur ein binäres Muster. Sie können es jedoch in Ihrem Anwendungscode als den Buchstaben "A" interpretieren. Die CRC- oder Prüfsummenberechnung ist dieselbe, unabhängig davon, ob Sie das Byte als 'A', '0x41' oder '0b01000001' betrachten.
Die Transportschicht ist die Paketebene, auf der sich Ihre Nachrichtenköpfe befinden, und die Fehlerprüfung, ob es sich um eine CRC-Datei oder eine einfache Prüfsumme handelt. Im Zusammenhang mit Firmware haben Sie möglicherweise eine Funktion wie send_data, bei der Sie ein zu sendendes Byte übergeben. Innerhalb dieser Funktion wird es in ein Paket geschrieben, das sagt: "Hey, das ist eine normale Nachricht, erfordert eine Bestätigung, und die Prüfsumme ist 0x47, die aktuelle Zeit ist X." Dieses Paket wird über die physikalische Schicht an den empfangenden Knoten gesendet.
Auf der physischen Schicht werden die Elektronik und die Schnittstelle definiert: Anschlüsse, Spannungspegel, Timing usw. Diese Schicht kann von einigen Spuren reichen, auf denen TTL-Signale für einen Basis-UART auf einer Leiterplatte ausgeführt werden, bis zu einem vollständig isolierten differentiellen Paar, wie in einigen CAN- Implementierungen.
Auf dem empfangenden Knoten kommt das Paket auf der physischen Schicht an, wird auf der Transportschicht entpackt und dann steht Ihr Binärmuster der Anwendungsschicht zur Verfügung. Die Ebene der empfangenden Knotenanwendung muss wissen, ob dieses Muster als "A", "0x41" oder "0b01000001" interpretiert werden soll und was damit zu tun ist.
Zusammenfassend ist es so gut wie immer akzeptabel, ASCII-Zeichen zu senden, wenn die Anwendung dies erfordert. Das Wichtigste ist, Ihr Kommunikationsschema zu verstehen und einen Fehlerprüfungsmechanismus einzuschließen.
quelle
Ein Punkt, der noch nicht erwähnt wurde, ist, dass unabhängig davon, ob ASCII oder ein Binärprotokoll verwendet wird, das Senden eines Rub-Out-Zeichens vor jedem Paket sicherstellt, dass alle Zeichen nach dem Rub- Wenn kein weiteres Rauschen zu hören ist, wird out korrekt gerahmt. Wenn man andernfalls kontinuierlich Pakete sendet und keine Zeichen enthält, von denen garantiert wird, dass sie eine Resynchronisation erreichen, kann ein Fehler alles beschädigen, was bis zur nächsten Sendepause folgt. Das 0xFF-Zeichen ist nett, da es garantiert, dass jeder Empfänger das folgende Zeichen erneut synchronisieren kann.
(*) 0xFF - wird als Ausradieren bezeichnet, da jemand, der beim Schreiben von Daten auf ein Papierband ein fehlerhaftes Zeichen eingibt, die Taste "Rücklauf" drücken und auf Ausradieren klicken kann, um das fehlerhaft gestanzte Zeichen durch 0xFF zu ersetzen von den meisten Empfängern ignoriert werden).
quelle
Ein Vorteil des Sendens von ASCII-Zeichenfolgen besteht darin, dass die Steuercodes dann verwendet werden können, um den Beginn / das Ende einer Nachricht zu signalisieren. zB STX (char 2) und ETX (char 3) können die Übertragung starten und beenden. Alternativ können Sie einen einfachen Zeilenvorschub hinzufügen, um das Ende der Übertragung zu markieren.
Beim Senden von Binärdaten wird dies komplizierter, da kein bestimmtes Bitmuster für einen Steuercode reserviert werden kann (ohne zusätzlichen Aufwand oder Komplexität), da ein gültiges Datenbyte das gleiche Muster haben kann.
quelle
ASCII ist in Ordnung, ich benutze es in fast allen Projekten. Dies erleichtert das Debuggen bei der Überwachung des Ports erheblich und würde nur dann zu einem Problem werden, wenn viele Daten gesendet werden müssten.
Ein weiterer Bonus: Ich verwende serielle Funkgeräte, um Nachrichten zwischen Arduinos abzurufen, und ich kann einen seriellen Monitor verwenden, der an meinen Laptop angeschlossen ist, und Nachrichten einspeisen, um bestimmte Dinge geschehen zu lassen. Ideal zum Testen.
Das Senden von Dingen als Binärdatei ist nicht unmöglich zu debuggen. Abhängig von Ihren Tools können Sie die Binärdatei extrahieren und in eine für Menschen lesbare Datei konvertieren. Oder wenn Sie wissen, wonach Sie suchen, können Sie den Datenstrom visuell untersuchen und Werte erkennen, wo sie sein sollten, und auf diese Weise Fehler finden, wenn auch nicht so einfach. Sie erkennen also die Muster von Bytes und die erwarteten Werte
quelle
Anstelle von Modbus sollte HDLC in Betracht gezogen werden . Sie erhalten eine Fehlererkennung (was bei gestörten seriellen Leitungen wichtig ist). Die Synchronisation ist robust, die Flucht ist robust.
Ich habe HDLC in RS-485-Netzwerken ohne Probleme verwendet und PPP verwendet es auch.
quelle
ASCII über den UART ist zum Teil deshalb am beliebtesten, weil:
Es ist beim Debuggen von Menschen lesbar (ich habe noch keinen Logikanalysator gesehen, der ASCII nicht decodiert).
Die Implementierung ist sehr einfach. Sie haben eine gut standardisierte ASCII-Tabelle über QuickGoogle.
Es hat in Synchronisation mit den Start / Stopp-Bits gebaut.
Fast die gesamte Hobbyst-Welt hat sich mit ASCII über seriell eingerichtet, daher müssen sich alle neuen Methoden damit befassen, und das ist keineswegs einfach.
Dann geraten Sie in eine Situation, in der Sie mit dem Senden einer bestimmten Codierung beginnen, z. B. das Senden der In-Memory-Darstellung eines Floats im Vergleich zum Konvertieren eines Floats in ASCII, das Senden über eine serielle Schnittstelle, die weit über 4 Byte liegen kann, und das Zurückkonvertieren zu einer In-Memory-Darstellung auf dem Host. Stattdessen senden Sie einfach jedes Mal die 4-Byte-Darstellung. Natürlich können Sie die Codierung selbst vornehmen, aber dann müssen Sie Start- / End-Tags, Reihenfolge usw. einrichten.
Stattdessen können Dinge wie Protobuf verwendet werden. Dies wurde tatsächlich in einem Projekt verwendet, an dem ich gearbeitet habe, und es war äußerst vorteilhaft, es verarbeitet Nachrichten mit variabler Länge, verarbeitet Endian für Sie und ein paar andere coole Funktionen. Die Codegröße ist auch nicht so groß, und Sie können alles angeben, was beim Start statisch zugewiesen werden soll. Sie müssten jedoch selbst eine Prüfsumme eingeben, wenn Sie diese benötigen.
quelle