Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Датчик звука

Скетчи с хлопками

Sound Sensor

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

Sound Sensor

Подстройка производится экспериментальным путём. Крутите отвёрткой в нужную сторону, пока не добьётесь желаемого результата.

Подключение очень простое - у модуля три вывода: питание 5В, земля и цифровой вывод.

Скетч для модуля.


int soundPin = 10;
int soundVal = HIGH;
boolean alarm = false;

unsigned long lastSoundDetectTime;

int soundAlarmTime = 500; // промежуток времени в миллисекундах

void setup ()
{
  Serial.begin(9600);
  pinMode(soundPin, INPUT);
}

void loop ()
{
  soundVal = digitalRead(soundPin) ; // считываем показания с вывода 10

  if (soundVal == LOW) // если появился звук
  {
    lastSoundDetectTime = millis(); // запоминаем время появления звука
    if (!alarm) {
      Serial.println("Alarm! Alarm!");
      alarm = true;
    }
  }
  else
  {
    if ((millis() - lastSoundDetectTime) > soundAlarmTime  &&  alarm) {
      Serial.println("Quiet");
      alarm = false;
    }
  }
}

Запустите скетч, откройте Serial Monitor и начинайте говорить. При обнаружении звука на экране появится надпись "Alarm! Alarm!". Данный скетч можно применять для определения ночного тыгыдыка кота в квартире. В реальной жизни чувствительность датчика желает лучшего, на хлопок реагирует, а на голос практически нет.

Модули с цифровым и аналоговым выводами

Также можно встретить модули, у которых четыре вывода: питание, земля, цифровой и аналоговый выводы. К ним относятся модели KY-030 (устар.), KY-037 (микрофон с высокой чувствительностью), KY-038 (конденсаторный микрофон).

KY-037

Подключение у модулей одинаковое.


KY-037 | Arduino 
----------------
    AO | A
   GND | GND
     + | 5V 
    DO | D

На модуле датчика должен загореться индикатор питания L1. Необходимо сначала подкрутить подстроечный резистор, настроив чувствительность датчика. В настройке чувствительности поможет индикатор L2. Если индикатор L2 при включении модуля тоже загорается, крутим подстроечный резистор против часовой стрелки до тех пор, пока не дойдём до момента затухания индикатора. Если же индикатор L2 находится в выключенном состоянии при включении модуля, значит крутим подстроечный резистор по часовой стрелке, пока не дойдём до момента, когда индикатор начнёт загораться. В итоге, нужно поймать момент, где чуть повернув подстроечный резистор в одну или другую сторону, индикатор стремиться потухнуть или загореться, и затем нужно повернуть совсем немного против часовой стрелки, чтобы индикатор L2 потух, но при хлопках в ладоши пытался загораться.

Скетч для цифрового вывода смотри выше. Для аналогового вывода напишите самостоятельно.

Включить по хлопку и выключить через несколько секунд

Напишем скетч, в котором будем включать свет по хлопку и выключать через определённое время.


const int sensorD0 = 4;  // пин для выхода D0 датчика
const int led = 13; // пин светодиода

void setup ()
{
  pinMode(led, OUTPUT); // устанавливаем цифровой пин 2 в режим выхода
}

void loop ()
{
  int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика
  if (sensorValue == 1) //если получен сигнал от датчика в виде единицы
  {
    digitalWrite(led, HIGH); // включаем светодиод
    delay(5000); // делаем паузу, чтобы светодиод горел 5 секунд
  }
  if (sensorValue == 0) // если приходит сигнал от датчика в виде нуля
    digitalWrite(led, LOW); // выключаем светодиод
}

Включить и выключать поочерёдно по хлопку

Напишем новый скетч с другой логикой - по первому хлопку включить светодиод, по повторному хлопку светодиод выключим.


const int sensorD0 = 4;  // пин для выхода D0 датчика
const int led = 13; // пин светодиода
int ledState = LOW; // статус светодиода "выключен"

void setup ()
{
  pinMode(led, OUTPUT);
}

void loop ()
{
  int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика

  if (sensorValue == 1 && ledState == LOW) //если порог громкости достигнут и светодиод был выключен
  {
    digitalWrite(led, HIGH); // включаем светодиод
    ledState = HIGH; // устанавливаем статус светодиода "включен"
    delay(100); // небольшая задержка для фильтрации помех
  }
  else {
    if (sensorValue == 1 && ledState == HIGH) // если порог громкости достигнут и светодиод был включен
    {
      digitalWrite(led, LOW); // выключаем светодиод
      ledState = LOW; // устанавливаем статус светодиода "выключен"
      delay(100); // небольшая задержка для фильтрации помех
    }
  }
}

Включаем светодиод по двойному хлопку

Следующий скетч поможет избежать случайных срабатываний, будем отслеживать парные хлопки - аналог двойного щелчка мыши.


const int sensorD0 = 4;  // пин для выхода D0 датчика
const int led = 13; // пин светодиода
int ledState = LOW; // статус светодиода "выключен"
long soundTime = 0; // время первого хлопка

void setup ()
{
  pinMode(led, OUTPUT);
}

void loop ()
{
  int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика

  if (sensorValue == 1 && ledState == LOW) //если порог громкости достигнут и светодиод был выключен
  {
    long curTime = millis(); // запоминаем текущее время

    // если текущее время хлопка больше времени последнего хлопка на 100 миллисекунд
    // и хлопок произошел не позже чем через 1000 миллисекунд после предыдущего
    // считаем такой хлопок повторным и реагируем на него
    if ((millis() > soundTime) && ((curTime - soundTime) > 100) && ((curTime - soundTime) < 1000))
    {
      digitalWrite(led, HIGH); // включаем светодиод
      ledState = HIGH; // устанавливаем статус светодиода "включен"
      delay(100); // небольшая задержка для фильтрации помех
    }
    soundTime = millis(); //записываем время последнего хлопка
  }
  else // иначе
  {
    if (sensorValue == 1 && ledState == HIGH) // если порог громкости достигнут и светодиод был включен
    {
      digitalWrite(led, LOW); // выключаем светодиод
      ledState = LOW; // устанавливаем статус светодиода "выключен"
      delay(100); // небольшая задержка для фильтрации помех
    }
  }
}
Реклама