Працюємо з 09:00 до 19:00 без вихідних.
Самовивіз - Київ біля ТЦ Квадрат бул.Перова

Шум аналогового входу

Будь-який аналоговий датчик, з'єднувальні дроти, та і сам аналоговий вхід контролера вносять у результуюче виміряне значення безліч шумів. Вони заважають нам отримати реальне значення параметру з повторюваною точністю.


Підключивши датчик до контролера, побачимо постійно стрибаюче значення фізичної величини. Якщо нам потрібно керувати яким-небуть виконавчим механізмом в залежності від величини такого стрибаючого значення, то механізм може вести себе доволі неадекватно. Так що будь-який аналоговий сигнал рекомендується згладжувати за допомогою програмного фільтру.

Давайте розглянемо два цікавих способи програмної фільтрації цих шумів. 

Наступна програма для контролера Arduino зчитує аналоговий вхід та виводить у монітор порта нефільтроване значення, та два значення відфільтровані двома різними способами.

int sensorPin = A0; // номер аналогового входу

// функція зчитує аналоговий вхід задану кількість разів
// та повертає відфільтроване значення
int readMean(int pin, int samples){
// змінна для зберігання суми зчитаних значень
int sum = 0;
// читання та додавання значень
for (int i = 0; i < samples; i++){
sum = sum + analogRead(pin);
}
// ділимо суму значень на кількість вимірів
sum = sum/samples;
// повертаємо середнє значення
return sum;
}
// функція зчитує аналоговий вхід задану кількість разів
// та повертає медіанне відфільтроване значення
int readMedian (int pin, int samples){
// масив для зберігання даних
int raw[samples];
// зчитуємо вхід та вкладаємо величину в комірки масиву
for (int i = 0; i < samples; i++){
raw[i] = analogRead(pin);
}
// сортуємо масив за збільшенням значень в комірках
int temp = 0; // тимчасова змінна
for (int i = 0; i < samples; i++){
for (int j = i; j < samples - 1; j++){
if (raw[j] > raw[j + 1]){
temp = raw[j];
raw[j] = raw[j + 1];
raw[j + 1] = temp;
}
}
}
// повертаємо значення середньої комірки масиву
return raw[samples/2];
}
void setup(){
Serial.begin(9600);
}
void loop(){
// виводимо значення на аналоговому вході в монітор порта
Serial.print(analogRead(sensorPin));
Serial.print(" ");
// виводимо середньовиміряне значення
Serial.print(readMean(sensorPin, 15));
Serial.print(" ");
// виводимо медіанне відфільтроване значення
Serial.println(readMedian(sensorPin, 15));
delay(100);
}

Винайдено безліч програмних фільтрів, але ми тут розглядаємо два самих використовуваних типи: фільтр за середнім значенням та медіанний фільтр.

Перший - фільтр за середнім значенням

Даний алгоритм збирає декілька значень та вираховує за ними середнє значення. Він доволі добре прибирає шум, але потребує великих витрат часу циклу від контролера. Із-за того, що необхідно зробити декілька вибірок сигналу з аналогового входу. Таким чином збільшується час відповіді під час опитування вхідного значення головною програмою. Але повільне отримання значення краще ніж стрибаюче значення.

1) Оголошуємо функцію з двома параметрами: перший містить номер аналогового входу Arduino, куди підключено датчик; а другий задає кількість вибірок.

2) Далі ми циклічно зчитуємо значення аналогового входу та кожний раз додаємо його до змінної sum
int sum = 0;
for (int i = 0; i < samples; i++){
sum = sum + analogRead(pin);
}

3) Далі знаходимо середнє значення. Суму усіх значень вибірок ділимо на кількість вибірок
sum = sum/samples;

Другий фільтр - медіанний

Алгоритм цього програмного фільтру дещо складніший, але дієвіший. Він не робить математичних перерахунків над вибірками. Фільтр заснований на припущенні, що викиди складових шуму розташовані рівномірно як у позитивний бік так і в негативний по відношенню до реального значення. Цей алгоритм зчитує ряд значень з аналогового входу контролера Arduino, сортує їх за збільшенням та вибирає значення, що стоїть у центрі отриманого переліку. В загальному випадку, якщо викиди шуму розташовані рівномірно з двох сторін від реального значення, то отримаємо точну величину.

1) Оголошуємо функцію медіанного фільтру, що приймає номер аналогового входу та кількість вибірок
int readMedian (int pin, int samples){
2) Далі оголошуємо масив для зберігання даних та у циклі заповнюємо цей масив зчитуваними з аналогового входу даними
int raw[samples];
for (int i = 0; i < samples; i++){
raw[i] = analogRead(pin);
}

Далі алгоритм виконує сортування масиву за значенням. Для цього використовується так званий пухирцевий алгоритм. Він розташує комірки масиву по порядку від менших значень до більших.

Та у кінці функції повертаємо значення середньої комірки відсортованого масиву.

return raw[samples/2];

Головний цикл програми

В головному циклі програми ми просто циклічно виводимо отримані дані у монітор порта, щоб прослідкувати за змінами вимірюваного параметру у часі. В один рядок програма повинна виводити нефільтроване значення та два фільтрованих різними алгоритмами значення. Таким чином ми зможемо оцінити якість фільтрації різними способами.

В коді програми задано зчитування 15 вибірок, але ви можете поекспериментувати і з іншою кількістю, спостерігаючи за зміною якості фільтрації сигналу.

Serial.print(analogRead(sensorPin));
Serial.print(" ");
Serial.print(readMean(sensorPin, 15));
Serial.print(" ");
Serial.println(readMedian(sensorPin, 15));
delay(100);

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Модуль Bluetooth HC 05

Модуль Bluetooth HC 05

Стандарт bluetooth V2.0 Працює в режимі майстер та підлеглий (налаштовується АТ-командами)Напру..

152.99грн.

Цифровий датчик температури DS18B20

Цифровий датчик температури DS18B20

Напруга живлення 3 ... 5,5 ВРобоча температура -55 ... +125 °CТочність ±0,5 °C забезп..

23.32грн.

Задатчик струму 4 20мА.

Задатчик струму 4 20мА.

Прилад дозволяє отримувати на виході 0...20 мА, 4...20 мА.Галузі застосування представленого пристро..

Роз'ємний конектор JST

Роз'ємний конектор JST

Слугує для швидкороз'эмного з'єднання. Наприклад, для монтажу датчиків, виконавчих механізмів, підве..

7.94грн.

Ковпачок на змінний резистор 24мм під 6мм

Ковпачок на змінний резистор 24мм під 6мм

Пластиковий ковпачок з максимальним діаметром 24 ммМонтажний отвір під зустрічний діаметр 6 ммВисота..

18.70грн.