Cuprins:
- Pasul 1: caz de utilizare: netezirea măsurătorilor ADC
- Pasul 2: caz de utilizare: măsurarea componentei CC a semnalului microfonului
- Pasul 3: Calcul
- Pasul 4: Codul
- Pasul 5: Extra
- Pasul 6: Concluzie
Video: Media de rulare pentru proiectele dvs. de microcontroler: 6 pași
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:42
În acest instructiv, voi explica ce este o medie de rulare și de ce ar trebui să vă pese de ea, precum și să vă arăt cum trebuie implementată pentru o eficiență calculală maximă (nu vă faceți griji cu privire la complexitate, este foarte simplu de înțeles și voi oferiți o bibliotecă ușor de utilizat și pentru proiectele dvs. arduino:)
Media de funcționare, denumită în mod obișnuit și medie mobilă, medie mobilă sau medie de funcționare, este un termen folosit pentru a descrie valoarea medie a ultimelor N valori din seriile de date. Poate fi calculat la fel ca media normală sau puteți utiliza un truc pentru a avea un impact minim asupra performanței codului dvs.
Pasul 1: caz de utilizare: netezirea măsurătorilor ADC
Arduino are un ADC decent de 10 biți cu foarte puțin zgomot. Când măsurați valoarea unui senzor, cum ar fi potențiometrul, fotorezistorul sau alte componente cu zgomot ridicat, este greu să aveți încredere că măsurarea este corectă.
O soluție este să luați mai multe măsurători de fiecare dată când doriți să citiți senzorul și să le calculați în medie. În unele cazuri, aceasta este o soluție viabilă, dar nu întotdeauna. Dacă doriți să citiți ADC de 1000 de ori pe secundă, ar trebui să faceți 10 000 dacă ați lua în medie 10 măsurători. O mare pierdere de timp de calcul.
Soluția mea propusă este de a lua măsurători de 1000 de ori pe secundă, de a actualiza media de rulare de fiecare dată și de a o folosi ca valoare curentă. Această metodă introduce o anumită latență, dar reduce complexitatea de calcul a aplicației dvs., oferindu-vă mult mai mult timp pentru procesare suplimentară.
În imaginea de mai sus am folosit media de rulare a ultimelor 32 de măsurători. Veți vedea că această metodă nu este 100% rezistentă la erori, dar îmbunătățește semnificativ acuratețea (nu este mai rău decât media a 32 de eșantioane de fiecare dată). Dacă ați dori să calculați o medie de 32 de măsurători de fiecare dată, ar dura peste 0,25 ms pe Arduino UNO numai pentru măsurători!
Pasul 2: caz de utilizare: măsurarea componentei CC a semnalului microfonului
Arduino poate măsura tensiuni între 0 și Vcc (în mod normal 5 V). Semnalul audio este complet AC și dacă doriți să îl măsurați pe un microcontroler, trebuie să-l plasați în jur de 1/2 Vcc. Într-un proiect Arduino UNO care ar însemna aproximativ 2,5 V (DC) + semnal audio (AC). Când utilizați sursa de alimentare ADC de 10 biți și 5 V, distorsiunea de 2,5 V trebuie să fie egală cu o măsurare de 512. Deci, pentru a obține o valoare de curent alternativ a semnalului, 512 ar trebui scăzut din măsurarea ADC și asta este, nu?
Într-o lume ideală, asta ar fi adevărat. Din păcate, viața reală este mai complicată, iar tendința noastră de semnal tinde să derive. Foarte frecvent este zgomotul de 50 Hz (60 Hz dacă locuiți în SUA) din rețeaua electrică. De obicei, nu este prea problematic, dar este bine să știm că există. Mai problematică este derivarea liniară de la încălzirea componentelor. Setați cu atenție corecția offset DC la pornire și se îndepărtează încet pe măsură ce aplicația dvs. rulează.
Voi ilustra această problemă cu un detector de ritm (muzical). Vă configurați eliminarea prejudecății și bătăile sunt clare (imaginea 2). După ceva timp, polarizarea DC se mișcă și bătăile sunt abia vizibile pentru microcontroler (imaginea 3). Algoritmul de detectare a bătăilor va fi explorat în profunzime într-un viitor instructiv, deoarece depășește domeniul de aplicare al acestui articol.
Din fericire, există o modalitate de a continua să calculăm în mod constant offset-ul audio DC. Nu va fi o surpriză faptul că media de rulare, subiectul acestui instructable, oferă o soluție.
Știm că valoarea medie a oricărui semnal de curent alternativ este 0. Folosind aceste cunoștințe putem deduce că valoarea medie a semnalului de curent alternativ + curent continuu este că este o polarizare continuă. Pentru a-l elimina, putem lua o medie de funcționare a ultimelor câteva valori și o putem scădea din citirea ADC curentă. Rețineți că trebuie să utilizați o medie de rulare suficient de lungă. Pentru sunet, o zecime de secundă (numărul de eșantioane depinde de rata de eșantionare) ar trebui să fie suficientă, dar să știți că mediile mai lungi funcționează mai bine. În prima imagine puteți vedea un exemplu de calcul al polarizării DC reale cu media de rulare cu 64 de elemente la o rată de eșantionare de 1 kHz (mai puțin decât am recomandat, dar funcționează în continuare).
Pasul 3: Calcul
Vă puteți imagina media de rulare ca o medie a greutății persoanelor din sala de așteptare a medicului. Doctorul termină examinarea unui pacient și simultan unul nou intră în sala de așteptare.
Pentru a afla greutatea medie a tuturor pacienților care așteaptă în sala de așteptare, asistenta ar putea apoi să întrebe fiecare pacient despre greutatea lor, să adune aceste numere și să împartă la numărul de pacienți. De fiecare dată când medicul acceptă un nou pacient, asistenta ar repeta întregul proces.
S-ar putea să vă gândiți: „Acest lucru nu sună prea eficient … Trebuie să existe o modalitate mai bună de a face acest lucru.” Și ai fi corect.
Pentru a optimiza acest proces, asistenta ar putea ține o evidență a greutății totale a grupului actual de pacienți. Odată ce medicul sună pacientul nou, asistenta îl întreabă despre greutatea sa și îl scade din totalul grupului și îl lasă să plece. Asistenta ar întreba apoi pacientul care tocmai a intrat în sala de așteptare despre greutatea sa și a adăugat-o la total. Greutatea medie a pacienților după fiecare schimbare ar fi suma greutăților împărțite la numărul de pacienți (da, la fel ca înainte, dar acum asistenta a întrebat doar două persoane despre greutatea lor în loc de toți). Îmi dau seama că acest paragraf ar fi putut fi puțin confuz, așa că vă rugăm să consultați ilustrația de mai sus pentru mai multă claritate (sau puneți întrebări în comentarii).
Dar, chiar dacă nu ați găsit confuz ultimul paragraf, s-ar putea să aveți întrebări precum ce ar trebui să fie în acumulator la început, cum pot pune ceea ce tocmai am citit într-un cod C real? Acest lucru va fi abordat în pasul următor, unde veți obține și codul meu sursă.
Pasul 4: Codul
Pentru a calcula media de rulare, mai întâi aveți nevoie de o modalitate de a stoca ultimele N valori. ați putea avea o matrice cu N elemente și puteți muta întregul conținut la un loc de fiecare dată când adăugați un element (vă rugăm să nu faceți acest lucru), sau puteți suprascrie un element vechi și reglați indicatorul la următorul element pentru a fi aruncat (vă rugăm să faceți acest lucru:)
Acumulatorul ar trebui să înceapă inițializat la 0, același lucru este valabil pentru toate elementele din linia de întârziere. În alt caz, media de rulare va fi întotdeauna greșită. Veți vedea că delayLine_init se ocupă de inițializarea liniei de întârziere, ar trebui să vă ocupați singur de acumulator.
adăugarea unui element la linia de întârziere este la fel de ușoară ca descreșterea indexului celui mai nou element cu 1, asigurându-ne că nu indică partea matricei de linie de întârziere. după decrementarea indexului atunci când este 0, va rula în jurul valorii de 255 (deoarece este un număr întreg de 8 biți nesemnat). Operatorul Modulo (%) cu dimensiunea liniei de întârziere se va asigura că indexul va indica un element valid.
Calculul unei medii curente ar trebui să fie ușor de înțeles dacă mi-ați urmat analogia în pasul anterior. Scoateți cel mai vechi element din acumulator, adăugați cea mai nouă valoare acumulatorului, împingeți cea mai nouă valoare pe linia de întârziere, întoarceți acumulatorul împărțit la numărul de elemente.
Ușor, nu?
Nu ezitați să experimentați utilizarea codului atașat pentru a înțelege mai bine cum funcționează toate acestea. În prezent, arduino citește valoarea analogică pe pinul analogic A0 și tipărește „[valoare ADC], [medie de rulare]” pe portul serial la o rată de 115200 baud. Dacă deschideți plotterul serial arduino la rata de transmisie corectă, veți vedea două linii: valoarea ADC (albastru) și valoarea netezită (roșu).
Pasul 5: Extra
Există câteva lucruri pe care nu trebuie neapărat să le cunoașteți pentru a utiliza media de rulare în proiectul dvs. ut nu va strica să știți.
întârziere: voi începe cu a vorbi despre ilustrarea acestui pas. Veți observa că media de rulare a mai multor elemente introduce o întârziere mai mare. Dacă timpul dvs. de răspuns la schimbarea valorii este critic, vă recomandăm să utilizați o medie de rulare mai scurtă sau să măriți rata de eșantionare (măsurați mai des).
Trecând peste.
inițializare: Când am vorbit despre inițializarea acumulatorului și a elementelor de întârziere, am spus că ar trebui să le inițializăm pe toate la 0. Alternativ, puteți inițializa linia de întârziere la orice doriți, dar acumulatorul ar trebui să înceapă ca o sumă de cele mai noi N elemente din linia de întârziere (unde N este numărul de elemente din media dvs. de rulare). Dacă acumulatorul pornește ca orice altă valoare, media calculată va fi greșită - fie prea mică, fie prea mare, întotdeauna cu aceeași cantitate (presupunând aceleași condiții inițiale). Vă sugerez să încercați să aflați de ce este așa utilizând o „simulare stilou și hârtie”.
dimensiunea acumulatorului: ar trebui să rețineți, de asemenea, că acumulatorul ar trebui să fie suficient de mare pentru a stoca suma tuturor elementelor în linia de întârziere dacă toate sunt maxime pozitive sau negative. Practic, acest lucru înseamnă că acumulatorul ar trebui să fie cu un tip de date mai mare decât elementele de linie de întârziere și semnat, dacă elementele de linie de întârziere sunt semnate.
truc: Liniile cu întârziere lungă ocupă multă memorie. Acest lucru poate deveni rapid o problemă. Dacă sunteți foarte limitat de memorie și nu vă pasă prea mult de acuratețe, puteți aproxima media de rulare omițând întârzierea complet și făcând acest lucru în schimb: scădeți acumulatorul 1 / N * din acumulator și adăugați o valoare nouă (de exemplu, media medie de funcționare 8: acumulator = acumulator * 7/8 + newValue). Această metodă dă rezultate greșite, dar este o metodă decentă de calcul al mediei de rulare atunci când nu aveți suficientă memorie.
lingvistică: „media de rulare / medie” este de obicei utilizată atunci când se referă la media în timp real, în timp ce „media mobilă / medie” înseamnă, de obicei, că algoritmul rulează pe un set de date statice, cum ar fi foaia de calcul Excel.
Pasul 6: Concluzie
Sper că acest instructiv a fost suficient de ușor de înțeles și că vă va ajuta în proiectele viitoare. Vă rugăm să nu ezitați să postați întrebări în comentariile de mai jos dacă există ceva neclar.
Recomandat:
Steam Punk UPS-ul dvs. pentru a obține ore de funcționare pentru routerul dvs. Wi-Fi: 4 pași (cu imagini)
Steam Punk UPS-ul dvs. pentru a obține ore de funcționare pentru routerul dvs. Wi-fi: există ceva fundamental dezagreabil în ceea ce privește ca UPS-ul dvs. să-și convertească puterea bateriei de 12V DC în 220V AC, astfel încât transformatoarele care rulează routerul și fibra ONT să-l poată converti din nou în 12V DC! De asemenea, vă confruntați cu [de obicei
Primiți notificări prin e-mail din proiectele dvs. IoT: 6 pași
Primiți notificări prin e-mail din proiectele dvs. IoT: notificări prin e-mail ale programului care conectează proiectele dvs. IoT la Adafruit IO și IFTTT. Am publicat câteva proiecte IoT. Sper că le-ați văzut, dacă nu, vă invit la profilul meu și le verific. Am vrut să primesc câteva notificări atunci când o variabilă
LED-uri curcubeu pentru proiectele dvs.: 4 pași (cu imagini)
LED-uri curcubeu pentru proiectele voastre: Bună tuturor! Am folosit aceste LED-uri pentru multe proiecte decorative și rezultatul este întotdeauna uimitor, așa că vreau să vă împărtășesc experiențele cu voi. modul de schimbare a culorii doar la
Suport baterie de gherilă pentru proiectele dvs. Breadboard / Arduino: 3 pași
Suport baterie de gherilă pentru proiectele dvs. Breadboard / Arduino: experimentez cu DS1307 și Arduino, a trebuit să găsesc o modalitate de a conecta o baterie CR1212. Am scotocit în cutia de conectori și nu am găsit nimic care să mă poată ajuta. Apoi, eur ê ka! Am avut o iluminare
Lista de ** STUFF GRATUIT ** pentru proiectele dvs.: 8 pași
Lista de ** PRODUSE GRATUITE ** pentru proiectele dvs.: Aceasta este o listă de locuri din care puteți obține lucruri GRATUITE, le puteți folosi în proiectele dvs. …. Este gratuit și articolele sunt livrate gratuit Deci, da, sper că vă place lista! Ok, așa că am organizat acest lucru instructabil în funcție de tipul de produs. PM mine dacă aveți un site