Küsimus:
Arduino ajaarvamine millis () abil pole täpne või õige?
user3284376
2014-03-10 04:28:49 UTC
view on stackexchange narkive permalink

Olen Arduinot kasutanud andmete salvestamiseks. Arduino sketšis kasutasin ka funktsiooni millis () , et saaksin jälgida iga mõõdetava väärtuse võtmise aega. Siiski märkasin, et ajastus pole õige. Näiteks päriselus tuleb 30 sekundit välja ainult 10 sekundina (see on näide).

Kas mul on õigus öeldes, et Arduino viivitusfunktsioon mõjutab ajakulu, kasutades millis () ? Teisisõnu oletan, et mul on viivitus 50 ms, kas see tähendab, et funktsioon millis () peatub ka selle kestuse vältel ja jätkub siis nii kaua, kuni ühendus kestab? Ma märkasin seda, kui proovisin joonistada mõnda teavet ja leida, et minu andmete tippude sagedus oli möödunud aega arvestades liiga sagedane. Nii et ma tahan teada, kas see on selle ajastuse mittevastavuse põhjus ja kui jah, siis kuidas seda parandada, et saaksin hoida iga proovi esinemise aega?

Siin on konteksti andmiseks minu visand :

  #include <eHealth.h> unsigned long time; // Seadistusrutiin töötab üks kord, kui vajutate reset: void setup () {Serial.begin (9600); } // Tsükli rutiin jookseb ikka ja jälle igavesti: void loop () {float EKG = eHealth.getECG (); aeg = millis (); Seeriaprint (aeg); Seeriaprint (""); Seeriaprint (EKG, 5); Serial.println (""); viivitus (50);}  
Kas kasutate mõnda ametlikku Uno tahvlit?
Tegelik ajastamine väljamõeldud väärtuste asemel (joonte ajatempliga seeriamonitor on ideaalne) aitaks ilmselt toimuvast aru saada.
Funktsiooni "millis ()" arvutamine on katkestuspõhine, nii et "delay ()" ei tohiks seda mõjutada.
Mul on sama probleem, kuid ainult siis, kui integreerin selle (millis ()) keerukasse koodi. Ma arvan, et koodi keerukus mõjutab selle täpsust, kuna see viivitab koodi keerukusega üha enam. Kas on kuidagi võimalik seda vältida? äkki kasutate eraldatud RTC moodulit?
Kolm vastused:
#1
+10
Cybergibbons
2014-03-10 14:15:13 UTC
view on stackexchange narkive permalink

millis () on katkestusjõuline, nii et delay () ei mõjuta seda, vähemalt mitte ATmega-põhisel tahvlil.

See ei tähenda, et ka millis () on täiesti täpne. Taimeri iga linnuke pole täpselt 1 ms, kuid on 1,024 ms. See viga koguneb järk-järgult, kuni parandus on tehtud. Seda on näha katkestuskäitleja TIMER0_OVF (taimer 0 ülevool) rakendamisel.

Teine ebatäpsuse allikas on ostsillaator / kristall ise, mis pole täpselt 16MHz. See on siiski üsna lähedal ja seni, kuni temperatuur ei muutu liiga palju, on suhteliselt stabiilne.

Ülaltoodu tähendab, et millis () code kasutamisel võite olla umbes 1 ms kaugusel >. See ei tundu teie probleemina.

