Съдържание:

Средна стойност за вашите проекти за микроконтролер: 6 стъпки
Средна стойност за вашите проекти за микроконтролер: 6 стъпки

Видео: Средна стойност за вашите проекти за микроконтролер: 6 стъпки

Видео: Средна стойност за вашите проекти за микроконтролер: 6 стъпки
Видео: LDmicro 13: HC-05 Bluetooth Phone App Control (Microcontroller PLC Ladder Programming with LDmicro) 2024, Ноември
Anonim
Средна стойност за вашите проекти за микроконтролер
Средна стойност за вашите проекти за микроконтролер

В тази инструкция ще обясня какво е текуща средна стойност и защо трябва да се интересувате от нея, както и ще ви покажа как тя трябва да бъде приложена за максимална изчислителна ефективност (не се притеснявайте за сложността, тя е много проста за разбиране и ще го направя осигурете лесна за използване библиотека и за вашите arduino проекти:)

Текуща средна стойност, наричана още често плъзгаща се средна, пълзяща средна или текуща средна стойност, е термин, използван за описване на средната стойност на последните N стойности в поредицата от данни. Тя може да бъде изчислена точно като нормална средна стойност или можете да използвате трик, за да я накарате да има минимално въздействие върху производителността на вашия код.

Стъпка 1: Използване: Изглаждане на ADC измерванията

Случай на употреба: Изглаждане на ADC измерванията
Случай на употреба: Изглаждане на ADC измерванията

Arduino има приличен 10 -битов ADC с много малко шум. При измерване на стойност на сензор като потенциометър, фоторезистор или други компоненти с висок шум е трудно да се повярва, че измерването е правилно.

Едно решение е да правите множество измервания всеки път, когато искате да прочетете сензора си, и да ги осредните. В някои случаи това е жизнеспособно решение, но не винаги. Ако искате да четете ADC 1000 пъти в секунда, ще трябва да направите 10 000, ако сте направили средно 10 измервания. Голяма загуба на изчислително време.

Моето предложено решение е да се правят измервания 1000 пъти в секунда, да се актуализира текущата средна стойност всеки път и да се използва като текуща стойност. Този метод въвежда известно забавяне, но намалява изчислителната сложност на вашето приложение, като ви дава много повече време за допълнителна обработка.

На горната снимка използвах средна стойност от последните 32 измервания. Ще видите, че този метод не е 100% отказоустойчив, но значително подобрява точността (не е по -лош от усредняването на 32 проби всеки път). Ако искате да изчислявате средно по 32 измервания всеки път, това би отнело над 0,25 ms на Arduino UNO само за измервания!

Стъпка 2: Използване: Измерване на DC компонента на сигнала на микрофона

Случай на употреба: Измерване на DC компонента на микрофонния сигнал
Случай на употреба: Измерване на DC компонента на микрофонния сигнал
Случай на употреба: Измерване на DC компонент на микрофонния сигнал
Случай на употреба: Измерване на DC компонент на микрофонния сигнал
Случай на употреба: Измерване на DC компонента на микрофонния сигнал
Случай на употреба: Измерване на DC компонента на микрофонния сигнал

Arduino може да измерва напрежения между 0 и Vcc (обикновено 5 V). Аудио сигналът е напълно AC и ако искате да го измерите на микроконтролер, трябва да го отклоните около 1/2 Vcc. В проект на Arduino UNO това би означавало приблизително 2.5 V (DC) + аудио сигнал (AC). Когато използвате 10 -битов ADC и 5 V захранване, 2,5 V отклонение трябва да е равно на измерване на 512. Така че, за да получите AC стойност на сигнала, 512 трябва да се извади от ADC измерването и това е, нали?

