Küsimus:
Arduino ja minu arvuti töötleva visandi vahelise viivituse vähendamine
Kenneth .J
2014-06-04 17:27:35 UTC
view on stackexchange narkive permalink

Olen praegu Arduino projektiraamatu projektis nr 14.

Püüan Arduino abil juhtida oma sülearvuti töötlemise visandit. Selle saavutamiseks kasutatakse potentsiomeetrit pildi tausta juhtimiseks.

Arduino kood:

  void setup () {Serial.begin (9600);} void loop () {Serial.write (analogRead (A0) / 4);}  

Töötlemine:

  // impordib jadakoguimport processing.serial. *; // seab jadaobjektiSerial myPort; // loob objekti imagePImage logole; // muutuja taustavärvi salvestamiseks bgcolor = 0; void setup () {colorMode (HSB, 255); logo = loadImage ("http://arduino.cc/logo.png"); suurus (logo.laius, logo.kõrgus); println ("Saadaval jadapordid"); println (Serial.list ()); myPort = uus jada (see, Serial.list () [0], 9600);} // arduino tsükli funktsiooni ekvivalent väldi joonistamist () {if (myPort.available () > 0) {bgcolor = myPort.read (); println (bgvärv); } Taust (bgcolor, 255,255); pilt (logo, 0,0);}  

Kui kood töötab ja taustavärv potentsiomeetri pööramisel muutub, on tohutu viivitus potentsiomeetri pööramise ja tausta värvi muutumise vahel ning Arduino / potentsiomeetri väärtused muutuvad töötlemise seeriamonitoril.

Mida olen proovinud:

  • Seeriaside kiiruse muutmine

Olen märganud, et kui vähendan jadaside kiirust, nt umbes 100, väheneb viivitus potentsiomeetri pööramise ja minu sülearvuti muutumise vahel umbes 1 sekundini. Kui ma aga jadaühenduse kiirust veelgi vähendan, nt väärtus 1, viivitus suureneb uuesti.

Tagaküljel on standardkiirusel 9600 viivitus tohutu, umbes 5 sekundit ++, enne kui potentsiomeetri muudatused sülearvutis ilmuvad / töötlemine.

Miks suhtluskiiruse vähendamine (kuni teatud punktini) vähendab viivitust ja selle suurendamine viivitust? Samuti, kas ma üldse suudan selle teha hetkega?

Arduino `loop ()` ümber esitate iga kord lugemist. On täiesti võimalik, et teie töötlemisprogramm ei tööta piisavalt kiiresti, et sellega sammu pidada. Selle aeglustamiseks proovige viivitada oma Arduino koodi `loop ()` sse; nt. "viivitus (50)".
Tere, Peter, aitäh kiire vastuse eest. Väikese viivituse lisamine tõesti lahendas mu probleemi. Kuid veel üks väike küsimus, kas on kuidagi võimalik oma töötlusprogrammi kiirust tulevikus kindlaks teha, et seda enam ei juhtuks, või lahendab probleemi parem sülearvuti / töötlemiskiiruse saamine? Samuti miks ajab 250 või 300 sidekiiruse sisestamine arduino näidud sassi? (Saadud näidud on vaheldumisi näidu ja nulliga, nt 147,0, 147,0)
Viis vastused:
Tom
2014-06-06 17:32:36 UTC
view on stackexchange narkive permalink

Nagu juba märgitud, ütleb teie Arduino liiga palju liiga kiiresti. delay () lisamine aeglustab seda, kuid ikkagi karjub Processing. Ideaalis soovite, et töötlemine küsiks väärtust, kui see on mugav, ja saaksite siis oma Arduinolt ühe vastuse.

Sisestage SerialEvent().

As vastupidi teie Arduino loop () -le ja töötlemisel draw () , kõik serialEvent () -i sees on ainult siis, kui loendis on midagi uut järjestikune puhver. Nii et selle asemel, et Töötleda küsimusi nii kiiresti kui võimalik ja teie Arduino veel kiiremini tagasi karjuda, võivad nad pidada toredat, viisakat (asünkroonset) vestlust.

