Küsimus:
Arduino ülitäpne ajastus seeriasideks
user3284376
2014-03-11 14:13:09 UTC
view on stackexchange narkive permalink

Kasutan Arduino Unot aja- ja pingeteabe edastamiseks jadapordi kaudu Pythonile kruntimiseks. Siiski näib järjestikuste ajatemplite ajavahemik aja jooksul suurenevat, mõjutades minu kavandamist. See kehtib eriti siis, kui baudi kiiruseks on seatud 9600, kus minu esialgsed ajaerinevused võivad olla 1320 ja suurenevad suhteliselt lühikese aja möödudes 16400-ni. Kui see kiirus on maksimaalselt 115200 bps, on muutus aeglasem ja vähem märgatav, umbes 1340-lt 1500-le isegi pärast suhteliselt pikka saatmist. Kõik ajad on antud mikrosekundites.

Tahaksin teada, kas saan seda efekti vähendada või selle kõrvaldada ja kui ei saa aru, miks see eksisteerib. Olen lugenud asju katkestuste ja viivituste kohta, mis seda põhjustavad, kuid ma ei mõista täielikult olemasoleva elektroonika keerukust ja tahaksin teada:

  1. Kas ma saan täpsust ajastada?
  2. Mis põhjustab aja muutuse?

Siin on see, mis mul praegu on:

  #include <eHealth.h>extern lenduv allkirjastamata pikk taimer0_overflow_count; float fanalog0; int analoog0; allkirjastamata kaua; bait serialByte; void setup () {Serial.begin (9600);} void loop () {while (Serial.available () >0) {serialByte = Serial.read (); if (serialByte == 'S') {while (1) {fanalog0 = eHealth.getECG (); // Kasutage taimerit0 = > 1 linnuke iga 4 aja järel = (timer0_overflow_count << 8) + TCNT0; // Mikrosekundite teisendamine. aeg = (aeg * 4); // Simuleerimiseks faili printimine //Serial.print(time); //Serial.print (""); Seeriaprint (fanalog0,5); Serial.print ("\ n"); if (Serial.available () >0) {serialByte = Serial.read (); kui (serialByte == 'F') puruneb; }}}}}  
