Quanto posso raggiungere un baud rate (senza errori)?


40

Lo standard è 9600 baud. Questo è solo lo standard . Utilizzando un Arduino Uno SMD R2, qual è il baud rate più alto che posso ottenere?

Punti bonus per l'audace: come faresti per creare un meccanismo di controllo degli errori e quindi aumentare il baud rate ridicolmente alto per ottenere alte velocità di trasferimento?


2
Vale la pena notare che le schede Arduino che utilizzano CI seriali USB FTDI possono essere REALMENTE veloci. Il comune FT232 può andare a 3 Megabaud (ovvero 3.000.000 di baud) senza problemi. L'uso di un ATmega16U2 è il fattore limitante.
Connor Wolf,

1
Il mio clone Arduino Nano che ho ricevuto da eBay ha raggiunto il massimo a 1.099.999. Sul serio. Lo ha fatto. Una volta raggiunti 1.100.000, l'output è stato confuso. laqq`na`fca`fga`fga`bcngaah````iin`ha`a`a`bga`fga`bcqpahhqfq```fh`oopa`bca`fca. Utilizza un chip CH340 per le comunicazioni USB.
PNDA,

Risposte:


59

Ci sono diversi fattori qui:

  • Quanto può raggiungere un baud rate con la MCU ATmega328P?
  • Quanto è alta la velocità di trasmissione dell'interfaccia USB-seriale?
  • Qual è la frequenza dell'oscillatore sull'ATmega328P?
  • Qual è la frequenza dell'oscillatore sull'interfaccia seriale USB (se ne ha una)?
  • Quanto è tollerata l'interfaccia USB-seriale della discrepanza di baud rate?

Tutti questi fattori sono rilevanti per determinare il baud rate massimo raggiungibile. ATmega328P utilizza un divisore hardware dalla frequenza di clock per generare il clock di base per l'interfaccia seriale. Se non esiste un rapporto intero tra il clock principale e il bit-time della velocità di trasmissione desiderata, l'MCU non sarà in grado di produrre esattamente la velocità desiderata. Ciò può portare a potenziali problemi, poiché alcuni dispositivi sono molto più sensibili alla discrepanza di baud rate rispetto ad altri.

Le interfacce basate su FTDI sono abbastanza tolleranti nei confronti della discrepanza di baud rate, con errori fino a diversi percento. Tuttavia, ho lavorato con moduli GPS integrati specializzati che non sono stati in grado di gestire nemmeno un errore di baud rate dello 0,5%.

Le interfacce seriali generali tollerano un errore di baud rate del 5% circa. Tuttavia, poiché ciascuna estremità può essere disattivata, una specifica più comune è + -2,5%. In questo modo, se un'estremità è veloce al 2,5% e l'altra è lenta al 2,5%, l' errore complessivo è ancora solo del 5%.


In ogni modo. Uno utilizza un ATmega328P come MCU primario e un ATmega16U2 come interfaccia seriale USB. Siamo anche fortunati qui che entrambi questi MCU utilizzano USART harware simili, nonché orologi da 16 Mhz.

Poiché entrambi gli MCU hanno lo stesso hardware e frequenza di clock, entrambi avranno lo stesso errore di baud rate nella stessa direzione, quindi possiamo ignorare funzionalmente il problema di errore di baud.

Ad ogni modo, la risposta "corretta" a questa domanda implicherebbe la ricerca della fonte per l'ATmega16U2 e la determinazione dei possibili baud rate da lì, ma dato che sono pigro, immagino che test empirici semplici funzioneranno.

Una rapida occhiata alla scheda tecnica ATmega328P produce la seguente tabella:
inserisci qui la descrizione dell'immagine

Quindi, dato il baud rate massimo dichiarato di 2 Mbps, ho scritto un programma di test rapido:

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 poi guardando la porta seriale pertinente con un terminale seriale:

inserisci qui la descrizione dell'immagine

Quindi sembra che l'hardware possa funzionare a 2.000.000 di baud senza problemi.

Si noti che questa velocità di trasmissione fornisce all'MCU 64 80 cicli di clock per byte, quindi sarebbe molto difficile mantenere occupata l'interfaccia seriale. Mentre i singoli byte possono essere trasferiti molto rapidamente, è probabile che ci sia molto tempo quando l'interfaccia è semplicemente inattiva.


Modifica: test effettivi!

I 2 Mbps sono reali:
inserisci qui la descrizione dell'immagine
ogni bit-time è di 500 ns, che corrisponde esattamente a quanto previsto.

Problemi di prestazione! Lunghezza complessiva del pacchetto:
500 Kbaud: inserisci qui la descrizione dell'immagine

1 MBaud: inserisci qui la descrizione dell'immagine

2 Mbaud: inserisci qui la descrizione dell'immagine
Nota: il notevole superamento è dovuto a cattive pratiche di messa a terra della sonda dell'oscilloscopio e probabilmente non è reale. Sto usando il cavo di massa che fa parte della mia sonda dell'oscilloscopio e l'induttanza del cavo è probabilmente la causa della maggior parte del superamento.

Come puoi vedere, la lunghezza totale della trasmissione è la stessa per 0,5, 1 e 2 MBaud. Questo perché il codice che inserisce i byte nel buffer seriale è scarsamente ottimizzato. Come tale, non otterrai mai niente di meglio di un efficace 500 Kbaud, a meno che tu non scriva le tue librerie seriali. Le librerie di Arduino sono scarsamente ottimizzate, quindi probabilmente non sarebbe troppo difficile ottenere 2 Mbaud adeguati, almeno per le trasmissioni a raffica, se ci passassi un po 'di tempo.


