Vraag:
Hoe hoog kan ik gaan (zonder fouten)?
Anonymous Penguin
2014-02-19 09:16:57 UTC
view on stackexchange narkive permalink

De standaard is 9600 baud. Dat is slechts de standaard . Wat is de hoogste praktische baudrate die ik kan bereiken met behulp van een Arduino Uno SMD R2?

Bonuspunten voor de gedurfde: Hoe zou je een foutcontrole maken? mechanisme en vervolgens het verhogen van de baudrate belachelijk hoog om hoge overdrachtssnelheden te krijgen?

Het is vermeldenswaard dat Arduino-boards die FTDI USB-seriële IC's gebruiken ECHT snel kunnen gaan. De gewone FT232 kan zonder problemen 3 Megabaud (dat is 3.000.000 baud) gaan. Het gebruik van een ATmega16U2 is de beperkende factor.
Mijn kloon Arduino Nano die ik van eBay kreeg, bedroeg maximaal 1.099.999. Ernstig. Het deed. Toen het eenmaal 1.100.000 bereikte, was de output onleesbaar. `` laqq`na`fca`fga`fga`bcngaah''iin`ha`a`a`bga`fga`bcqpahhqfq''`fh`oopa`bca`fca ''. Het gebruikt een CH340-chip voor USB-communicatie.
Vier antwoorden:
#1
+63
Connor Wolf
2014-02-19 12:24:55 UTC
view on stackexchange narkive permalink

Er zijn hier verschillende factoren:

  • Hoe hoog kan de baud-rate van de ATmega328P MCU bereiken?
  • Hoe hoog kan de baud-rate de USB- Seriële interface bereikt?
  • Wat is de oscillatorfrequentie op de ATmega328P?
  • Wat is de oscillatorfrequentie op de USB-seriële interface (als die er is)?
  • Hoe tolerant is de USB-seriële interface wat betreft baudrate-mismatch?

Al deze factoren zijn relevant voor het bepalen van de maximaal haalbare baudrate. De ATmega328P gebruikt een hardwaredeler van zijn kloksnelheid om de basisklok voor de seriële interface te genereren. Als er geen integer-verhouding is tussen de hoofdklok en de bit-tijd van de gewenste baudrate, kan de MCU niet exact de gewenste snelheid produceren. Dit kan tot potentiële problemen leiden, aangezien sommige apparaten veel gevoeliger zijn voor verkeerde baudrate dan andere.

Op FTDI gebaseerde interfaces zijn vrij tolerant ten aanzien van niet-overeenkomende baudrate, tot enkele procenten fouten. Ik heb echter met gespecialiseerde embedded GPS-modules gewerkt die zelfs geen 0,5% baudrate-fout aankonden.

Algemene seriële interfaces zijn tolerant voor ~ 5% baudrate-fouten. Omdat elk uiteinde echter kan zijn uitgeschakeld, is een meer algemene specificatie + -2,5%. Op deze manier, als het ene uiteinde 2,5% snel is en het andere 2,5% langzaam, is uw algehele fout nog steeds slechts 5%.


Hoe dan ook. De Uno gebruikt een ATmega328P als de primaire MCU en een ATmega16U2 als de USB-seriële interface. We hebben hier ook het geluk dat beide MCU's vergelijkbare harware USART's gebruiken, evenals klokken van 16 Mhz.

Aangezien beide MCU's dezelfde harware en kloksnelheid hebben, hebben ze allebei dezelfde baudrate-fout in dezelfde richting, zodat we het probleem met de baud-fout functioneel kunnen negeren.

Hoe dan ook, het "juiste" antwoord op deze vraag zou het opgraven van de bron voor de ATmega16U2 inhouden, en van daaruit de mogelijke baudrates uitwerken, maar aangezien ik lui ben, denk ik dat eenvoudige, empirische tests zullen werken. / p>

Een snelle blik op de ATmega328P-datasheet levert de volgende tabel op:
enter image description here

Dus gezien de maximale opgegeven baud-rate van 2 Mbps, heb ik een snel testprogramma geschreven:

  void setup () {}; void loop () {delay (1000); Serial.begin (57600); Serial.println ("\ r \ rBaud-rate = 57600"); vertraging (1000); Serial.begin (76800); Serial.println ("\ r \ rBaud-rate = 76800"); vertraging (1000); Serial.begin (115200); Serial.println ("\ r \ rBaud-rate = 115200"); vertraging (1000); Serial.begin (230400); Serial.println ("\ r \ rBaud-rate = 230400"); vertraging (1000); Serial.begin (250000); Serial.println ("\ r \ rBaud-rate = 250000"); vertraging (1000); Serial.begin (500000); Serial.println ("\ r \ rBaud-rate = 500000"); vertraging (1000); Serial.begin (1000000); Serial.println ("\ r \ rBaud-rate = 1000000"); vertraging (1000); Serial.begin (2000000); Serial.println ("\ r \ rBaud-rate = 2000000");};  

En dan kijken naar de relevante seriële poort met een seriële terminal:

enter image description here

Het lijkt erop dat de hardware zonder problemen op 2.000.000 baud kan draaien.

Merk op dat deze baudrate de MCU 64 80 klokcycli geeft per byte, dus het zou een grote uitdaging zijn om de seriële interface bezig te houden. Hoewel de individuele bytes zeer snel kunnen worden overgedragen, is er waarschijnlijk veel tijd wanneer de interface gewoon inactief is.


Bewerken: feitelijk testen!

De 2 Mbps is echt:
enter image description here
elke bit-tijd is 500 ns, wat precies overeenkomt met wat wordt verwacht.

Prestatieproblemen! Totale pakketlengte:
500 Kbaud: enter image description here

1 Mbaud: enter image description here

2 Mbaud: enter image description here
Opmerking: de merkbare overschrijding is te wijten aan slechte aardingsmethoden voor de scoopsonde en is waarschijnlijk niet echt. Ik gebruik de ground-clip-lead die deel uitmaakt van mijn scoop-probe, en de lead-inductantie is waarschijnlijk de oorzaak van het grootste deel van de overshoot.

Zoals u kunt zien, is de totale transmissielengte hetzelfde voor 0,5, 1 en 2 Mbaud. Dit komt doordat de code die de bytes in de seriële buffer plaatst, slecht is geoptimaliseerd. Als zodanig zul je nooit iets beters bereiken dan een effectieve 500 Kbaud, tenzij je je eigen seriële bibliotheken schrijft. De Arduino-bibliotheken zijn erg slecht geoptimaliseerd, dus het zou waarschijnlijk niet al te moeilijk zijn om een ​​goede 2 Mbaud te krijgen, althans voor burst-transmissies, als je er wat tijd aan zou besteden.

Mooie illustratie van de doorvoerbeperking!
@jippie - Ik had de scope en draaide het programma in mijn antwoord dat door baudrates loopt. Het was heel weinig extra werk, en illustreert het probleem heel mooi. Ook is het gesegmenteerde geheugen op mijn scope geweldig.
DS2000-reeks? Verdubbelt het verlagen van de bitsnelheid tot 250kb de tijd van de verzending? Ik denk dat ik de start / stop-bits nog steeds gemakkelijk kan zien in de 500kb-afbeelding.
@jippie - 4000 reeksen. Ik hou van mij zo'n 4 kanalen.
Als u de seriële bibliotheek overslaat, kunt u veel sneller worden.
@Cybergibbons - Ja. Zie de opmerking aan het einde over optimalisatie.
Wauw, ik dacht dat de 9600 baud best goed was voor een AVR-apparaat, maar ik had nooit 2 MBPS verwacht!
@AnnonomusPerson - Als je overschakelt naar een 20 Mhz-klok, kun je 2,5 Mbps doen.
@FakeName 20 Mhz hoofdkristal of op de USB-chip?
@AnnonomusPerson - Je zou beide moeten verwisselen, of een FTDI usb-seriële interface gebruiken met een 20 Mhz ATmega328P-oscillator. De ATmega328P kan geen 2,5 Mbps halen zonder een 20 Mhz kristal / resonator. Hetzelfde geldt voor alle ATmega16U2-interfaces.
Goed antwoord! Slechts één kleine correctie: bij 2 Mb / s duurt elke byte-overdracht 80 CPU-cycli, niet 64. Dit komt omdat, in de tijd, elke byte 10 bits waard is (1 start, 8 data, 1 stop).
@EdgarBonet - Je hebt helemaal gelijk (en oeps). Gemaakt.
Dit is een geweldig antwoord met één uitzondering: het houdt geen rekening met de effecten van de fysieke media (draad / kabel die wordt gebruikt om verbinding te maken met het andere apparaat). Dit zal ook een belangrijke beperkende factor zijn in bruikbare baudrates. Seriële communicatie is behoorlijk saai met slechts één apparaat (inclusief loopback). ::grijns::
@linhartr22 - Draden spelen pas echt een rol als ze * lang * zijn, zoals in 12 "+. Ik denk dat het waarschijnlijk onwaarschijnlijk is dat te veel mensen 30 meter lange kabels te veel gebruiken. Bovendien was de vraag hoe hoog de ** arduino / ATmega ** baudrate kan gaan, niet hoe hoog een willekeurige kabelassemblage kan gaan.
@ConnorWolf, Ik weet niet of ik het 100% eens ben met deze stelling: "Aangezien beide MCU's dezelfde hardware en kloksnelheid hebben, hebben ze allebei dezelfde baudrate-fout in dezelfde richting, dus we kunnen functioneel de baud error probleem. " Ik zie niet in hoe het zijn van dezelfde UART een fout in dezelfde richting zou garanderen, aangezien individuele chips nog steeds willekeurig kunnen variëren, toch? - en hoewel de chips beide dezelfde freq hebben, betekent dit dat de seriële freq-berekeningsfout in dezelfde richting is , Ik weet dat de chips niet dezelfde klokbron gebruiken (16U2 gebruikt kristal, 328 gebruikt een afzonderlijke keramische oscillator).
@GabrielStaples - Je mist de fout waar ik het over heb. Kortom, de manier waarop de ATmega UART's werken, is dat ze een integer-deler van de MCU-klok gebruiken om de seriële timing te genereren. Als zodanig kunnen sommige baudrates niet direct worden bereikt, aangezien de verhouding tussen de baudrate en de systeemklok geen geheel getal is. Over het algemeen wordt in deze situatie de * dichtstbijzijnde optie * gekozen, wat resulteert in de fout waar ik het hier over heb (`abs (dichtstbijzijnde optie - target baud) = err`). ** Deze ** fout zal worden vergeleken tussen de twee verschillende delen.
While chips can vary, the operation of the UART is deterministic, so if you drive two parts with the same clock source, you'll get the same outputs (minus some small potential jitter).
@ConnorWolf, Ik begrijp het, dus wat dit inhoudt, is dat als je de mogelijkheid wilt maximaliseren dat twee apparaten met een zeer hoge baudrate kunnen praten, aangezien dit asynchrone communicatie is, je ze allebei dezelfde frequentieklok moet laten gebruiken zodat hun werkelijke baudrates zijn scheef in dezelfde richting, waardoor hun bit-timing beter wordt uitgelijnd? Is dat juist? dat wil zeggen: een 16 MHz Arduino met een 16 MHz USB naar UART-apparaat is beter dan een 16 MHz Arduino met een 20 MHz USB naar UART-apparaat?
Basically, the issue is that you have a MCU with a 20 MHz clock, you might get a -1.5% error from the baud-rate divisor *and* the oscillator variance could be -1%. Then, if talking to a MCU with a 16 MHz osc which produces a +2% divisor error, and a +1.5% oscillator error, all your errors sum up to 5% in total. However, if you share the same reference oscillator frequency, the baud rate divisor errors match, so they cancel out, and the only relevant factor becomes the oscillator error.
Edit: Yeah, you've got it. However, the baud-rate generation logic is specific to a device/line-of-devices,so comparing between different manufacturers can be complicated.
I see now. I just checked the ATmega328 datasheet. Here's [another table](http://i.stack.imgur.com/muABX.png) (from pg. 175) you might want to throw in your answer under the first one. It helps calculate the baud-rates to verify their errors in the table, and it makes it clear to me how they got their errors. For example, 115.2k shows -3.5% error for asynchronous normal mode (U2Xn=0). The formula goes: `16e6/(16*(8+1)) = 111111.11bps`. That's the closest option. So, the error is 111111.11/115200 = 0.9645 = -3.5%.
Grappig dat de 1MBPS baud en 2MBPS baud evenveel tijd nodig hebben om te verzenden. Omdat de bytes niet snel genoeg worden gekopieerd, kan dit ook betekenen dat u de bytes niet met deze snelheid kunt ontvangen. Je kunt natuurlijk 1 byte ontvangen op 2Mbaud, maar voor het ontvangen van meerdere bytes hangt het af van hoe snel de Arduino de seriële buffer wist (en dus een andere byte kan worden ontvangen).
@Paul - De arduino doet niets. De ** ATMega328p ** doet daarentegen veel dingen. Hoe dan ook, de doorvoerproblemen zijn een functie van de efficiëntie van de transmit-interrupthandlersnelheid. In de regel is de code in de standaard arduino-bibliotheken echt van slechte kwaliteit. Het zou heel goed mogelijk moeten zijn om de seriële verbinding gedurende ten minste korte bursts te verzadigen.
Denk je dat het toevoegen van de-bouncing caps (~ 10-2pf) aan de grond de stabiliteit kan vergroten?
@tuskiomi - Wat? Nee, het probleem is de inductantie van de aardklemdraad die deel uitmaakt van mijn scoopsonde. De juiste oplossing is om een ​​[probe tip ground] te gebruiken (https://electronics.stackexchange.com/a/40421/1374), maar tenzij je specifiek dingen zoals stijgtijd probeert te meten, zolang je het rinkelen kent is niet echt, het is geen significant probleem.
@ConnorWolf Ik weet het niet zeker. bijvoorbeeld op [mijn vraag] (https://arduino.stackexchange.com/questions/41661/arduino-due-not-properly-detecting-sd-card), de condensatoren negeerden de meeste spiking, wat niet gebeuren als het een sonde-ding was.
@tuskiomi - Dat is te verwachten, aangezien de condensatoren de flanksnelheid vertragen, wat betekent dat de inductantie van de grondclip een kleiner effect heeft. Het punt is dat de piek 1. niet schadelijk is, 2. in de meeste gevallen niet echt, maar eerder een meetartefact. Bovendien, als er iets is, zijn de condensatoren * slechter * voor het circuit, omdat ze rechtstreeks worden belast op de uitgangsstuurprogramma's van de IC die de bus aandrijft. Over het algemeen zijn er ** zeer ** weinig gevallen waarin u ooit capaciteit wilt * toevoegen * aan een databus.
Kortom, voordat u begint met het overal plaatsen van condensatoren, [leer uw tipgrond te gebruiken] (https://electronics.stackexchange.com/questions/40420/what-is-the-name-of-this-springy-type-oscilloscope- sonde-accessoire / 40421 # 40421), en controleer daarmee. [Here] (http://teledynelecroy.com/doc/passive-probe-ground-lead-effects) is een whitepaper van Teledyne LeCroy over dit onderwerp. [Here] (http://web.mit.edu/6.101/www/reference/ABCprobes_s.pdf) is een andere van Tektronix.
Onthoud dat zelfs als uw gegevenssnelheid relatief laag is, het de * flankfrequentie * is die het effect bepaalt van de aardingsdraadinductie, en niet de flankfrequentie. Zelfs langzame kleine apparaten zoals ATMega IC's kunnen behoorlijk snelle randen produceren.
#2
+8
sachleen
2014-02-19 11:27:36 UTC
view on stackexchange narkive permalink

Het Arduino Serial Monitor-venster beperkt je tot 115200, maar dat is niet de hoogste baudrate. Je kunt de Atmel en de FT232 (of wat je ook gebruikt) datasheets lezen om erachter te komen wat het maximum is, maar ik kan zonder problemen 230400 (twee keer zo snel als de grootste die de Arduino Serial Monitor ondersteunt) gebruiken.

Als u de resultaten op uw computer wilt zien, heeft u een andere seriële monitor nodig die andere baudrate-opties ondersteunt. Ik vind CoolTerm en Termite leuk.

Houd er rekening mee dat dit ook sterk afhankelijk is van je kloksnelheid.

Hier is een calculator om u te helpen bij het berekenen van wat mogelijk is.

Naarmate u steeds sneller gaat werken, wordt de beperking de seriële bibliotheek - de implementatie ervan is niet erg efficiënt.
website of link is dead
"Het Arduino Serial Monitor-venster beperkt je tot 115200," - Dat is niet langer waar. Het gaat tot 2 Mbps
#3
+3
jippie
2014-02-19 12:39:32 UTC
view on stackexchange narkive permalink

Dit is waarschijnlijk een van de weinige aspecten waarbij el-Cheapo-boards verschillen van originele boards. De maximale seriële overdrachtssnelheid wordt vrijwel alleen beperkt door de kwaliteit van het bord en de lay-out. Zodra de seriële gegevens de AVR- of USB-interfacechip binnenkomen, worden de gegevens anders verwerkt dan het seriële UART-protocol.

Houd er echter rekening mee dat de microcontroller wat basishardware heeft om seriële gegevens naar / van de IO-pinnen te verplaatsen, maar de absolute maximale snelheid is beperkt tot de 16MHz-klok (voor AVR's). Zodra een byte naar de seriële buffer is verplaatst, neemt de UART-hardware het over en duwt / trekt de bits vanzelf naar binnen. Een AVR haalt op zijn best 16M instructies per seconde en de interrupts die worden gebruikt om de seriële buffer te vullen, hebben wat overhead (minimaal 8 kloktikken voor de afhandeling van de interrupt + instructies om de huidige status op te slaan + verschillende instructies om de buffer daadwerkelijk te vullen). Bij een bepaalde bitsnelheid werkt het protocol met maar liefst n bits per seconde, maar je controller heeft meer tijd nodig om de seriële buffer te vullen dan nodig is om de gegevens daadwerkelijk uit te voeren, wat resulteert in een lagere gemiddelde doorvoer dan je verwacht en de UART inactief is voor een relatief lange tijd. Nadeel is de grotere kans op bitfouten.

Een ander effect om te onthouden is dat alle overhead die nodig is om gegevens naar UART te pushen (of binnen te halen) niet kan worden besteed aan uw eigenlijke programma, wat weer van invloed is op het gemiddelde praktische doorvoer. Je kunt elke instructiecyclus maar één keer gebruiken, ofwel voor het vullen van de buffer ofwel voor het berekenen van de hoofdlus.

De maximale doorvoersnelheid is daarom afhankelijk van de applicatie die je gebruikt (hoe snel worden data gegenereerd / berekend / klaar om verplaats naar / van de seriële buffer) en de feitelijke 'fysieke' bitsnelheid is slechts een klein deel van de ontwerpbeslissing.

Ik betwijfel echt, ECHT dat een van de boards die er zijn lay-outproblemen hebben die ernstig genoeg zijn om te voorkomen dat een 2 Mhz-signaal goed werkt. 2 Mhz is niet bepaald een hoge frequentie.
@FakeName Ten minste één bord op mijn bureau hier heeft de BER verhoogd als ik op seriële snelheid druk. Ik gebruik meestal 9600, dat is meer dan genoeg voor de meeste toepassingen en is robuust.
Geen grapje! Huh. Ik vraag me af hoe slecht de lay-out moet zijn om dat te laten gebeuren? Ik zou echter vermoeden dat het niet zozeer lay-out is als resonatoren / kristallen met een slechte tolerantie.
Hoge baudrates, vooral als `U2Xn = 1` in de USART, worden nogal chagrijnig over mismatch.
@FakeName Ik ben een dinosaurus, ik hou een beetje van "9600 8N1" om alle verkeerde redenen die je kunt bedenken; o)
Verdorie, ik gebruik 9600 zelf voor de meeste foutopsporing. Jij bent het niet alleen. Het komt gewoon af en toe voor dat ik * veel * aan gegevens moet pushen, en het kennen van de limieten is belangrijk.
Het zou me niet verbazen als de verhoogde BER te wijten is aan een goedkope nep-seriële chip. (FTDI-namaak) @ConnorWolf
#4
+2
80HD
2014-02-19 21:31:57 UTC
view on stackexchange narkive permalink

Foutcontrole is eigenlijk heel eenvoudig en er is een AVR-lib die dit doet in een one liner.

Lees het op util / crc16.h en je zou binnen de kortste keren klaar moeten zijn met de meegeleverde voorbeelden.

CRC is behoorlijk robuust en snel voor eenvoudige toepassingen.



Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...