Fråga:
Hur hög överföringshastighet kan jag gå (utan fel)?
Anonymous Penguin
2014-02-19 09:16:57 UTC
view on stackexchange narkive permalink

Standarden är 9600 baud. Det är bara standarden . Med vilken Arduino Uno SMD R2, vad är den högsta praktiska överföringshastigheten jag kan uppnå?

Bonuspoäng för den djärva: Hur skulle du göra för att skapa en felkontroll mekanism och sedan öka överföringshastigheten löjligt hög för att få höga överföringshastigheter?

Det är värt att notera att Arduino-kort som använder FTDI USB-seriella IC kan gå riktigt snabbt. Den gemensamma FT232 kan gå 3 Megabaud (det är 3.000.000 baud) utan problem. Användningen av en ATmega16U2 är den begränsande faktorn.
Min klon Arduino Nano som jag fick från eBay uppgick till 1.099.999. Allvarligt. Det gjorde. När den nådde 1 100 000, förvrängdes produktionen. `` laqq`na`fca`fga`fga`bcngaah````in`ha`a`a`bga`fga`bcqpahhqfq``fh`oopa`bca`fca``. Den använder ett CH340-chip för USB-kommandon.
Fyra svar:
#1
+63
Connor Wolf
2014-02-19 12:24:55 UTC
view on stackexchange narkive permalink

Det finns flera faktorer här:

  • Hur hög överföringshastighet kan ATmega328P MCU uppnå?
  • Hur hög överföringshastighet kan USB- Seriellt gränssnitt uppnår?
  • Vad är oscillatorfrekvensen på ATmega328P?
  • Vad är oscillatorfrekvensen på USB-seriellt gränssnitt (om den har en)?
  • Hur tolerant är det USB-seriella gränssnittet för överföringshastighetsmatchning?

Alla dessa faktorer är relevanta för att bestämma den maximala uppnåbara överföringshastigheten. ATmega328P använder en maskinvarudelare från dess klockfrekvens för att generera basklockan för det seriella gränssnittet. Om det inte finns något heltalsförhållande från huvudklockan till bittiden för den önskade baudhastigheten kommer MCU inte att kunna exakt producera den önskade hastigheten. Detta kan leda till potentiella problem, eftersom vissa enheter är mycket känsligare för baudhastighetsmatchning än andra.

FTDI-baserade gränssnitt är ganska toleranta för baudhastighetsmatchning, upp till flera procents fel. Jag har dock arbetat med specialiserade inbäddade GPS-moduler som inte kunde hantera ens ett 0,5% baudhastighetsfel.

Allmänna seriella gränssnitt är toleranta för ~ 5% baudhastighetsfel. Men eftersom varje ände kan vara avstängd är en vanligare specifikation + -2,5%. På det här sättet, om ena änden är 2,5% snabb och den andra är 2,5% långsam, är ditt totala -fel fortfarande bara 5%.


Hur som helst. Uno använder en ATmega328P som primär MCU och en ATmega16U2 som USB-seriellt gränssnitt. Vi har också turen här genom att båda dessa MCU: er använder liknande harware USARTs, liksom 16 MHz-klockor.

Eftersom båda MCU: erna har samma harware och klockfrekvens, kommer de båda att ha samma baud-rate-fel i samma riktning, så vi kan funktionellt ignorera baud-felproblemet.

Hur som helst, det "rätta" svaret på den här frågan skulle innebära att man gräver upp källan för ATmega16U2 och räknar ut de möjliga baud-hastigheterna därifrån, men eftersom jag är lat tror jag att enkla, empiriska test kommer att fungera. / p>

En snabb blick på ATmega328P-databladet ger följande tabell:
enter image description here

Så med tanke på den maximala angivna överföringshastigheten på 2 Mbps skrev jag ett snabbtestprogram:

  ogiltig inställning () {}; ogiltig slinga () {fördröjning (1000); Serial.begin (57600); Serial.println ("\ r \ rBaud-rate = 57600"); fördröjning (1000); Serial.begin (76800); Serial.println ("\ r \ rBaud-rate = 76800"); fördröjning (1000); Serial.begin (115200); Serial.println ("\ r \ rBaud-rate = 115200"); fördröjning (1000); Serial.begin (230400); Serial.println ("\ r \ rBaud-rate = 230400"); fördröjning (1000); Serial.begin (250000); Serial.println ("\ r \ rBaud-rate = 250000"); fördröjning (1000); Serial.begin (500000); Serial.println ("\ r \ rBaud-rate = 500000"); fördröjning (1000); Serial.begin (1000000); Serial.println ("\ r \ rBaud-rate = 1000000"); fördröjning (1000); Serial.begin (2000000); Serial.println ("\ r \ rBaud-rate = 2000000");};  