Nii töötlemisel kui ka Arduinol on serialEvent. See on serialEvent () Arduinos ja see on serialEvent () töötlemisel. Kasutades serialEventi mõlemal küljel, see juhtuks:

  1. Töötlemine saadab märgi jadaühendusse. See võib olla ükskõik milline märk, kuid kui me selle eelnevalt määrame, saame filtreerida kõik soovimatud taotlused, mis on põhjustatud nt. lärmakas signaal. Selle näite jaoks saadame iga kord V , kui soovime teie potimeetri uut lugemist. Pärast tegelase saatmist jätkame oma tegevust tavapäraselt. Ärge oodake siin vastust!

  2. Arduino poolel ei juhtu midagi, kuni see saab andmeid jadapuhvrisse. See kontrollib, kas sissetulev märk on V , ja meil on õnne, et see on. Arduino loeb keraamikameetri väärtust üks kord, väljastab selle väärtuse üks kord seeriasse ja läheb tagasi lõõgastumise juurde, maksimeerides lõõgastust. Protip: lõpetage väärtus tähemärgiga (meie puhul * ). See aitab teil järgmises etapis.

  3. Töötlemine on tavapärane liidestav piksliäri, kui järsku on jadapuhvris jõus häireid uusi andmeid. See lülitub versioonile serialEvent () ja alustab seeriandmete lugemist, kuni leitakse meie lõpetav * . Teades kindlasti, et see oli viimane lugemist väärt märk, saame nüüd sissetuleva väärtuse salvestada muutujasse, mis salvestab Arduino näidu.

  4. See on kõik. Töötlemine teab nüüd sensori uut väärtust ja jätkab kõike, mida me käskime. Vahepeal naudib teie Arduino ilma või mõtiskleb selle olemasolu üle, kuni saabuvad seerianumbrid.

Ja kui olete käes, pange kondensaator paralleelselt oma potimeetriga. See sujub teie DAC-i sisendis vähe muudatusi, vältides võib-olla töötlemisel närvilist liikumist.
Aitäh selle toreda (ja kindla antropomorfse) vastuse eest!
Tegelikult võib idee olla USB kaudu küsimuste esitamine. Selle põhjuseks on asjaolu, et USB-l on palju rohkem * latentsust * kui jadapordil, seega on küsimuse esitamine ja vastuse ootamine aeganõudvam toiming kui muidu, eriti võrreldes sellega, mida saaks teha suure baudikiirusega. On hea lasta Arduinol veidi kiiremini töötada (kuigi see ei tohiks küllastada lingi jadast osa); Konks on see, et töötlemise visand peaks Arduino andmed tühjendama, kui need kättesaadavaks saavad, ja hoidma kinni viimasest täielikust väärtusest, mida seda kasutada, kui seda vaja on.
Peter Bloomfield
2014-06-04 19:25:42 UTC
view on stackexchange narkive permalink

Te esitate lugemist iga kord Arduino loop () ümber, seega näib tõenäoline, et teie töötlemisprogramm ei tööta piisavalt kiiresti, et sellega sammu pidada. Selle aeglustamiseks proovige oma Arduino koodi viivitusega loop () sisestada, nt:

  void loop () {Serial.write (analogRead (A0) / 4); delay (50);}  

Minu teada on töötlemise eesmärk töötada järjepideva kaadrisagedusega, mida saate muuta frameRate () code abil > funktsioon. Vaikimisi on see 60 kaadrit sekundis, ehkki vanemates süsteemides (või intensiivse programmi käitamise korral) võib see töötada aeglasemalt. Selle töötamise kiirust saate kontrollida muutujat frameRate lugedes.

Arduino silmusesse 50 millisekundilise viivituse sisseviimine tähendab, et seda värskendatakse veidi alla 20 korda sekundis. See tähendab, et see peaks olema kasutajaliidese jaoks piisavalt kiire, kuid peaks olema ka teie töötlemisprogrammi võimaluste piires.

Mis puutub baudikiirusesse (sidekiirus), siis kohandage seda suvaliste summadega on tõenäoliselt ettearvamatuid tulemusi. Seda seetõttu, et riistvara toetab ainult konkreetseid kiirusi ja kui proovite kasutada midagi muud, võib tulemuseks olla, et andmed on teises otsas segased. Dokumentatsioonis Serial.begin () on toetatud baudikiiruste kohta lisateavet.

Volker Siegel
2014-06-04 23:09:00 UTC
view on stackexchange narkive permalink

Teie valimisringkond töötab teie protsessori täiskiirusel ja kirjutab igas voorus jadaporti.

