Wie geht der Arduino mit einem seriellen Pufferüberlauf um? Wirft es die neuesten eingehenden Daten oder die ältesten weg? Wie viele Bytes kann der Puffer aufnehmen?
Wie geht der Arduino mit einem seriellen Pufferüberlauf um? Wirft es die neuesten eingehenden Daten oder die ältesten weg? Wie viele Bytes kann der Puffer aufnehmen?
Antworten:
Bei seriellen Hardware-Ports können Sie in HardwareSerial.cpp sehen, dass die Puffergröße abhängig von der auf dem jeweiligen AVR verfügbaren RAM-Größe variiert:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Für einen seriellen Software-Port in SoftwareSerial.h ist die Puffergröße des Empfängers _SS_MAX_RX_BUFF
mit 64 Byte definiert. In beiden Fällen wird der Versuch, empfangene Daten in die Warteschlange einzufügen, abgebrochen, wenn sie voll sind, sodass Sie eine Mischung aus alten und neuen Daten erhalten können, je nachdem, wie Sie Daten aus der Warteschlange abrufen.
Im Idealfall sollte sichergestellt werden, dass der Puffer immer rechtzeitig geleert wird, um ein Füllen des Puffers zu vermeiden. Vielleicht werfen Sie einen Blick auf Timer und implementieren eine einfache Zustandsmaschine, wenn Ihr Problem mit anderem Code zusammenhängt, der die Hauptschleife blockiert.
An der Quelle von HardwareSerial können Sie erkennen, dass ein eingehendes Byte verworfen wird, wenn es den Ringpuffer voll findet:
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
Ich habe den Eindruck, dass, wenn ich Daten an das Arduino übertrage und auf der Arduino-Seite keinen aktiven "Puller" für Daten habe, wenn mehr Daten ankommen, als in den Puffer passen, diese verworfen werden. Kannst du das bestätigen?
Ja, es wird verworfen. Es gibt keine Software- oder Hardware-Flusskontrolle, es sei denn, Sie implementieren Ihre eigene.
Mit einem 64-Byte-Puffer und Datenempfang bei (sagen wir) 9600 Baud erhalten Sie jedoch alle 1,04 ms ein Byte, und daher sind 66,6 ms erforderlich, um den Puffer zu füllen. Auf einem 16-MHz-Prozessor sollte es möglich sein, den Puffer häufig genug zu überprüfen, damit er nicht voll wird. Alles, was Sie wirklich tun müssen, ist, die Daten aus dem HardwareSerial-Puffer in Ihren eigenen zu verschieben, wenn Sie sie jetzt nicht verarbeiten möchten.
Sie können #if (RAMEND < 1000)
anhand der Überprüfung feststellen, dass Prozessoren mit mehr als 1000 Byte RAM den 64-Byte-Puffer erhalten, während Prozessoren mit weniger RAM den 16-Byte-Puffer erhalten.
Daten, die Sie schreiben, werden in einem Puffer gleicher Größe (16 oder 64 Byte) abgelegt. Im Falle des Sendens, wenn der Puffer den Code füllt, "blockiert" das Warten auf einen Interrupt, um das nächste Byte über die serielle Schnittstelle zu senden.
Wenn Interrupts deaktiviert sind, geschieht dies niemals. Sie führen also keine seriellen Drucke innerhalb einer Interrupt-Serviceroutine durch.
1/960 = 0.001042 s
- das ist ein Byte alle 1,04 ms.