Изглаждане на данни с EMA филтър на ESP32 с MicroPython

ESP32 MicroPython EMA filter

Въведение

В света на вградени системи и сензори, получаването на стабилни и надеждни данни е от съществено значение. Често данните, които се събират от аналогово-цифрови преобразуватели (АЦП), са шумни и съдържат нежелани колебания. Един от ефективните методи за изглаждане на тези данни е използването на Exponential Moving Average (EMA) филтър. В тази статия ще разгледаме как да приложим EMA филтър с помощта на MicroPython на ESP32, като създадем библиотека, която можем да използваме във вашите проекти.

Какво е EMA филтър?

Exponential Moving Average или на кратко (EMA) е тип филтър, който придава по-голяма тежест на последните наблюдения, което го прави по-чувствителен към нови данни. Формулата за EMA е следната:

EMAt​=α×Pt​+(1−α)×EMAt−1​

Където:

  • EMAt​ е текущата стойност на EMA.
  • α (alphaα) е изглаждащият фактор, който определя колко тежест се дава на новите данни (обикновено между 0 и 1).
  • Pt​ е текущата измерена стойност.
  • EMAt−1​ е предишната стойност на EMA.

Защо да използваме EMA филтър?

  1. Изглаждане на данни: EMA филтърът помага да се изгладят шумните данни, като намалява ефекта от краткосрочните колебания.
  2. Реактивност: Поради своята природа, EMA филтърът е по-реактивен към последните промени, което го прави полезен за приложения, които изискват бърза реакция.
  3. Лесно имплементиране: Формулата на EMA е проста и лесна за реализиране в микроконтролери.

Създаване на библиотека за EMA филтър в MicroPython

Създаване на EMA филтър библиотека

След, когато ESP32 е готов за работа, ще създадем библиотека за EMA филтъра. Създайте файл с име ema_filter.py и добавете следния код:

from machine import ADC, Pin
import time

class EMAFilter:
    def __init__(self, pin, alpha=0.2, num_samples=100):
        self.adc = ADC(Pin(pin))
        self.adc.atten(ADC.ATTN_11DB)
        self.adc.width(ADC.WIDTH_12BIT)
        self.alpha = alpha
        self.num_samples = num_samples
        self.ema = 0
        self.first_reading = True

    def read_adc(self):
        total = 0
        for _ in range(self.num_samples):
            total += self.adc.read()
            time.sleep(0.001)  # Малко забавяне между прочитанията (1 ms)
        return total / self.num_samples

    def update_ema(self):
        current_reading = self.read_adc()
        if self.first_reading:
            self.ema = current_reading
            self.first_reading = False
        else:
            self.ema = self.alpha * current_reading + (1 - self.alpha) * self.ema
        return self.ema

Стъпка 3: Използване на библиотеката в основния скрипт

За да използваме библиотеката в нашия основен скрипт, можем да създадем нов файл, например main.py, и да импортираме класа EMAFilter:

from ema_filter import EMAFilter
import time

pin = 1  # Задаване на аналогов пин за изчитане
alpha = 0.1  # Избрана стойност за alpha
num_samples = 100	# Брой изчитания на аналоговия вход

filter = EMAFilter(pin, alpha, num_samples)

while True:
    ema_value = filter.update_ema()
    #print('EMA Value:', round(ema_value,2))
    print(round(ema_value,2))
    time.sleep(0.1)  # Забавяне за следващото четене

Обяснение на кода

  1. from ema_filter import EMAFilter : импортиране на класа EMAFilter от файла ema_filter.py
  2. time : импортиране на библиотеката “time”, която се използва за добавяне на забавяне между четенията на аналоговия вход.
  3. pin : задава аналоговия пин, който ще се използва за изчитане на стойности от АЦП/ADC (аналогово-цифров преобразувател).
  4. alpha : задава стойността на изглаждащия фактор за EMA (Exponential Moving Average). Тази стойност определя колко тежест се дава на новите данни в сравнение със старите данни. Ако не зададете тази стойност по дефиниция в библиотеката е заложена стойността 0.2.
  5. num_samples : задава броя на изчитанията, които ще се използват за осредняване на аналоговата стойност преди прилагане на EMA филтъра.
  6. filter = EMAFilter(pin, alpha, num_samples) : Този ред създава инстанция на класа EMAFilter с зададените параметри pin, alpha и num_samples.
  7. ema_value = filter.update_ema() : актуализира и връща новата стойност на EMA чрез метода update_ema на класа EMAFilter. Този метод първо чете и осреднява num_samples на брой изчитания от АЦП, след което изчислява новата стойност на EMA на базата на текущата осреднена стойност и предишната стойност на EMA.
  8. print(round(ema_value, 2)) : извежда стойността на EMA, закръглена до две десетични места.
  9. time.sleep(0.1) : добавя забавяне от 0.1 секунди преди следващото изчитане, за да намали честотата на четене и обработка на данни.

Това е пример за изчитане на няколко аналогови пина с тази билиотека:

from ema_filter import EMAFilter
import time

# Задаване на аналогови пинове
pin1 = 1  # Задаване според вашата ESP32 платформа
pin2 = 0  # Задаване според вашата ESP32 платформа
pin3 = 3  # Задаване според вашата ESP32 платформа

# Избрана стойност за alpha и брой изчитания на аналоговия вход
alpha = 0.1  # ако не бъде зададена стойността и ще е 0.2
num_samples = 100

# Създаване на EMA филтри за всеки пин
filter1 = EMAFilter(pin1, alpha, num_samples)
filter2 = EMAFilter(pin2, alpha, num_samples)
filter3 = EMAFilter(pin3, alpha, num_samples)

while True:
    # Актуализиране на EMA стойности за всеки пин
    ema_value1 = filter1.update_ema()
    ema_value2 = filter2.update_ema()
    ema_value3 = filter3.update_ema()

    # Отпечатване на стойностите
    print("EMA Value 1:", round(ema_value1, 2))
    print("EMA Value 2:", round(ema_value2, 2))
    print("EMA Value 3:", round(ema_value3, 2))

    # Забавяне за следващото четене
    time.sleep(0.1)

За да зададете правилните аналогови входове може да разгледате раздела ни Ревюта, където ще намерите спецификациите на някои ESP32 платформи.

Заключение

Използването на EMA филтър с MicroPython на ESP32 е ефективен начин за изглаждане на данните от сензори и намаляване на шума. Създадената библиотека е лесна за използване и може да бъде интегрирана във вашите проекти за вградени системи. Независимо дали работите с температурни сензори, светлинни датчици или други аналогови устройства, EMA филтърът може да ви помогне да получите по-надеждни и стабилни данни. Може да прочетете повече за този математичен модел тук.

Надявам се тази статия да ви е помогнала да разберете как да използвате EMA филтър с MicroPython и ESP32. Ако имате въпроси или нужда от допълнителна помощ, не се колебайте да се свържете с мен!