Mida sa mõtled "täpse" all? Loenduri antud kellaajad saavad olema üsna täpsed, täpsed ja hea resolutsiooniga. Kas soovite, et ajad oleksid deterministlikud (st alati samad)?
Vabandused jah
Lisage ajatempel arvuti lõppu, mitte Arduino lõppu, või kasutage RTC (reaalajas kell) moodulit. RTC mooduleid on erinevatest veebipoodidest üsna odav leida, lihtsalt veenduge, et pood linkiks andmelehele. Teine meetod on taimeri programmeerimine ja katkestusteenuse rutiini kasutamine, et saada piisavalt täpne ajastus.
Mida teeb "eHealth.getECG ()"? Kas see kõne kestab alati sama palju aega?
Kas saate täpsustada, kui kaua "suhteliselt lühike ajavahemik" kestab? Kas pärast Arduino taaskäivitamist on see alati sama?
getECG () kutsub funktsiooni, mis võtab subjektiga ühendatud elektroodidelt EKG väärtuse. See on pinge väärtus ja lühike ajavahemik hõlmab tavaliselt 10–15 sekundit
Meetodi "getECG ()" postitamine võib aidata teie täheldatud käitumist selgitada. Kas see on meetod, mille kirjutasite ise või hankisite selle raamatukogust?
Ehkki mul pole EKG kraami, olen püüdnud teie kirjeldatud käitumist taasesitada (ja asendanud `getECG ()` lihtsa `viivitusega (10) '). 9600 bps juures ei suutnud ma jälgida aja muutumist, nagu te kirjeldate.
Ajatempli lisamine arvuti lõpus oleks hea, et vältida * vigade kogunemist, kuid lisab USB-jadale * asünkroonse paketiseerimise * tõttu mõningaid värinaid *. Nii et lühiajaliste täpsete intervallide jaoks oleks parem fikseerida ajatempel allikale.
"getECG ()" teisendab lihtsalt analoogväärtuse analog0 pinge väärtuseks 0-5, see on lihtne arvutus.
Kolm vastused:
#1
+4
jippie
2014-03-11 22:16:43 UTC
view on stackexchange narkive permalink

Kasutage ajastuse täpsemaks muutmiseks taimerit ja ISR-i (katkestage teenuse rutiin).

Vaadake minu 1 ms ajastatud katkestuse kontseptsiooni tõendit. Idee on selles, et süsteemis oleks piisavalt täpne 1 ms "südamelöök", mida saab kasutada muude sündmuste käivitamiseks. PoC-s kasutatakse seda LED-i vilkumiseks ½Hz juures, kuid juurdepääs uutele muutujatele millisecondCounter ja secondCounter võimaldab teil meelevaldselt (kuid täpselt ajastatud) hetki.

Teie PoC on väga huvitav, kuid sellel on viga (seda on lihtne parandada), kuna see loeb 2-baidist väärtust, kui katkestused on lubatud (in "loop ()"), seda väärtust muudab ISR. Võib juhtuda, et `loop ()` loeb halba väärtust (keset ISR-i tehtud modifikatsiooni). Ma postitasin teie blogisse selle kohta kommentaari.
@jfpoilpret huvitav punkt, mille seal teete, pole kunagi mõelnud katkestusele, mis toimub poolel teel RAM-i väärtuse hankimisel. Ma kontrollin täna õhtul lahtivõtmist ja värskendan artiklit. Võib-olla on hea põhjus ka teise artikli kirjutamiseks: o)
Lõin proovi teie PoC-st ja nägin, et probleem ilmnes minu UNO-s vähemalt kord 10 sekundi jooksul. Kuid tegelikkuses sõltub see suuresti sellest, mida teete oma "loop ()" -s: minu proov sai just millisekundite väärtuse, võrdlesin seda eelmise loetud väärtusega ja kui erinevus> 0 (välja arvatud nullimine loendurile 0), kuvage sõnum.
@jfpoilpret pole seda tegelikult kunagi märganud. Ma kasutan seda lihtsalt südamelöökidena, et jälgida oma kasside toiduämbreid ja teha LED-välklamp, kui minu kassid võivad pettuda ...; o) See kindlasti muudab viisi, kuidas ma ISR-e tulevikus kasutan.
@jfpoilpret kood on uuendatud. Vaja istuda, et sellest kena blogi kirjutada. Thnx
Kuigi Uno saavutab eraldusvõime 1 ms kergesti, on selle ajabaas tavaliselt halvem kui 1000 ppm. Teisisõnu triivib see tavaliselt üle 1 ms sekundis. Pole harvad juhud, kui UNOs triivib iga 10 minuti järel rohkem kui 1 sekundit.
@UdoKlein Täpseks ajahoidmiseks peaksite siiski kasutama RTC-d, kuid 1000ppm on kristall-ostsillaatori jaoks palju. Ootaksin suurusjärku 100ppm
UNO-l pole kontrolleri jaoks kristalloskillaatorit. Sellel on ainult seeriaühenduse jaoks kristall-ostsillaator. Peakontrollerit juhitakse resonaatorist. Seega on UNO tüüpiline kõrvalekalle >> 1000 ppm. Vanemate Arduinode (kristallidega) väärtus oli varem ~ 30 ppm või parem.
@UdoKlein http: // arduino.cc / et / uploads / Main / Arduino_Uno_Rev3-schematic.pdf näitab endiselt 16MHz kristalli.
See näitab plokiga ATMEGA16U2 ühendatud kristalli ja ATMEGA328P-PU-ga ühendatud resonaatorit. 16U2 on jadaliidese jaoks, 328P on "The Arduino". Huvitav on see, et 16U2 suudaks oma kella lükata teise kiibini, nt. 328P.
@UdoKlein Otsisin osa numbri ja seisan parandatud. Ebamugav disainiotsus.
#2
+3
zmo
2014-03-11 20:28:40 UTC
view on stackexchange narkive permalink

Ma saan mõelda mõnele asjale, mis võivad mõjutada seeriate kirjutamise ajastuse "järjepidevust":

  • väljatrükitavate andmete suurus

see võib olla kõige ilmsem mõelda, kuid tõepoolest, mida rohkem printida, seda rohkem kulub selle käsitsemiseks.

Lahendus: printige string teadaoleva pikkusega stringiks.

  • puhverdatud jadade kasutamine

unixis pääseb jadapordile puhverdatud või puhverdamata viisil. Puhverdatud viisi pikaajaline kasutamine võib selle puhvri täitumisel veidi aeglustada, tavaliselt juhtub see siis, kui andmed saabuvad kiiremini, kui loete ...

Lahendus: kasutage pakkimata jadarida ( nt : Darwin / OSX-is on /dev/cu.usbmodemXXX asemel /dev/tty.usbmodemXXX)

  • taimerite prioriteet

tundub, et kasutate TC-katkestust ja AVR-idel on katkestuste käsitlemise prioriteedid, ma ei tea Atmega328 prioriteetsuse järjekorda, ja see pole üks kõige dokumenteeritumaid funktsioone, nii et ma ei tea, kui ohutu on TC0 versus UART-katkestus.

Lahendus: otsige katkestuse prioriteetide kohta lisateavet dokumentatsioonist / andmelehest ja muutke taimerit vajadusel ; ja / või tehke test, ilma et teine ​​taimer töötaks.

  • nende andmete lugemine, mida loete, võtab aja jooksul rohkem aega

mõned draiverid peavad keskmistama või tegema mõned toimingud üle eelmiste väärtuste, nii et mida rohkem väärtusi mõõdate, seda pikem on puhver ja seda kauem kulub väärtuse arvutamiseks, kuni olete saavutanud puhvri maksimaalse suuruse.

Lahendus: vaadake kasutatava kogu lähtekoodi ja optimeerige see, eemaldage kalkulaator, kui see on olemas, või võtke arvesse seda pikenevat töötlemisaega.

  • vältides arduino raamistiku üldkulusid

aga kui tõesti soovite arduino seeriaväljundit optimeerida, peaksite vältima arduino üldkulude kasutamist ... Kuid see on nii vähem elegantne ja mugav kasutada.

I " Olen üsna kindel, et mul on veel punkte, mis mul puuduvad, kuid see on esimene asi, mida kontrolliksin enne edasist kaevamist.

#3
+2
Udo Klein
2014-04-28 13:52:37 UTC
view on stackexchange narkive permalink

Teie kood sisaldab väljundi kestust järgmistel mõõtmistel. Seega, sõltuvalt väljundi pikkusest, mõõdate erinevaid aegu. Seda saab fikseerida kindla pikkusega väljundiks.

Järgmine probleem on see, et UNO-l on väga halb ajabaas. Vaadake siit erinevate Arduino tüüpide võrdlust DCF77 ajaviitega.

Järeldus: kui vajate täpset ajastust, hankige kristalliga Arduino või minge RTC-le. . Võin väga soovitada DS3231 / DS3232 RTC-sid, kuna need saavutavad karbist tavaliselt 2 ppm täpsuse.



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...