Nii kirjutate jadaporti sagedamini, kui see suudab.

Pord kirjutab andmed välja nii kiiresti, kui olete need seadistanud, ja puhverandmed , mis teie programmist sisse tulevad liiga kiiresti , et need välja kirjutada nii kiiresti kui võimalik. Puhver on täis, see lihtsalt langetab uusi andmeid.

Siin on oluline, et see säilitaks väärtuste järjekorra: see on FIFO puhver , töötades First In / First Out järjekorras.

Mis juhtub, on:
Silmus täidab pordipuhvri ja hoiab selle 100% täis.
Kui keerate potentsiomeetrit, on muudetud väärtus get on kirjutatud puhvri lõppu , port töötab nii kiiresti kui võimalik, et välja kirjutada kõik puhvri elemendid, millel on endiselt vana väärtus.

Ja lõpuks väärtus, mis teid huvitab. Kõige värskem väärtus, mida tahtsime kohe näha, oli FIFO lõpus ja esimene sisse / esimene välja tähendab ka viimast sisse / viimast välja. Vastupidi sellele, mida me tahame.

Maksimaalne sagedus, mida on mõistlik oma andmeid lugeda, on sagedus, mille saate need välja kirjutada, nii et peaksite kasutama vähemalt viivitust, mis on baiti praeguse pordikiiruse korral.


Teise iseseisva meetmena sellise viivituse vältimiseks üldiselt võite
lisaks seada pordi kirjutuspuhvri miinimumini.

Selle tulemusel langetaks andmed palju varem, selle asemel et enne palju puhverdada.

Muidugi pole paljudes rakendustes seda, mida vajate; Ebaõnnega võib see alguses niikuinii toimida ja mõnes olukorras muutuda ebastabiilseks, kui ajastus muutub näiteks protsessori koormuse põhjal ja langevad ainult mõned juhuslikud andmeproovid . Suur puhver käitub üldiselt palju deterministlikumalt, nii et kasutage vaikimisi suurt puhvrit .

Õige idee, kuid mitte päris õige väitega "See puhver on täis, see lihtsalt langeb uued andmed." Kui puhver on täidetud, ei loobuta andmeid, pigem kirjutatakse plokk, kuni väljuvas puhvris on ruumi. See tähendab, et sisend ja väljund voolavad peagi sama keskmise kiirusega, kuid nende vahel on puhvri latentsus.
Daniel Eisterhold
2014-06-05 07:50:26 UTC
view on stackexchange narkive permalink

Seeriandmete pideva saatmise asemel saatke andmeid ainult siis, kui potentsiomeetri väärtus on teatud künnise kohal muutunud.

  int oldValue = 0; const int lävi = 5; void setup ( ) {Seeria.algus (9600); pinMode (A0, INPUT)} void loop () {if (oldValue > = analogRead (A0) + lävi || oldValue < = analogRead (A0) -läve) {Serial.println (analogRead (A0)); oldValue = analogRead (A0); }}  
See "loop ()" ei täida väljundpuhvrit võrdsete proovidega, see on hea. Kuid see töötab ikkagi protsessori täiskiirusel, mis võib olla 100 korda nii kiire kui vaja. See tähendab, et see suudab ikkagi puhvri kiiresti piirini täita, kui sisend muutub sageli, näiteks müra ületamisel `läve` või pideva suure eraldusvõimega muutuse korral (mida siin näite rakenduses ei tehta)
Rishi Swethan
2017-06-03 03:35:34 UTC
view on stackexchange narkive permalink

Kaks lihtsat lahendust, mis sobivad kindlasti kõigile, kes alles otsivad: -

  1. Suurendage viivitust 50–100 millisekundini.

  2. Lisage see pärast Serial.begin (9600) -i jaotises setup();

      Serial.setTimeout (50) ;  

Teine samm on kõige olulisem. Minu jaoks töötas see alles pärast ülaltoodud koodi lisamist. Seda ei mainita väga sageli paljudes teistes foorumites, mida olen otsinud, kui mul oli täpselt sama probleem.

See on mõnevõrra ekslik. Meetod setTimeout () kehtib sisendi, mitte väljundi kohta - vaadake dokumentatsiooni aadressil https://www.arduino.cc/en/Serial/SetTimeout


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...