Como o Arduino lida com o estouro de buffer serial? Joga fora os dados mais recentes ou os mais antigos? Quantos bytes o buffer pode conter?
Como o Arduino lida com o estouro de buffer serial? Joga fora os dados mais recentes ou os mais antigos? Quantos bytes o buffer pode conter?
Respostas:
Para portas seriais de hardware, você pode ver no HardwareSerial.cpp que o tamanho do buffer varia dependendo da quantidade de RAM disponível no AVR específico:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Para uma porta serial de software no SoftwareSerial.h, o tamanho do buffer do receptor _SS_MAX_RX_BUFF
é definido como 64 bytes. Nos dois casos, ele pára de tentar inserir os dados recebidos na fila quando está cheio, para que você possa misturar os dados antigos e os novos, dependendo de como está recuperando dados da fila.
Idealmente, seria melhor garantir que o buffer sempre seja esvaziado rapidamente, para evitar o preenchimento do buffer. Talvez dê uma olhada nos temporizadores e na implementação de uma máquina de estado simples se o seu problema estiver relacionado a outro código que bloqueia o loop principal.
Você pode ver na fonte do HardwareSerial que, se um byte recebido encontrar o buffer de anel cheio, ele será descartado:
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;
}
}
Tenho a impressão de que se eu transmitir dados para o Arduino e não tiver um "extrator" ativo de dados no lado do Arduino, se houver mais dados que possam caber no buffer, eles serão descartados. Você pode confirmar isso?
Sim, será descartado. Não há controle de fluxo de software ou hardware, a menos que você implemente o seu.
No entanto, com um buffer de 64 bytes e recebendo dados em (digamos) 9600 baud, você recebe um byte a cada 1,04 ms e, portanto, leva 66,6 ms para preencher o buffer. Em um processador de 16 MHz, você deve poder verificar o buffer com freqüência suficiente para que ele não encha. Tudo o que você realmente precisa fazer é mover os dados do buffer HardwareSerial para o seu, se você não quiser processá-los agora.
Você pode ver pela #if (RAMEND < 1000)
verificação de que os processadores com mais de 1000 bytes de RAM obtêm o buffer de 64 bytes, e aqueles com menos RAM obtêm o buffer de 16 bytes.
Os dados que você escreve são colocados em um buffer do mesmo tamanho (16 ou 64 bytes). No caso de envio, se o buffer preencher os "blocos" de código, aguarde uma interrupção para enviar o próximo byte pela porta serial.
Se as interrupções forem desativadas, isso nunca acontecerá, portanto, você não fará impressões seriais dentro de uma rotina de serviço de interrupção.
1/960 = 0.001042 s
- esse é um byte a cada 1,04 ms.