Teine potentsiaalne probleem oleks see, mida getECG () teeb - see võib olla väga aeglane.

  ujuk eHealthClass :: getECG (tühine) {ujukanaloog0; // Loe analoogsest in. Analoog0 = analogRead (0); // binaarse pinge muundamise tagastamise analoog0 = (ujuk) analoog0 * 5 / 1023,0; }  

analogRead () on aeglane, kuid mitte nii aeglane, et sellisele silmusele mõju avaldada.

Teine probleem, mida olen inimesi näinud on see, kui nad muudavad kella kiirust, kuid ei muuda boards.txt õigesti. See tähendab, et rakenduses millis () kasutatavad konstandid on valed ja kellaajad valed.

Kui soovite väärtusi lugeda iga 50 ms tagant, on palju parem viis rakendamiseks see on järgmine:

  staatiline pikk lastUpdate; if (millis () - lastUpdate > 50) {lastUpdate = millis (); // Tehke asju}  

Peaksime tõesti nägema teile saadetud ajatemplid. Kui näete, et 30-aastased näitavad kümnendatena, on tööl midagi muud.

Pange tähele, et Uno jaoks ei ole kell kristallipõhine, vaid kasutab lihtsalt keraamilist resonaatorit, mis on vähem täpne kui kristall.
@jfpoilpret Ah hea teada. [Skeemi vaadates] (http://arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf) oleks see CSTCE16M0V53-R0 [Murata CERALOCK-seade] (http://www.mouser.com / ProductDetail / Murata-Electronics / CSTCE16M0V53-R0 /? Qs = HPA2Xx% 252bU0WhPWbRcNuzhZw ==).
Resonaatoritel on halb algtolerants (sageli 0,5–2%) ja halb temperatuuri stabiilsus, kuid kui kalibreerite nende kasutamisel ajavõtusilmuseid, võivad need korras olla seni, kuni temperatuur ei liigu.
Millis () töötab ikka taimeril, mis tiksub iga 1,024 ms järel, kuid nad lisasid veakompensatsiooni, suurendades seda alati, kui veamõõturi muutuja muutub liiga kõrgeks. Ma arvan, et see on tegelikult Roman Blacki algoritm. Nii et ajastus peaks olema palju täpsem kui 1 ms. Https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring.c
Neile, kes on endiselt huvitatud, vaadake kommentaari, mille olen postitanud JRoberti vastusele, ma ei tahtnud oma vastusega vastata, kuna mul pole seda, ma lihtsalt sõnastasin probleemi uuesti.
Rohkem optimeeritud `getECG`:` float eHealthClass :: getECG (void) {return analogRead (0) * 5 / 1023.0; } "
#2
+2
JRobert
2014-03-11 21:08:00 UTC
view on stackexchange narkive permalink

Kui katkestused on mõne olulise osa jaoks välja lülitatud eHealth.getECG () kõne kestus, võib millis () arv jääda maha. Vastasel juhul peaks millis () tagastama palju täpsema aja kui teie kirjeldatud kolmekordsed vead.

Ütlesite, et teie valimisignaali sagedus on suurem kui eeldasite, mis võib juhtuda, kui teie valimissagedus on kavandatust madalam. Kas eeldate 20Hz valimissagedust? Teie silmus võib võtta natuke kauem kui 50 ms, mida näete trükitud aegadel, kuid need peaksid ikkagi jälgima kella aega. Kui te seda ei arvestanud, kuid eeldasite 50 ms valimi kohta, näeksite andmete ilmset kiirust.

Kui see pole probleem, siis oleks järgmine samm lülitada väljund, kui olete loop () -is, ja mõõtke saadud ruutlaine sagedust sagedusmõõturiga (mõned odavad DVM-id saavad seda teha) või 'ulatuse abil. Tehke sama asja tühja loop () abil. Esimeses katses määratakse teie tegelik proovivõtusagedus või intervall; teine ​​ütleb teile, kas millis () (st. taimeri0 sagedus) on see, mida te ootasite.

Olen sellega edasi mänginud ja aru saanud, et küsimus pole Arduinos, funktsioon millis () töötab enamasti väga hästi, mõned väärtused ei ole täpselt 8 ms (viivitus) kaugusel, vaid millest olete öelnud, et seda on oodata. Kirjeldatud 3x viga kehtib asjade Pythoni poolel, mida ma andmete vastuvõtmiseks kasutasin. Mis tahes idee, mille see võiks olla, kasutan Pythoni püseriala ja see on pagana aeglane.
Ma ei tea teie rakendusest piisavalt, et anda teile rohkem kui 1 / [email protected]'d oletus, kuid kas Pythoni külg on proovide viskamiseks piisavalt aeglane?
#3
  0
user48711
2015-09-04 01:29:18 UTC
view on stackexchange narkive permalink

Sama siin. Võin lisada, et kui katkestused välja lülitada, on mõõdetud aeg "reaalajas". Igatahes ei saa ma aru, miks see viivitus on, sest kui tsükkel võtab liiga kaua aega, peaksid millised () tagastama reaalajas väärtused (ainult siis, kui iga väärtuse vahel on suurem vahemaa)

Mida viitab "sama siin"? Vastused peaksid iseseisvalt seisma, kuna StackExchange saab asju ümber korraldada (erinevalt foorumist). Nii et "sama siin" võib tähendada kõike, sõltuvalt sellest, millise vastuse / küsimuse all teie vastus ilmub.
This post would be more appropriate as a comment, although (admittedly) you lack sufficient reputation .
Vabandust, kui ma aga midagi vastate, on ilmselge, et see viitab peamisele postitusele, muidu oleks see kommentaar


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