¿Cómo maneja el Arduino el desbordamiento del búfer en serie? ¿Tira los datos entrantes más nuevos o los más antiguos? ¿Cuántos bytes puede contener el búfer?
¿Cómo maneja el Arduino el desbordamiento del búfer en serie? ¿Tira los datos entrantes más nuevos o los más antiguos? ¿Cuántos bytes puede contener el búfer?
Respuestas:
Para los puertos seriales de hardware, puede ver en HardwareSerial.cpp que el tamaño del búfer varía según la cantidad de RAM disponible en el AVR particular:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Para un puerto serie de software en SoftwareSerial.h, el tamaño del búfer del receptor _SS_MAX_RX_BUFF
se define como 64 bytes. En ambos casos, deja de intentar insertar los datos recibidos en la cola cuando está llena, por lo que puede obtener una combinación de datos antiguos y nuevos dependiendo de cómo esté recuperando los datos de la cola.
Idealmente, sería mejor asegurarse de que el búfer siempre se vacíe de manera rápida para evitar el llenado del búfer. Quizás eche un vistazo a los temporizadores e implemente una máquina de estado simple si su problema está relacionado con otro código que bloquea el bucle principal.
Puede ver desde la fuente de HardwareSerial que si un byte entrante encuentra que el búfer de anillo está lleno, se descarta:
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;
}
}
Tengo la impresión de que si transmito datos al Arduino y no tengo un "extractor" activo de datos en el lado de Arduino, si llegan más datos de los que pueden caber en el búfer, se descartarán. ¿Puedes confirmar eso?
Sí, será descartado. No hay control de flujo de software o hardware, a menos que implemente el suyo.
Sin embargo, con un búfer de 64 bytes y recibiendo datos a (digamos) 9600 baudios, obtienes un byte cada 1.04 ms y, por lo tanto, se necesitan 66.6 ms para llenar el búfer. En un procesador de 16 MHz, debería poder verificar el búfer con la frecuencia suficiente para que no se llene. Todo lo que realmente tiene que hacer es mover los datos del búfer de HardwareSerial a los suyos, si no desea procesarlos en este momento.
Puede ver en la #if (RAMEND < 1000)
verificación que los procesadores con más de 1000 bytes de RAM obtienen el búfer de 64 bytes, los que menos RAM obtienen el búfer de 16 bytes.
Los datos que escribe se colocan en un búfer del mismo tamaño (16 o 64 bytes). En el caso de enviar si el búfer llena el código "bloquea" esperando una interrupción para enviar el siguiente byte al puerto serie.
Si las interrupciones están desactivadas, esto nunca sucederá, por lo que no debe realizar impresiones en serie dentro de una rutina de servicio de interrupción.
1/960 = 0.001042 s
- eso es un byte cada 1.04 ms.