In Bezug auf die Arduino Uno, Mega2560, Leonardo und ähnliche Boards:
- Wie funktioniert die serielle Kommunikation?
- Wie schnell ist seriell?
- Wie verbinde ich einen Sender mit einem Empfänger?
Bitte beachten Sie: Dies ist eine Referenzfrage.
In Bezug auf die Arduino Uno, Mega2560, Leonardo und ähnliche Boards:
Bitte beachten Sie: Dies ist eine Referenzfrage.
Antworten:
Asynchrone serielle Kommunikation (normalerweise als serielle Kommunikation bezeichnet) wird zum Senden von Bytes von einem Gerät zu einem anderen verwendet. Ein Gerät kann eines oder mehrere der folgenden sein:
Im Gegensatz zu SPI / USB / I2C hat die serielle Kommunikation kein Taktsignal. Der Abtasttakt ist eine vereinbarte Abtastrate (bekannt als die Baudrate). Sowohl der Sender als auch der Empfänger müssen so konfiguriert sein, dass sie dieselbe Rate verwenden. Andernfalls empfängt der Empfänger bedeutungslose Daten (da die Bits nicht mit derselben Rate abgetastet werden, mit der sie gesendet wurden).
Die Übertragung ist asynchron, was im Grunde bedeutet, dass Bytes jederzeit mit unterschiedlichen Lücken zwischen ihnen gesendet werden können. Diese Grafik zeigt ein einzelnes Byte, das gesendet wird:
Die obige Grafik zeigt den übertragenen Buchstaben 'F'. In ASCII ist dies 0x46 (in hex) oder 0b01000110 (in binär). Die am wenigsten signifikant (niedrige Ordnung) Bit wird zuerst übertragen, so dass in der obigen Grafik , um die Bits zu sehen in der Reihenfolge der Ankunft: 01100010
.
Die "Leerlauf" -Zeit zwischen Bytes wird als kontinuierliche "1" -Bits übertragen (effektiv wird die Übertragungsleitung kontinuierlich hochgehalten).
Um den Beginn eines Bytes anzuzeigen, wird das Startbit immer durch Ziehen der Linie nach unten angezeigt, wie in der Grafik dargestellt. Sobald der Empfänger das Startbit sieht, wartet er auf das 1,5-fache der Abtastzeit und tastet dann die Datenbits ab. Es wartet 1,5 mal damit es:
Wenn die Baudrate beispielsweise 9600 Baud beträgt, beträgt die Abtastrate 1/9600 = 0.00010416
Sekunden (104,16 µs).
Somit wartet der Empfänger bei 9600 Baud nach dem Empfang eines Startbits auf 156,25 us und tastet dann alle 104,16 us ab.
Der Zweck des Stoppbits besteht darin, sicherzustellen, dass definitiv ein 1-Bit zwischen jedem Byte liegt. Wenn ein Byte ohne das Stoppbit mit einer Null endet, ist es für die Hardware unmöglich, den Unterschied zwischen diesem und dem Startbit des nächsten Bytes zu erkennen.
Um die obige Ausgabe auf einem Uno zu erzeugen, könnten Sie diesen Code schreiben:
void setup()
{
Serial.begin(9600);
Serial.print("F");
}
void loop ()
{
}
Um Übertragungszeit zu sparen (früher), durften Sie unterschiedlich viele Datenbits angeben. Die AtMega-Hardware unterstützt Datenbits mit einer Nummerierung von 5 bis 9. Je weniger Datenbits Sie senden können, desto weniger Informationen können Sie senden, aber desto schneller.
Sie können optional ein Paritätsbit haben. Dies wird bei Bedarf berechnet, indem die Anzahl der Einsen im Zeichen gezählt wird und dann sichergestellt wird, dass diese Anzahl ungerade oder gerade ist, indem das Paritätsbit nach Bedarf auf 0 oder 1 gesetzt wird.
Beispielsweise können Sie für den Buchstaben "F" (oder 0x46 oder 0b01000110) sehen, dass es dort 3 gibt (in 01000110). Somit haben wir bereits eine ungerade Parität. Das Paritätsbit wäre also wie folgt:
Das Paritätsbit erscheint, falls vorhanden, nach dem vorletzten Datenbit vor dem Stoppbit.
Wenn der Empfänger nicht das richtige Paritätsbit erhält, spricht man von einem "Paritätsfehler". Dies weist darauf hin, dass ein Problem vorliegt. Möglicherweise sind Sender und Empfänger so konfiguriert, dass sie unterschiedliche Baudraten (Bitraten) verwenden, oder es gab Rauschen auf der Leitung, das eine Null in eine Eins verwandelte, oder umgekehrt.
Einige frühe Systeme verwendeten auch "Mark" -Parität (wobei das Paritätsbit unabhängig von den Daten immer 1 war) oder "Space" -Parität (wobei das Paritätsbit unabhängig von den Daten immer 0 war).
Einige Kommunikationsgeräte verwenden 9-Bit-Daten. In diesen Fällen wird das Paritätsbit in das 9. Bit umgewandelt. Es gibt spezielle Techniken zum Senden dieses 9. Bits (die Register sind 8-Bit-Register, so dass das 9. Bit an einer anderen Stelle abgelegt werden muss).
Frühe Geräte tendierten dazu, elektronisch etwas langsamer zu sein. Um dem Empfänger Zeit für die Verarbeitung des eingehenden Bytes zu geben, wurde manchmal festgelegt, dass der Sender zwei Stoppbits sendet. Dies fügt im Grunde genommen mehr Zeit hinzu, wenn die Datenleitung hoch gehalten wird (eine weitere Bitzeit), bevor das nächste Startbit erscheinen kann. Diese zusätzliche Bitzeit gibt dem Empfänger Zeit, das letzte eingehende Byte zu verarbeiten.
Wenn der Empfänger keine logische 1 erhält, wenn das Stoppbit sein soll, wird dies als "Rahmenfehler" bezeichnet. Dies weist darauf hin, dass ein Problem vorliegt. Möglicherweise sind Sender und Empfänger so konfiguriert, dass sie unterschiedliche Baudraten (Bitraten) verwenden.
In der Regel wird die serielle Kommunikation folgendermaßen angegeben: Geschwindigkeit, Anzahl der Datenbits, Art der Parität und Anzahl der Stoppbits.
9600/8-N-1
Das sagt uns:
Es ist wichtig, dass sich Absender und Empfänger einig sind. Andernfalls ist es unwahrscheinlich, dass die Kommunikation erfolgreich ist.
Der Arduino Uno verfügt über die digitalen Pins 0 und 1 für die Hardware-Seriennummer:
Um zwei Arduinos Sie tauschen Tx und Rx wie folgt aus :
Ein breiter Geschwindigkeitsbereich wird unterstützt (siehe Grafik unten). "Standard" -Geschwindigkeiten sind normalerweise ein Vielfaches von 300 Baud (z. B. 300/600/1200/2400 usw.).
Andere "nicht standardmäßige" Geschwindigkeiten können durch Einstellen der entsprechenden Register gehandhabt werden. Die HardwareSerial-Klasse erledigt dies für Sie. z.B.
Serial.begin (115200); // set speed to 115200 baud
Als Faustregel gilt, dass Sie unter der Annahme, dass Sie 8-Bit-Daten verwenden, die Anzahl der Bytes schätzen können, die Sie pro Sekunde übertragen können, indem Sie die Baudrate durch 10 dividieren (aufgrund des Startbits und des Stoppbits).
Somit können Sie bei 9600 Baud 960 Bytes ( 9600 / 10 = 960
) pro Sekunde übertragen.
Die Baudrate des Atmega wird durch Herunterteilen der Systemuhr und anschließendes Hochzählen auf eine voreingestellte Zahl erzeugt. Diese Tabelle aus dem Datenblatt zeigt die Registerwerte und Fehlerprozentsätze für einen 16-MHz-Takt (wie den auf dem Arduino Uno).
Das U2Xn-Bit wirkt sich auf den Taktteiler aus (0 = Division durch 16, 1 = Division durch 8). Das UBRRn-Register enthält die Nummer, bis zu der der Prozessor zählt.
In der obigen Tabelle sehen wir also, dass wir 9600 Baud von einem 16-MHz-Takt wie folgt erhalten:
16000000 / 16 / 104 = 9615
Wir teilen durch 104 und nicht durch 103, da der Zähler relativ zu Null ist. Der Fehler liegt hier also in 15 / 9600 = 0.0016
der Nähe der obigen Tabelle (0,02%).
Sie werden feststellen, dass einige Baudraten eine höhere Fehlermenge aufweisen als andere.
Laut Datenblatt liegt die maximale Fehlerquote für 8 Datenbits im Bereich von 1,5% bis 2,0% (siehe Datenblatt für weitere Details).
Arduino Leonardo und Micro verfolgen einen anderen Ansatz für die serielle Kommunikation, da sie direkt über USB und nicht über den seriellen Port mit dem Host-Computer verbunden sind.
Aus diesem Grund müssen Sie warten, bis Serial "bereit" ist (wenn die Software eine USB-Verbindung herstellt).
void setup()
{
Serial.begin(115200);
while (!Serial)
{} // wait for Serial comms to become ready
Serial.print("Fab");
}
void loop ()
{
}
Wenn Sie jedoch tatsächlich über die Pins D0 und D1 kommunizieren möchten (anstatt über das USB-Kabel), müssen Sie Serial1 anstelle von Serial verwenden. Du machst das so:
void setup()
{
Serial1.begin(115200);
Serial1.print("Fab");
}
void loop ()
{
}
Beachten Sie, dass der Arduino TTL-Pegel für die serielle Kommunikation verwendet. Dies bedeutet, dass es erwartet:
Ältere serielle Geräte, die zum Anschluss an die serielle Schnittstelle eines PCs entwickelt wurden, verwenden wahrscheinlich RS232-Spannungspegel, und zwar:
Dies ist nicht nur in Bezug auf TTL-Pegel "invertiert" (eine "Eins" ist negativer als eine "Null"), der Arduino kann auch keine negativen Spannungen an seinen Eingangspins verarbeiten (noch positive Spannungen über 5 V).
Daher benötigen Sie eine Schnittstellenschaltung für die Kommunikation mit solchen Geräten. Nur für den Eingang (zum Arduino) reichen ein einfacher Transistor, eine Diode und ein paar Widerstände aus:
Für die bidirektionale Kommunikation müssen Sie in der Lage sein, negative Spannungen zu erzeugen, sodass eine komplexere Schaltung erforderlich ist. Zum Beispiel wird der MAX232-Chip dies in Verbindung mit vier 1-µF-Kondensatoren tun, um als Ladungspumpenkreise zu fungieren.
Es gibt eine Bibliothek namens SoftwareSerial, mit der Sie serielle Kommunikationen (bis zu einem gewissen Punkt) in Software und nicht in Hardware durchführen können. Dies hat den Vorteil, dass Sie für die serielle Kommunikation unterschiedliche Pin-Konfigurationen verwenden können. Der Nachteil ist, dass die serielle Ausführung in Software prozessorintensiver und fehleranfälliger ist. Weitere Informationen finden Sie unter Software Serial .
Das Arduino "Mega" verfügt über 3 zusätzliche serielle Hardware-Ports. Sie sind auf der Platine als Tx1 / Rx1, Tx2 / Rx2, Tx3 / Rx3 gekennzeichnet. Sie sollten nach Möglichkeit anstelle von SoftwareSerial verwendet werden. Um diese anderen Ports zu öffnen, verwenden Sie die Namen Serial1, Serial2, Serial3 wie folgt:
Serial1.begin (115200); // start hardware serial port Tx1/Rx1
Serial2.begin (115200); // start hardware serial port Tx2/Rx2
Serial3.begin (115200); // start hardware serial port Tx3/Rx3
Sowohl das Senden als auch das Empfangen unter Verwendung der HardwareSerial-Bibliothek verwenden Interrupts.
Wenn Sie a ausführen Serial.print
, werden die Daten, die Sie drucken möchten, in einem internen "Sendepuffer" abgelegt. Wenn Sie über 1024 Byte oder mehr RAM verfügen (z. B. auf dem Uno), erhalten Sie einen 64-Byte-Puffer, andernfalls erhalten Sie einen 16-Byte-Puffer. Wenn der Puffer Platz hat, Serial.print
kehrt der Code sofort zurück und verzögert den Code nicht. Wenn kein Platz vorhanden ist, wird "blockiert", bis der Puffer so weit geleert ist, dass Platz vorhanden ist.
Wenn dann jedes Byte von der Hardware übertragen wird, wird ein Interrupt aufgerufen (der "USART, Data Register Empty" -Interrupt) und die Interruptroutine sendet das nächste Byte aus dem Puffer aus dem seriellen Port.
Wenn ankommende Daten empfangen werden, wird eine Interruptroutine aufgerufen (der "USART Rx Complete" -Interrupt) und das ankommende Byte wird in einen "Empfangs" -Puffer (mit der gleichen Größe wie der oben erwähnte Sendepuffer) gestellt.
Wenn Sie anrufen Serial.available
, erfahren Sie, wie viele Bytes in diesem Empfangspuffer verfügbar sind. Beim Aufruf wird Serial.read
ein Byte aus dem Empfangspuffer entfernt und an Ihren Code zurückgegeben.
Auf Arduinos mit 1000 Bytes oder mehr RAM gibt es keine Eile, Daten aus dem Empfangspuffer zu entfernen, vorausgesetzt, Sie lassen sie nicht voll werden. Wenn es voll ist, werden alle weiteren eingehenden Daten verworfen.
Beachten Sie, dass es aufgrund der Größe dieses Puffers keinen Sinn macht, auf das Eintreffen einer sehr großen Anzahl von Bytes zu warten. Beispiel:
while (Serial.available () < 200)
{ } // wait for 200 bytes to arrive
Dies wird niemals funktionieren, da der Puffer nicht so viel aufnehmen kann.
Stellen Sie vor dem Lesen immer sicher, dass Daten verfügbar sind. Zum Beispiel ist das falsch:
if (Serial.available ())
{
char a = Serial.read ();
char b = Serial.read (); // may not be available
}
Der Serial.available
Test stellt nur sicher, dass Sie über ein Byte verfügen , der Code versucht jedoch, zwei zu lesen. Es kann funktionieren, wenn sich zwei Bytes im Puffer befinden. Andernfalls wird -1 zurückgegeben, was beim Drucken wie 'ÿ' aussieht.
Beachten Sie, wie lange das Senden von Daten dauert. Wie oben erwähnt, werden bei 9600 Baud nur 960 Bytes pro Sekunde übertragen, sodass der Versuch, 1000 Messwerte von einem analogen Port bei 9600 Baud zu senden, nicht sehr erfolgreich ist.