Працюємо з 09:00 до 20:00 без вихідних.
Самовивіз не працює до 10.09.2017

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

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


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

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

Наступна програма для контролера 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 размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Мікроконтролер ATTINY13A

Мікроконтролер ATTINY13A

Мініатюрний економічний AVR 8-бітний мікроконтролер, який можна програмувати як програматором, так і..

19.41грн.

Універсальна плата під мікросхеми SOP8, SSOP8

Універсальна плата під мікросхеми SOP8, SSOP8

Універсальна монтажна плата, дозволяє проводити монтаж різноманітних мікросхем з поверхневим монтаже..

3.89грн.

Символьний індикатор LCD 2004

Символьний індикатор LCD 2004

Чотирьохрядковий символьний рідкокристалічний індикатор з блакитною підсвіткою LCD2004.Напруга живле..

137.81грн.

Модуль Bluetooth HC 06

Модуль Bluetooth HC 06

Зв'язок з контролером через UART портЗкеровується АТ-командамиЗа замовчанням швидкість обміну 9600 б..

111.78грн.

Міні кнопка SMD 6 x 6 x 5 мм

Міні кнопка SMD 6 x 6 x 5 мм

Мініатюрна кнопка з SMD виводамиРозміри 6 x 6 x 5 мм..

0.64грн.