4
Bella illustrazione della limitazione della velocità effettiva!
jippie,

1
@AnnonomusPerson - Se passi a un orologio da 20 Mhz, puoi fare 2,5 Mbps.
Connor Wolf,

1
@AnnonomusPerson - Dovresti scambiare entrambi o utilizzare un'interfaccia seriale USB FTDI con un oscillatore ATmega328P da 20 Mhz. L'ATmega328P non può fare 2,5 Mbps senza un risonatore / cristallo da 20 Mhz. Lo stesso vale per qualsiasi interfaccia ATmega16U2.
Connor Wolf,

1
Bella risposta! Solo una piccola correzione: a 2 Mb / s, ogni trasmissione di byte richiede 80 cicli di CPU, non 64. Questo perché, nel tempo, ogni byte vale 10 bit (1 avvio, 8 dati, 1 arresto).
Edgar Bonet,

1
@ linhartr22 - I cavi entrano davvero in gioco solo se sono lunghi , come in 12 "+. Penso che sia probabilmente improbabile che troppe persone stiano usando troppi cavi lunghi 100 piedi. Inoltre, la domanda era: quanto è alto l' arduino / ATmega il baud rate può andare, non quanto può arrivare un gruppo di cavi arbitrario.
Connor Wolf

7

La finestra di monitoraggio seriale Arduino ti limita a 115200, ma non è la velocità di trasmissione più elevata. Puoi leggere i fogli dati Atmel e FT232 (o qualunque cosa tu stia utilizzando) per scoprire il massimo, ma sono in grado di utilizzare con successo 230400 (due volte più veloce del più grande supportato dal monitor seriale Arduino) senza problemi.

Se vuoi vedere i risultati sul tuo computer, avrai bisogno di un altro monitor seriale che supporti altre opzioni di baud rate. Mi piacciono CoolTerm e Termite .

Nota che questo dipende fortemente anche dalla velocità del tuo clock.

Ecco una calcolatrice per aiutarti a calcolare ciò che è possibile.


Quando inizi ad andare sempre più veloce, la limitazione diventa la libreria seriale - la sua implementazione non è molto efficiente.
Cybergibbons,

il sito web del link è morto
Codebeat

3

Questo è probabilmente uno dei pochi aspetti in cui le schede el-Cheapo differiscono dalle schede originali. La velocità massima di trasferimento seriale è praticamente limitata solo dalla qualità della scheda e dal suo layout. Una volta che i dati seriali entrano nel chip di interfaccia AVR o USB, i dati verranno elaborati in modo diverso dal protocollo UART seriale.

Tenere presente, tuttavia, che il microcontrollore dispone di hardware di base per spostare in / out i dati seriali da / verso i pin IO, ma la frequenza massima assoluta è limitata al clock a 16 MHz (per gli AVR). Una volta che un byte viene spostato nel buffer seriale, l'hardware UART subentra e spinge / estrae i bit da solo. Un AVR raggiunge al massimo 16 M di istruzioni al secondo e gli interrupt utilizzati per riempire il buffer seriale hanno un certo sovraccarico (almeno 8 tick di clock per la gestione degli interrupt + istruzioni per salvare lo stato corrente + diverse istruzioni per riempire effettivamente il buffer). A un dato bitrate, il protocollo verrà eseguito a n bit netti al secondo, ma il controller ha bisogno di più tempo per riempire il buffer seriale di quanto non sia effettivamente necessario per l'output dei dati, con un throughput medio inferiore a quello previsto e l'idle UART per un tempo relativamente lungo.

Un altro effetto da ricordare è che tutto l'overhead necessario per inviare i dati su UART (o estrarli) non può essere speso nel tuo programma reale, influenzando nuovamente il throughput pratico medio. È possibile utilizzare ogni ciclo di istruzioni una sola volta, sia per riempire il buffer sia per calcolare il ciclo principale.

Il throughput massimo dipende quindi dall'applicazione utilizzata (la velocità con cui i dati vengono generati / calcolati / pronti per passare al / dal buffer seriale) e l'effettivo bitrate 'fisico' è solo una piccola parte della decisione di progettazione.


1
Davvero, VERAMENTE, dubito che una qualsiasi delle schede in circolazione abbia problemi di layout abbastanza gravi da impedire che un segnale da 2 Mhz funzioni correttamente. 2 Mhz non sono esattamente ad alta frequenza.
Connor Wolf,

@FakeName Almeno una scheda sulla mia scrivania qui ha aumentato il BER quando spingo la velocità seriale. Di solito uso 9600, che è più che sufficiente per la maggior parte delle applicazioni ed è robusto.
jippie,

Non scherzo! Huh. Mi chiedo quanto deve essere brutto il layout perché ciò accada? Tuttavia, sospetto che non sia un layout tanto quanto risonatori / cristalli a bassa tolleranza.
Connor Wolf,

1
I baud rate elevati, in particolare se U2Xn = 1nell'USART, tendono a diventare piuttosto irritabili riguardo alla mancata corrispondenza.
Connor Wolf,

@FakeName Sono un dinosauro, mi piace un po '"9600 8N1" per tutti i motivi dell'eredità sbagliati che ti vengono in mente; o)
jippie,

2

Il controllo degli errori è in realtà molto semplice e c'è una libreria AVR che lo fa in una riga.

Continua a leggere util/crc16.he dovresti essere pronto a non perdere tempo con gli esempi inclusi.

CRC è abbastanza robusto e veloce per applicazioni semplici.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.