Och tittar sedan på relevant seriell port med en seriell terminal:

enter image description here

Så det verkar som att hårdvaran kan köras med 2.000.000 baud utan problem.

Observera att denna baudhastighet bara ger MCU 64 80 klockcykler per byte, så det skulle vara mycket utmanande att hålla det seriella gränssnittet upptagen. Medan de enskilda byten kan överföras mycket snabbt, kommer det troligtvis att finnas mycket tid när gränssnittet helt enkelt är inaktivt.


Redigera: Faktisk testning!

De 2 Mbps är verkligt: ​​
enter image description here
varje bit-tid är 500 ns, vilket matchar exakt vad som förväntas.

Prestandafrågor! Totalt paketlängd:
500 Kbaud: enter image description here

1 Mbaud: enter image description here

2 Mbaud: enter image description here
Obs: Den märkbara överskjutningen beror på dålig jordningsmetod för sondomfång och är troligen inte verklig. Jag använder jordklämledningen som är en del av min scope-sond, och blyinduktansen är sannolikt orsaken till majoriteten av överskottet.

Som du kan se är den totala överföringslängden densamma för 0,5, 1 och 2 Mbaud. Detta beror på att koden som placerar byten i den seriella bufferten är dåligt optimerad. Som sådan kommer du aldrig att uppnå något bättre än en effektiv 500 Kbaud, såvida du inte skriver dina egna seriebibliotek. Arduino-biblioteken är mycket dåligt optimerade, så det skulle förmodligen inte vara för svårt att få en ordentlig 2 Mbaud, åtminstone för burst-sändningar, om du spenderade lite tid på det.