В един идеален свят това би било вярно. За съжаление реалният живот е по -сложен и нашето сигнално отклонение има тенденция да се отклонява. Много често се получава 50 Hz шум (60 Hz, ако живеете в САЩ) от електрическа мрежа. Обикновено не е твърде проблематично, но е добре да знаете, че съществува. По -проблемен е линейният отклонение от нагряването на компонентите. Внимателно задавате корекция на DC offset при стартиране и тя бавно се отдалечава, докато приложението ви работи.

Ще илюстрирам този проблем с (музикален) детектор на ритъма. Настройвате премахването на пристрастията и ударите са ясни (снимка 2). След известно време DC отклонението се движи и ударите са едва забележими за микроконтролера (снимка 3). Алгоритъмът за откриване на ритъм ще бъде разгледан задълбочено в бъдещи инструкции, тъй като надхвърля обхвата на тази статия.

За щастие има начин непрекъснато да се изчислява DC компенсирането на аудиото. Няма да е изненада, че средностатистическата тема на тази инструкция предоставя решение.

Знаем, че средната стойност на всеки AC сигнал е 0. Използвайки тези знания, можем да извадим, че средната стойност на AC+DC сигнала е неговото DC отклонение. За да го премахнем, можем да вземем средна стойност от последните няколко стойности и да я извадим от текущото отчитане на ADC. Имайте предвид, че трябва да използвате достатъчно дълга средна стойност. За аудио десета от секундата (броят на пробите зависи от честотата на дискретизация) трябва да е достатъчна, но знайте, че по -дългите средни стойности работят по -добре. На първата снимка можете да видите пример за изчисляване на реални DC пристрастия с текуща средна стойност от 64 елемента при честота на дискретизация 1 kHz (по -малко от препоръчаното от мен, но все още работи).

Стъпка 3: Изчисление

Изчисление
Изчисление

Можете да си представите средната стойност като средно тегло на хора в чакалнята на лекаря. Лекарят завършва прегледа на един пациент и едновременно с това нов влиза в чакалнята.

За да установи средното тегло на всички чакащи пациенти в чакалнята, медицинската сестра може след това да попита всеки пациент за тяхното тегло, да добави тези числа и да ги раздели на броя на пациентите. Всеки път, когато лекарят приеме нов пациент, сестрата ще повтори целия процес.

Може би си мислите: "Това не звучи прекалено ефективно … Трябва да има по -добър начин да направите това." И бихте били прави.

За да оптимизира този процес, медицинската сестра може да води отчет за общото тегло на настоящата група пациенти. След като лекарят повика нов пациент, медицинската сестра ще го попита за теглото му и ще го извади от общата група и го пусне. След това сестрата би попитала пациента, който току -що влезе в чакалнята, за теглото му и го добави към общата сума. Средното тегло на пациентите след всяка смяна ще бъде сума от теглата, разделена на броя на пациентите (да, същото като преди, но сега медицинската сестра попита само двама души за тяхното тегло, вместо всички тях). Осъзнавам, че този параграф може да е бил малко объркващ, затова, моля, вижте илюстрацията по -горе за допълнителна яснота (или задайте въпроси в коментарите).

Но дори и да не ви се стори последният абзац объркващ, може да имате въпроси като например какво трябва да има в акумулатора в началото, как да поставя това, което току -що прочетох, в действителен C код? Това ще бъде разгледано в следващата стъпка, където ще получите и моя изходен код.

Стъпка 4: Кодът

Кодът
Кодът

За да изчислите текущата средна стойност, първо се нуждаете от начин за съхраняване на последните N стойности. можете да имате масив с N елементи и да премествате цялото съдържание на едно място всеки път, когато добавяте елемент (моля, не правете това), или можете да презапишете един стар елемент и да коригирате показалеца към следващия елемент, който ще бъде изхвърлен (моля, направете това:)

Акумулаторът трябва да започне да се инициализира на 0, същото важи и за всички елементи в закъснителната линия. В противен случай средната Ви стойност винаги ще бъде грешна. Ще видите, че delayLine_init се грижи за инициализиране на линията на закъснение, вие сами трябва да се погрижите за акумулатора.

