Existem vários fatores aqui:
- Qual a taxa de transmissão que o ATmega328P MCU pode atingir?
- Qual o nível de taxa de transmissão que a interface USB-Serial pode atingir?
- Qual é a frequência do oscilador no ATmega328P?
- Qual é a frequência do oscilador na interface serial USB (se houver uma)?
- Quão tolerante é a interface serial USB da incompatibilidade da taxa de transmissão?
Todos esses fatores são relevantes para determinar a taxa de transmissão máxima alcançável. O ATmega328P usa um divisor de hardware de sua taxa de clock para gerar o clock base para a interface serial. Se não houver uma taxa inteira entre o relógio principal e o tempo de bit da taxa de transmissão desejada, o MCU não poderá produzir exatamente a taxa desejada. Isso pode levar a possíveis problemas, pois alguns dispositivos são muito mais sensíveis à incompatibilidade da taxa de transmissão do que outros.
As interfaces baseadas em FTDI são bastante tolerantes à incompatibilidade da taxa de transmissão, até vários por cento de erro. No entanto, trabalhei com módulos GPS incorporados especializados que não conseguiam lidar nem com um erro de taxa de transmissão de 0,5%.
Interfaces seriais gerais são tolerantes a ~ 5% de erro na taxa de transmissão. No entanto, como cada extremidade pode ser desativada, uma especificação mais comum é + -2,5%. Dessa forma, se uma extremidade for 2,5% rápida e a outra 2,5% lenta, seu erro geral ainda será de apenas 5%.
Em todo o caso. O Uno usa um ATmega328P como o MCU principal e um ATmega16U2 como a interface serial USB. Também temos a sorte de que esses dois MCUs usem USARTs de harware semelhantes e relógios de 16 Mhz.
Como os dois MCUs têm o mesmo harware e taxa de clock, ambos terão o mesmo erro de taxa de transmissão na mesma direção, para que possamos ignorar funcionalmente o problema do erro de transmissão.
De qualquer forma, a resposta "adequada" a essa pergunta envolveria desenterrar a fonte do ATmega16U2 e elaborar as possíveis taxas de transmissão a partir daí, mas, como sou preguiçoso, acho que testes simples e empíricos funcionarão.
Uma rápida olhada na folha de dados do ATmega328P produz a seguinte tabela:
Portanto, considerando a taxa de transmissão máxima declarada de 2 Mbps, escrevi um programa de teste rápido:
void setup(){};
void loop()
{
delay(1000);
Serial.begin(57600);
Serial.println("\r\rBaud-rate = 57600");
delay(1000);
Serial.begin(76800);
Serial.println("\r\rBaud-rate = 76800");
delay(1000);
Serial.begin(115200);
Serial.println("\r\rBaud-rate = 115200");
delay(1000);
Serial.begin(230400);
Serial.println("\r\rBaud-rate = 230400");
delay(1000);
Serial.begin(250000);
Serial.println("\r\rBaud-rate = 250000");
delay(1000);
Serial.begin(500000);
Serial.println("\r\rBaud-rate = 500000");
delay(1000);
Serial.begin(1000000);
Serial.println("\r\rBaud-rate = 1000000");
delay(1000);
Serial.begin(2000000);
Serial.println("\r\rBaud-rate = 2000000");
};
E então olhando para a porta serial relevante com um terminal serial:
Parece que o hardware pode rodar a 2.000.000 de bauds sem problemas.
Observe que essa taxa de transmissão fornece apenas ciclos de clock do MCU 64 80 por byte; portanto, seria muito desafiador manter a interface serial ocupada. Embora os bytes individuais possam ser transferidos muito rapidamente, é provável que haja muito tempo quando a interface estiver simplesmente ociosa.
Edit: Teste Real!
Os 2 Mbps são reais:
cada bit-time é de 500 ns, o que corresponde exatamente ao esperado.
Problemas de desempenho! Comprimento total do pacote:
500 Kbaud:
1 Mbaud:
2 Mbaud:
Nota: O overshoot perceptível se deve a práticas inadequadas de aterramento da sonda e provavelmente não é real. Estou usando o chumbo de clipe de terra que faz parte da minha sonda de escopo, e a indutância de chumbo provavelmente é a causa da maioria dos excedentes.
Como você pode ver, o comprimento total da transmissão é o mesmo para 0,5, 1 e 2 Mbaud. Isso ocorre porque o código que está colocando os bytes no buffer serial é pouco otimizado. Como tal, você nunca alcançará nada melhor do que um eficaz 500 Kbaud, a menos que escreva suas próprias bibliotecas seriais. As bibliotecas do Arduino são muito otimizadas, portanto, provavelmente não seria muito difícil obter um 2 Mbaud adequado, pelo menos para transmissões intermitentes, se você gastasse um pouco de tempo com isso.