Trevlig illustration av kapacitetsbegränsningen!
@jippie - Jag hade räckvidden och körde programmet i mitt svar som går igenom överföringshastigheter. Det var väldigt lite extra arbete och illustrerar problemet ganska snyggt. Det segmenterade minnet i mitt omfång är också fantastiskt.
DS2000-serien? Fördubblar faktiskt sänkning av bithastigheten till 250 kb sändningstiden? Jag tror att jag fortfarande lätt kan hitta start / stopp-bitarna i 500kb-bilden.
@jippie - 4000-serien. Jag älskar mig några kanaler.
Om du hoppar över det seriella biblioteket kan du bli mycket snabbare.
@Cybergibbons - Japp. Se anmärkningen i slutet om optimering.
Wow jag trodde att 9600 baud var ganska bra för en AVR-enhet men jag förväntade mig aldrig 2 MBPS!
@AnnonomusPerson - Om du byter till en 20 MHz-klocka kan du göra 2,5 Mbps.
@FakeName 20 MHz huvudkristall eller på USB-chipet?
@AnnonomusPerson - Du måste byta båda, eller använda ett FTDI USB-seriellt gränssnitt med en 20 MHz ATmega328P-oscillator. ATmega328P kan inte göra 2,5 Mbps utan en 20 MHz kristall / resonator. Detsamma gäller för alla ATmega16U2-gränssnitt.
Bra svar! Bara en liten korrigering: vid 2 Mb / s tar varje byteöverföring 80 CPU-cykler, inte 64. Detta beror på att varje byte tidvis är värt 10 bitar (1 start, 8 data, 1 stopp).
@EdgarBonet - Du har rätt (och whoops). Fast.
Detta är ett bra svar med ett undantag eftersom det inte tar hänsyn till effekterna av det fysiska mediet (kabel / kabel som används för att ansluta till den andra enheten). Detta kommer också att vara en viktig begränsande faktor i användbara baudhastigheter. Seriekommunikation är ganska tråkig med bara en enhet (loopback ingår). ::flin::
@linhartr22 - Ledningar spelar bara riktigt in om de är * långa *, som i 12 "+. Jag tror att det förmodligen är osannolikt att för många använder 100 fot långa kablar för mycket. Dessutom var frågan hur hög ** arduino / ATmega ** överföringshastighet kan gå, inte hur hög en godtycklig kabelenhet kan gå.
@ConnorWolf, Jag vet inte om jag håller 100% med detta uttalande, "Eftersom båda MCU: erna har samma harware och klockfrekvens, kommer de båda att ha samma baudhastighetsfel i samma riktning, så vi kan funktionellt ignorera baud-felproblem. " Jag förstår inte hur det att vara samma UART skulle garantera fel i samma riktning, eftersom enskilda marker fortfarande kan variera slumpmässigt eller? Jag vet att chipsen inte använder samma klockkälla (16U2 använder kristall, 328 använder separat keramisk oscillator).
AiliywylmcCMT - You're missing the error I'm talking about. Basically, the way the ATmega UARTs work is they use an integer divider from the MCU clock to generate the serial timing. As such, some baud rates cannot be directly achieved, as the ratio between the baud rate and the system clock is not an integer. Generally, in this situation, the *closest option* is chosen, which results in the error I'm talking about here (`abs(closest option - target baud) = err`). **This** error will be matched between the two different parts.
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, ser jag, så vad detta innebär är att om du vill maximera möjligheten för två enheter att prata med en mycket hög baudhastighet, eftersom detta är asynkron kommunikation, bör du låta dem båda använda samma frekvensklocka så att deras faktiska överföringshastigheter är snedställda i samma riktning och därigenom anpassa deras bit-timing bättre? Är det rätt? dvs: en 16MHz Arduino med en 16MHz USB till UART-enhet är bättre än en 16MHz Arduino med en 20MHz USB till UART-enhet?
I grund och botten är problemet att du har en MCU med en 20 MHz klocka, du kan få ett -1,5% fel från baud-rate divisor * och * oscillatorvariansen kan vara -1%. Om du sedan pratar med en MCU med en 16 MHz osc som ger ett + 2% delningsfel och ett + 1,5% oscillatorfel, summerar alla dina fel totalt upp till 5% totalt. Men om du delar samma referensoscillatorfrekvens matchar överföringshastighetsdelarfel så att de avbryts och den enda relevanta faktorn blir oscillatorfelet.
Redigera: Ja, du har det. Emellertid är logik för generering av överföringshastighet specifik för en enhet / linje-av-enheter, så att jämföra mellan olika tillverkare kan vara komplicerat.
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%.
Roligt att 1MBPS baud och 2MBPS baud tar samma tid att sända. Det beror på att byten inte kopieras tillräckligt snabbt? Det kan också betyda att du inte kommer att kunna ta emot byten i den här hastigheten. Naturligtvis kan du ta emot 1 byte vid 2Mbaud, men för att ta emot flera byte beror det på hur snabbt Arduino rensar den seriella bufferten (och därmed kan en annan byte tas emot).
@Paul - Arduino gör ingenting. ** ATMega328p **, å andra sidan, gör massor av saker. Hur som helst, genomströmningsproblemen är en funktion av effektiviteten hos sändningsavbrottshanterarens hastighet. Som regel är koden i standard arduino-biblioteken, ja, riktigt dålig kvalitet. Det borde vara fullt möjligt att mätta den seriella länken för åtminstone korta skurar.
Tror du att om du lägger av studsande lock (~ 10-2pf) till marken kan det öka stabiliteten?
@tuskiomi - Vad? Nej, frågan är induktansen för jordklämkabeln som ingår i min scope-sond. Den rätta lösningen är att använda en [probe tip ground] (https://electronics.stackexchange.com/a/40421/1374), men om du inte specifikt försöker mäta saker som risetime, så länge du känner till ringen är inte riktigt, det är inte en viktig fråga.
@ConnorWolf Jag är inte säker. till exempel över på [min fråga] (https://arduino.stackexchange.com/questions/41661/arduino-due-not-properly-detecting-sd-card), kondensatorerna negerade det mesta av spikningen, vilket inte skulle hända om det var en sond sak.
@tuskiomi - Det kan förväntas, eftersom kondensatorerna saktar ner kanthastigheten, vilket innebär att jordklämmans induktans har en mindre effekt. Poängen är att spikningen är 1. inte skadlig, 2. i de flesta fall inte egentligen verklig, utan snarare en mätartefakt. Dessutom, om något, är kondensatorerna * värre * för kretsen, eftersom de är en belastning direkt på utgångsdrivrutinerna på IC som kör bussen. I allmänhet finns det ** väldigt ** få fall där du någonsin vill * lägga till * kapacitans till en databuss.
Innan du börjar fästa kondensatorer överallt, [lär dig att använda din spetsjord] (https://electronics.stackexchange.com/questions/40420/what-is-the-name-of-this-springy-type-oscilloscope- sondtillbehör / 40421 # 40421), och kontrollera med det. [Här] (http://teledynelecroy.com/doc/passive-probe-ground-lead-effects) finns en vitbok av Teledyne LeCroy om ämnet. [Här] (http://web.mit.edu/6.101/www/reference/ABCprobes_s.pdf) är en annan från Tektronix.
Kom ihåg att även om din datahastighet är relativt långsam är det * kanthastigheten * som bestämmer effekten jordledningens induktans har, snarare än kantfrekvensen. Även långsamma små enheter som ATMega IC kan producera ganska snabba kanter.
#2
+8
sachleen
2014-02-19 11:27:36 UTC
view on stackexchange narkive permalink

Arduino Serial Monitor-fönstret begränsar dig till 115200, men det är inte den högsta baudfrekvensen. Du kan läsa databladen Atmel och FT232 (eller vad du än använder) för att ta reda på det maximala men jag kan framgångsrikt använda 230400 (dubbelt så snabbt som den största som Arduino Serial Monitor stöder) utan problem.

Om du vill se resultaten på din dator behöver du en annan seriell bildskärm som stöder andra överföringshastighetsalternativ. Jag gillar CoolTerm och Termite.

Observera att detta också beror mycket på din klockhastighet.

Här är en miniräknare för att hjälpa dig med att beräkna vad som är möjligt.

När du börjar gå snabbare och snabbare blir begränsningen det seriella biblioteket - dess implementering är inte särskilt effektiv.
webbplatsen för länken är död
"Arduino Serial Monitor-fönstret begränsar dig till 115200," - Det är inte längre sant. Det går upp till 2 Mbps
#3
+3
jippie
2014-02-19 12:39:32 UTC
view on stackexchange narkive permalink

Detta är förmodligen en av få aspekter där el-Cheapo-kort skiljer sig från originalbrädor. Den maximala seriella överföringshastigheten är i stort sett bara begränsad av kortets kvalitet och dess layout. När seriell data kommer in i antingen AVR- eller USB-gränssnittschip behandlas data på ett annat sätt än det seriella UART-protokollet.

Kom dock ihåg att mikrokontrollern har grundläggande hårdvara för att skifta in / ut seriell data till / från IO-stiften, men den absoluta maximala hastigheten är begränsad till 16MHz-klockan (för AVR). När en byte har flyttats till den seriella bufferten tar UART-hårdvaran över och skjuter ut / drar in bitarna på egen hand. En AVR når i bästa fall 16M instruktioner per sekund och de avbrott som används för att fylla den seriella bufferten har några omkostnader (minst 8 klockor för avbrottshanteringen + instruktioner för att spara aktuellt tillstånd + flera instruktioner för att faktiskt fylla bufferten). Vid en given bithastighet kommer protokollet att gå med hela n bitar per sekund, men din styrenhet behöver mer tid för att fylla den seriella bufferten än vad den behöver för att faktiskt mata ut data, vilket resulterar i en lägre genomsnittlig genomströmning än du förväntar dig och UART-tomgång relativt lång tid. Nackdelen är den ökade sannolikheten för bitfel.

En annan effekt att komma ihåg är att alla omkostnader som krävs för att skicka ut data till UART (eller dra in det) inte kan spenderas i ditt faktiska program, vilket återigen påverkar genomsnittet praktisk genomströmning. Du kan bara använda varje instruktionscykel en gång, antingen för att fylla bufferten eller för att beräkna huvudslingan.

Den maximala kapaciteten beror därför på vilken applikation du använder (hur snabbt data genereras / beräknas / redo att flytta till / från den seriella bufferten) och den faktiska "fysiska" bithastigheten är bara en liten del av designbeslutet.

Jag tvivlar verkligen på att någon av korten där ute har layoutproblem som är tillräckligt allvarliga för att förhindra att en 2 MHz-signal fungerar bra. 2 MHz är inte exakt hög frekvens.
@FakeName Minst ett bräde på mitt skrivbord här har ökat BER när jag trycker på seriehastigheten. Jag använder vanligtvis 9600, det är mer än tillräckligt för de flesta applikationer och är robust.
Inte skojar! Huh. Jag undrar hur dålig layouten måste vara för att det ska hända? Jag skulle misstänka att det inte är lika mycket layout som resonatorer / kristaller med dålig tolerans.
Höga överföringshastigheter, särskilt om "U2Xn = 1" i USART, tenderar att bli ganska vresiga när det gäller överensstämmelse.
@FakeName Jag är en dinosaurie, jag gillar ganska "9600 8N1" av alla felaktiga skäl som du kan tänka dig; o)
Fan, jag använder 9600 själv för mest felsökningsskit. Det är inte bara du. Det är bara tillfälligt att jag måste driva mycket * data runt, och att veta gränserna är viktigt.
Jag skulle inte bli förvånad om den ökade BER beror på ett billigt falskt seriechip. (FTDI-förfalskning) @ConnorWolf
#4
+2
80HD
2014-02-19 21:31:57 UTC
view on stackexchange narkive permalink

Felkontroll är faktiskt väldigt enkelt och det finns en AVR-lib som gör detta i en enda liner.

Läs igenom util / crc16.h så ska du vara bra att gå på nolltid med de inkluderade exemplen.

CRC är ganska robust och snabbt för enkla applikationer.



Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...