добавянето на елемент към закъснителната линия е толкова лесно, колкото намаляване на индекса на най -новия елемент с 1, като се уверите, че не посочва страна на масив от редове за забавяне. след намаляване на индекса, когато е 0, той ще се върти около 255 (тъй като е 8 -битово беззнаково цяло число). Операторът Modulo (%) с размера на масив от линии на закъснение ще гарантира, че индексът ще сочи към валиден елемент.

Изчисляването на текуща средна стойност трябва да бъде лесно за разбиране, ако следвате моята аналогия в предишната стъпка. Извадете най -стария елемент от акумулатора, добавете най -новата стойност към акумулатора, натиснете най -новата стойност към линията на забавяне, върнете акумулатора, разделен на броя елементи.

Лесно, нали?

Моля, не се колебайте да експериментирате с използването на приложения код, за да разберете по -добре как работи всичко това. Както е в момента, arduino чете аналогова стойност на аналоговия щифт A0 и отпечатва "[ADC стойност], [текуща средна стойност]" на сериен порт при скорост 115200 бода. Ако отворите серийния плотер на arduino с правилна скорост на предаване, ще видите два реда: ADC стойност (синя) и изгладена стойност (червена).

Стъпка 5: Екстри

Екстри
Екстри

Има няколко неща, които не е задължително да знаете, за да използвате средната стойност в проекта си. Няма да навреди да знаете.

забавяне: Ще започна с говорене за илюстрация на тази стъпка. Ще забележите, че средната стойност на повече елементи въвежда по -голямо забавяне. Ако времето за реакция за промяна на стойността е критично, може да искате да използвате по -къса текуща средна стойност или да увеличите честотата на извадката (измервайте по -често).

Преместване на.

инициализиране: Когато говорих за инициализиране на акумулатор и елементи на закъснение, казах, че трябва да ги инициализирате на 0. Алтернативно можете да инициализирате закъснение на всичко, което искате, но акумулаторът трябва да започне като сума от най -новите N елемента в закъснение (където N е броят на елементите във вашата средна стойност). Ако акумулаторът стартира като всяка друга стойност, изчислената средна стойност ще бъде грешна - или твърде ниска, или твърде висока, винаги с една и съща сума (приемайки същите първоначални условия). Предлагам ви да се опитате да научите защо това е така, като използвате "симулация на химикалка и хартия".

размер на акумулатора: Трябва също така да се отбележи, че акумулаторът трябва да бъде достатъчно голям, за да съхранява сумата от всички елементи в закъснение, ако всички те са положителни или отрицателни макс. На практика това означава, че акумулаторът трябва да бъде с един тип данни по -голям от елементите на закъснителната линия и подписан, ако са подписани елементи на закъснителната линия.

трик: Линиите с дълги забавяния заемат много памет. Това може бързо да се превърне в проблем. Ако сте много ограничени в паметта и не се интересувате много от точността, можете да приближите текущата средна стойност, като пропуснете изцяло забавянето и направите това вместо това: извадете 1/N * акумулатора от акумулатора и добавете нова стойност (например 8 дългосрочни средни стойности: акумулатор = акумулатор * 7/8 + newValue). Този метод дава грешен резултат, но е приличен метод за изчисляване на текущата средна стойност, когато имате малко памет.

лингвистика: "текуща средна/средна стойност" обикновено се използва, когато се отнася за осредняване в реално време, докато "плъзгаща средна/средна стойност" обикновено означава, че алгоритъмът работи върху статичен набор от данни, като например електронна таблица на Excel.

Стъпка 6: Заключение

Надявам се, че тази инструкция беше достатъчно лесна за разбиране и че ще ви помогне в бъдещите ви проекти. Моля, не се колебайте да публикувате въпроси в коментарите по -долу, ако има нещо неясно.

Препоръчано: