À quelle vitesse puis-je aller en bauds (sans erreur)?

40

La norme est de 9600 bauds. C'est juste la norme . Avec un Arduino Uno SMD R2, quel est le débit en bauds le plus élevé que je puisse obtenir?

Points bonus pour les audacieux: comment feriez-vous pour créer un mécanisme de vérification des erreurs puis augmenter le débit en bauds de manière ridicule afin d’obtenir des taux de transfert élevés?

Pingouin Anonyme
la source
2
Il est à noter que les cartes Arduino qui utilisent les CI série USB FTDI peuvent aller VRAIMENT vite. Le FT232 commun peut atteindre 3 mégabauds (soit 3 000 000 bauds) sans problème. L'utilisation d'un ATmega16U2 est le facteur limitant.
Connor Wolf
1
Mon clone Arduino Nano que j'ai reçu d'eBay a atteint un maximum de 1 099 999. Sérieusement. Ça faisait. Une fois qu'il a atteint 1.100.000, la sortie a été déformée. laqq`na`fca`fga`fga`bcngaah````iin`ha`a`a`bga`fga`bcqpahhqfq```fh`oopa`bca`fca. Il utilise une puce CH340 pour les communications USB.
PNDA

Réponses:

59

Il y a plusieurs facteurs ici:

  • Quel est le débit en bauds atteint par le MCU ATmega328P?
  • Quel est le débit en bauds de l'interface USB-série?
  • Quelle est la fréquence de l’oscillateur sur l’ATmega328P?
  • Quelle est la fréquence de l’oscillateur sur l’interface série USB (s’il en existe une)?
  • Quelle est la tolérance de l'interface série USB de la non-concordance des débits en bauds?

Tous ces facteurs sont pertinents pour déterminer le débit en bauds maximum réalisable. L'ATmega328P utilise un diviseur matériel à partir de sa fréquence d'horloge pour générer l'horloge de base de l'interface série. S'il n'y a pas de rapport entier entre l'horloge principale et le temps en bits du débit en bauds souhaité, la MCU ne sera pas en mesure de produire exactement le débit souhaité. Cela peut entraîner des problèmes potentiels, car certains appareils sont beaucoup plus sensibles à l'inadéquation du débit en bauds que d'autres.

Les interfaces basées sur FTDI tolèrent assez bien le décalage entre les débits en bauds, jusqu'à plusieurs pour cent d'erreur. Cependant, j'ai travaillé avec des modules GPS embarqués spécialisés, incapables de gérer une erreur de 0,5% en bauds.

Les interfaces série générales tolèrent une erreur de taux de bauds de ~ 5%. Cependant, étant donné que chaque extrémité peut être désactivée, une spécification plus courante est + -2,5%. De cette façon, si une extrémité est rapide à 2,5% et l'autre à 2,5% lente, votre erreur globale n'est que de 5%.


Quoi qu'il en soit. Uno utilise un ATmega328P en tant que MCU principal et un ATmega16U2 en tant qu'interface USB-série. Nous avons également la chance d’être ici dans la mesure où ces deux MCU utilisent des USART similaires, ainsi que des horloges à 16 MHz.

Étant donné que les deux microcontrôleurs ont le même matériel matériel et la même fréquence d'horloge, ils ont tous deux la même erreur de débit en bauds dans le même sens, ce qui permet d'ignorer fonctionnellement le problème de l'erreur en bauds.

Quoi qu'il en soit, la réponse "appropriée" à cette question impliquerait de rechercher la source de l'ATmega16U2 et de déterminer les débits en bauds possibles à partir de là, mais comme je suis paresseux, je pense qu'il est simple de procéder à des tests empiriques.

Un rapide coup d’œil sur la fiche technique ATmega328P donne le tableau suivant:
entrez la description de l'image ici

Donc, étant donné le débit maximum indiqué de 2 Mbps, j'ai écrit un programme de test rapide:

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");
};

Et puis en regardant le port série approprié avec un terminal série:

entrez la description de l'image ici

Il semble donc que le matériel puisse fonctionner à 2 000 000 bauds sans problèmes.

Notez que cette vitesse de transmission ne donne à la MCU 64 que 80 cycles d'horloge par octet. Il serait donc très difficile de garder l'interface série occupée. Bien que les octets individuels puissent être transférés très rapidement, il est probable que l'interface soit simplement inactive.


Edit: Test en cours!

Le 2 Mbps est réel:
entrez la description de l'image ici
chaque bit-time est de 500 ns, ce qui correspond exactement à ce qui est attendu.

Les problèmes de performance! Longueur totale du paquet:
500 Kbauds: entrez la description de l'image ici

1 Mbaud: entrez la description de l'image ici

2 Mbauds: entrez la description de l'image ici
Remarque: le dépassement notable est dû à de mauvaises pratiques de mise à la terre de la sonde de portée et n'est probablement pas réel. J'utilise le fil de terre qui fait partie de ma sonde d'oscilloscope, et l'inductance du fil est probablement à l'origine de la majorité du dépassement.

Comme vous pouvez le constater, la longueur totale de la transmission est la même pour 0,5, 1 et 2 Mbauds. Cela est dû au fait que le code qui place les octets dans le tampon série est mal optimisé. En tant que tel, vous ne réaliserez jamais mieux qu'un 500 Kbaud effectif , à moins d'écrire vos propres bibliothèques de séries. Les bibliothèques Arduino sont très mal optimisées, il ne serait donc probablement pas trop difficile d'obtenir un débit de 2 Mbaud approprié, du moins pour les transmissions en rafales, si vous y consacriez un peu de temps.

Connor Wolf
la source
4
Belle illustration de la limitation du débit!
Jippie
1
@AnnonomusPerson - Si vous passez à une horloge de 20 Mhz, vous pouvez faire 2,5 Mbps.
Connor Wolf
1
@AnnonomusPerson - Vous devez permuter les deux ou utiliser une interface série-usb FTDI avec un oscillateur ATmega328P à 20 Mhz. L'ATmega328P ne peut pas atteindre 2,5 Mbps sans un cristal / résonateur de 20 Mhz. Il en va de même pour toutes les interfaces ATmega16U2.
Connor Wolf
1
Très bonne réponse! Juste une petite correction: à 2 Mb / s, chaque transmission d'octet nécessite 80 cycles de traitement, et non 64. Cela s'explique par le fait que chaque octet vaut 10 bits (1 début, 8 données, 1 arrêt).
Edgar Bonet
1
@ linhartr22 - Les fils n'entrent vraiment en jeu que s'ils sont longs , comme en 12 "+. Je pense qu'il est probablement improbable qu'un trop grand nombre de personnes utilisent trop de câbles de 100 pieds. En outre, la question était de savoir à quelle hauteur l' arduino / ATmega le débit en bauds peut aller, pas la hauteur qu'un câble arbitraire peut atteindre
Connor Wolf
7

La fenêtre du moniteur série Arduino vous limite à 115200, mais ce n’est pas le débit le plus élevé possible. Vous pouvez lire les fiches techniques Atmel et FT232 (ou tout ce que vous utilisez) pour connaître le maximum, mais je peux utiliser 230400 (deux fois plus rapidement que les plus grandes cartes prises en charge par le moniteur série Arduino) sans aucun problème.

Si vous souhaitez voir les résultats sur votre ordinateur, vous aurez besoin d'un autre moniteur série prenant en charge d'autres options de débit en bauds. J'aime CoolTerm et Termite .

Notez que cela dépend aussi beaucoup de votre vitesse d'horloge.

Voici une calculatrice pour vous aider à calculer ce qui est possible.

Sachleen
la source
Lorsque vous commencez à aller de plus en plus vite, la limitation devient la bibliothèque Serial. Son implémentation n'est pas très efficace.
Cybergibbons
Site web de link is dead
Codebeat
3

C’est probablement l’un des rares aspects où les cartes el-Cheapo se distinguent des cartes originales. Le taux maximum de transfert en série n’est quasiment limité que par la qualité du tableau et son agencement. Une fois que les données série entrent dans la puce d’interface AVR ou USB, les données seront traitées différemment du protocole UART série.

Gardez toutefois à l'esprit que le microcontrôleur dispose de matériel de base pour déplacer des données série vers / depuis les broches d'E / S, mais que le débit maximal absolu est limité à l'horloge à 16 MHz (pour les AVR). Une fois qu'un octet est déplacé dans la mémoire tampon série, le matériel UART prend le relais et extrait / extrait les bits de son côté. Un AVR au mieux atteint 16 millions d'instructions par seconde et les interruptions utilisées pour remplir le tampon série ont un surcoût (au moins 8 ticks d'horloge pour la gestion des interruptions + instructions pour sauvegarder l'état actuel + plusieurs instructions pour réellement remplir le tampon). À un débit binaire donné, le protocole fonctionnera à n bits par seconde, mais votre contrôleur a besoin de plus de temps pour remplir le tampon série que nécessaire pour sortir les données, ce qui entraîne un débit moyen inférieur à celui attendu et le temps d'inactivité UART. pendant un temps relativement long.

Un autre effet à garder à l'esprit est que toute la surcharge nécessaire pour transférer des données sur UART (ou les extraire) ne peut pas être dépensée dans votre programme réel, ce qui affecte à nouveau le débit moyen moyen. Vous ne pouvez utiliser chaque cycle d'instruction qu'une seule fois, soit pour remplir la mémoire tampon, soit pour calculer la boucle principale.

Le débit maximal dépend donc de l’application que vous utilisez (rapidité avec laquelle les données sont générées / calculées / prêtes à être déplacées vers / depuis le tampon série) et le débit réel «physique» n’est qu’une petite partie de la décision de conception.

jippie
la source
1
Vraiment, je doute vraiment que l’une quelconque des cartes présente des problèmes d’agencement suffisamment graves pour empêcher un signal de 2 Mhz de fonctionner correctement. 2 Mhz n'est pas vraiment haute fréquence.
Connor Wolf
@FakeName Au moins une des cartes de mon bureau a augmenté le TEB lorsque j'utilise la vitesse de série. J'utilise habituellement le 9600, ce qui est plus que suffisant pour la plupart des applications et qui est robuste.
Jippie
Sans blague! Huh. Je me demande à quel point la mise en page doit être mauvaise pour que cela se produise? Je soupçonne que ce n'est pas aussi bien mis en page que résonateurs / cristaux de faible tolérance, cependant.
Connor Wolf
1
Des taux de transmission élevés, en particulier U2Xn = 1dans l'USART, ont tendance à être plutôt grincheux à propos de l'inadéquation.
Connor Wolf
@ FakeName Je suis un dinosaure, j'aime un peu "9600 8N1" pour toutes les mauvaises raisons d'héritage auxquelles vous pouvez penser; o)
jippie
2

La vérification des erreurs est en réalité très facile et il existe une bibliothèque AVR qui le fait dans une seule ligne.

Lisez util/crc16.het vous devriez être prêt à partir en un rien de temps avec les exemples fournis.

Le CRC est assez robuste et rapide pour des applications simples.

80HD
la source