Проект 3. Детектор шума

Устройство считывает уровень шума и показывает график изменения звука.

Описание работы:

Для начала работы подключите питание к Arduino. На дисплее будет показываться график уровня звука, который изменяется слева направо. Так же появляется риска, которая может двигаться сверху вниз. Изменение положения риски зависит от потенциометра. Изменение значение потенциометра регулирует предельное значение уровня звука. При увеличении значения потенциометра, риска будет двигать вверх, при уменьшении - вниз. Если уровень шума окружающей среды больше заданного предельного значения на потенциометре, то загорится светодиод.

Нам понадобится:

Для реализации проекта нам необходимо установить следующую библиотеку:

О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.

Схема сборки:

  • Устанавливаем в 6 посадочную площадку.

  • Полученные результат представлен ниже на рисунке.

Код программы:

#include <iarduino_OLED.h>                                       // Подключаем библиотеку iarduino_OLED.
iarduino_OLED myOLED(0x3C);                                      // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x3C.
                                                                 //
int pinDatS = A3;                                                // Объявляем пин для работы с датчиком звука.
int pinLedRed = 11;                                              // Объявляем пин для работы с красным светодиодом.
int pinPot = A0;                                                 // Объявляем пин для работы с потенциометром.
                                                                 //
float mass[44];                                                  // Массив для хранения полученных данных с датчика звука.
const float average = 2;                                         // Переменная усреднения показаний датчика (чем выше значение, тем выше инерционность выводимых показаний).
int potValue;                                                    // Переменная для считывания показания потенциометра.
int potValuePrev;                                                // Переменная для сохранения предыдущего значения потенциометра.
                                                                 //
float readDatS;                                                  //
void setup()                                                     //
{                                                                //
  myOLED.begin();                                                // Инициируем работу с дисплеем.
  myOLED.autoUpdate(false);                                      // Запрещаем автоматический вывод данных. Информация на дисплее будет обновляться только после обращения к функции update().
  pinMode(pinLedRed, OUTPUT);                                    // Переводим вывод pinLedRed в режим выхода.
}                                                                //
                                                                 //
void loop()                                                      //
{                                                                //
  for (int i = 0; i <= 130; i = i + 3)                           // Цикл для стирания графика с предыдущими элементами массива.
  {                                                              //
    myOLED.drawLine(i, 64-mass[i/3], i+3, 64-mass[(i+3)/3], 0);  // Стираем график.
  }                                                              //
                                                                 //
  readDatS =  map(analogRead(pinDatS), 0, 1023, 0, 64);          // Считаем показания датчика.
                                                                 //  
  int Prev = mass[0];                                            // Дополнительная переменная для переноса массива, присваиваем ей значение первого элемента массива.
  int Prev2;                                                     // Вторая дополнительные переменные для переноса массива.
  // Формула аппроксимации.                                      //
  mass[0] *= average-1;                                          // Умножаем предыдущее значение датчика звука на коэффициент усреднения-1.
  mass[0] += readDatS;                                           // Добавляем к полученному значению новые показания датчика звука.
  mass[0] /= average;                                            // Делим полученное значение на коэффициент усреднения.
                                                                 //
  for (int i = 1; i <= 43; i++)                                  // Переносим каждый элемент массива по очереди с помощью цикла.
  {                                                              //
    Prev2 = mass[i];                                             // Присваиваем второй дополнительное переменной новый элемент массива.
    mass[i] = Prev;                                              // Присваиваем новому элементу массива предыдущий элемента массива.
    Prev = Prev2;                                                // Присваиваем дополнительным переменным вторую дополнительную переменную.
  }                                                              //
                                                                 //
  for (int i = 0; i <= 130; i = i + 3)                           // Цикл для выведения на дисплей график.
  {                                                              //
    myOLED.drawLine(i, 64-mass[i/3], i+3, 64-mass[(i+3)/3],1);   // Выводим на дисплей график
  }                                                              //
                                                                 //
  potValue = analogRead(pinPot)/16;                              // Считываем показания потенциометра и делим на 16.
  if (potValuePrev != potValue)                                  // Если не равны предыдущее и полученное значение потенциометра, то произошло изменение.
  {                                                              //
    myOLED.drawLine(0, potValuePrev, 130, potValuePrev,0);       // Стираем на дисплее уровень в виде линии.
    potValuePrev = potValue;                                     // Сохраняем полученное значение с датчика звука в предыдущую переменную. 
  }                                                              //
  myOLED.drawLine (0, potValue, 130, potValue,1);                // Выводим на дисплей уровень в виде линии.
                                                                 //
  if (mass[0] > 64 - potValue){digitalWrite(pinLedRed, HIGH);}   // Если значения датчика звука больше потенциометра, то зажигаем светодиод.
  else {digitalWrite(pinLedRed, LOW);}                           // Если меньше, то гасим светодиод.
                                                                 //
  myOLED.update();                                               // Разрешаем автоматический вывод данных.
}                                                                //

Алгоритм работы:

В начале скетча (до кода setup) выполняются следующие действия:

В коде setup выполняются следующие действия:

  • Инициируем работу с дисплеем. Запрещаем автоматический вывод данных.
  • Переводим вывод Arduino для светодиода в режим выхода.

В коде loop выполняются следующие действия:

  • Стираем график звука.
  • Считываем показания датчика и аппроксимируем полученные значения по формуле.
  • Сдвигаем массив данных.
  • Отрисовываем новый график.
  • Проверяем изменилось положение риски, если изменилось, то выводим риску на дисплей, стираем предыдущее положение риски.
  • Проверяем превышает уровень звука на датчики предельный уровень потенциометра . Если превышает, то горит светодиод.

Особенность:

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

Ссылки:

Обсуждение