====== Управление звуком ======
===== Описание =====
В этом проекте мы будем управлять роботом с помощью звуков, например, хлопков. Количество хлопков в ладоши будет подсчитывать датчик звука, размещённый на роботе. Каждому количеству хлопков будет присвоена своя команда. Итак, это будут следующие команды:
  - (один) хлопок - остановиться
  - (два) хлопка - двигаться вперёд
  - (три) хлопка - двигаться назад
  - (четыре) хлопка - двигаться вправо
  - (пять) хлопков - двигаться влево

===== Дополнительные модули =====
Предполагается что у Вас уже есть набор "Смарт РОБО", и вы собрали его по инструкции в руководстве пользователя. Тогда дополнительно понадобится:

^ Что нужно                                                                                                               ^  Кол-во, шт  ^
| [[https://smartelements.ru/collection/datchiki-i-sensory/product/modul-datchika-zvuka|Датчик звука]] |  1           |
| [[https://smartelements.ru/collection/moduli/product/modul-adresnyh-svetodiodov-h4|Модуль адресных светодиодов]] |  2           |
| [[https://smartelements.ru/collection/aksessuary/product/komplekt-neylonovyh-krepleniy|Комплект нейлоновых креплений]] |  1           |
| [[https://smartelements.ru/collection/provoda-i-kabeli/product/shleyf-mama-mama-h3-20-sm|Шлейф "мама-мама" х3, 20 см]] |  1           |


===== Библиотеки =====
  * [[http://files.smartelements.ru/know_libs/robotSE.zip|Библиотека robotSE (для робота)]]
  * [[http://files.smartelements.ru/know_libs/Adafruit_NeoPixel.zip|Библиотека Adafruit_NeoPixel (для модуля светодиодов)]]
===== Порядок действий =====
==== Шаг 1. Пересоберите робота ====
  - С помощью отвёртки, входящей в комплект набора, снимите с платформы модуль ИК-приёмника
  - С помощью отвёртки, входящей в комплект набора, прикрепите на место модуля ИК-приёмника - [[https://smartelements.ru/collection/datchiki-i-sensory/product/modul-datchika-zvuka|Датчик звука]]
  - Присоедините датчик звука с помощью трёхпроводного шлейфа к аналоговому выводу А3 мотор шилда.
  - С помощью отвёртки, входящей в комплект набора, и нейлоновых креплений (одна гайка, один винт и одна стойка) прикрепите в свободное крайнее отверстие (справа от ИК-приёмника) [[https://smartelements.ru/collection/moduli/product/modul-adresnyh-svetodiodov-h4|Модуль адресных светодиодов]]
  - С помощью отвёртки, входящей в комплект набора, и нейлоновых креплений (одна гайка, один винт и одна стойка) прикрепите в свободное крайнее отверстие (слева от ИК-приёмника) [[https://smartelements.ru/collection/moduli/product/modul-adresnyh-svetodiodov-h4|Модуль адресных светодиодов]]
  - Присоедините один из модулей адресных светодиодов с помощью трёхпроводного шлейфа к выводам D11 мотор шилда (вывод модуля Din).
  - Соедините между собой модули адресных светодиодов трёхпроводным шлейфом (D out первого с D in второго).

{{ :main:upgkits:soundrobo.png?nolink |}}
==== Шаг 2. Количество хлопков ====
Для начала загрузите на контроллер скетч, который определяет количество хлопков и выводит значение на индикатор. 
Как правильно хлопать? 
Представим себе звук хлопка на упрощённом графике:
{{ ::soundgraph.png?nolink |}}

Рассмотрим по точкам:
  * На датчике мы всегда получаем информацию по окружающему шуму
  * В какой-то момент, начиная хлопок, уровень шума повышается (А - Б)
  * Далее, происходит сам хлопок, в этот момент уровень шума преодолевает критическую отметку (Б - В)
  * Затем происходит затухание шума

Следует заметить такую особенность: так как датчик фиксирует данные постоянно, то после момента преодоления порога шума (примерно 80 единиц), нам следует остановить приём датчиком значений в какое-то время (на графике это участок Б-В), чтобы не поймать "остаток" текущего хлопка. Будем примерно считать что это 150 мс.

Проверить как робот будет определять количество хлопков можно с помощью скетча:
<file Arduino>
#include <Adafruit_NeoPixel.h>    //Библиотека для работы со светодиодами

const int PIN_SOUND = A3;         //Вывод для подключения датчика звука
const int PIN_LED = 11;         //Вывод подключения адресных светодиодов

int clap_q = 0; //Переменная, хранящая количество хлопков
unsigned long time_long = 1000; //Время ожидания следующего хлопка

Adafruit_NeoPixel pixels(8, PIN_LED); //создание объекта адр. светодиодов

//Определение количества хлопков
void claps_quantity()
{
  int val = analogRead(PIN_SOUND); //чтение значения с датчика
  if (val > 80) //если значение больше 80
  {
    delay(150); //дать время для того чтобы звуковая волна погасла
    clap_q += 1; //прибавить количество хлоков
    unsigned long new_time = millis() + time_long; //зафиксировать время ожидания нового хлопка
    while (millis() < new_time) //пока идёт это время
    {
      claps_quantity(); //снова зайти в эту функцию
    }
  }
}

//зажечь столько светодиодов, сколько определено хлопков
void light()
{
  if (clap_q > 0)
  {
    for (int i = 0; i < clap_q; i++)
    {
      pixels.setPixelColor(i, pixels.Color(0, 255, 0)); //установка цвета свечения для очередного светодиода
      pixels.show();                                    //показать цвет светодиода
      delay(100);
    }

    delay(400);
    pixels.clear();
    pixels.show();
  }
}

void setup()
{
  pixels.begin();               //инициализация светодиодов
}

void loop()
{
  clap_q = 0;               //Сброс количества хлопков
  claps_quantity();         //Подсчёт количества хлопков

  light(); //вывод количества хлопков
}
</file>

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

==== Шаг 3. Установите библиотеки ====
Установите в Arduino IDE библиотеки, которые представлены по ссылкам выше (в подпункте «Библиотеки»). О том как устанавливаются библиотеки описано в руководстве пользователя, входящем в комплект, либо посетите соответствующий [[main:info:libs|раздел Базы Знаний]].


==== Шаг 4. Загрузите скетч на контроллер ====
Теперь добавим в скетч функции, отвечающие за движение робота. 

<file Arduino>
#include <robotSE.h>            //Подключение библиотеки для работы с платформой.
#include <Adafruit_NeoPixel.h>    //Библиотека для работы со светодиодами

const int PIN_SOUND = A3;         //Вывод для подключения датчика звука
const int PIN_LED = 11;         //Вывод подключения адресных светодиодов

int clap_q = 0; //Переменная, хранящая количество хлопков
unsigned long time_long = 1000; //Время ожидания следующего хлопка

robotSE robot; //Создание объекта робота

Adafruit_NeoPixel pixels(8, PIN_LED); //создание объекта адр. светодиодов

//Определение количества хлопков
void claps_quantity()
{
  int val = analogRead(PIN_SOUND); //чтение значения с датчика
  if (val > 80) //если значение больше 80
  {
    delay(150); //дать время для того чтобы звуковая волна погасла
    clap_q += 1; //прибавить количество хлоков
    unsigned long new_time = millis() + time_long; //зафиксировать время ожидания нового хлопка
    while (millis() < new_time) //пока идёт это время
    {
      claps_quantity(); //снова зайти в эту функцию
    }
  }
}

//зажечь столько светодиодов, сколько определено хлопков
void light()
{
  if (clap_q > 0)
  {
    for (int i = 0; i < clap_q; i++)
    {
      pixels.setPixelColor(i, pixels.Color(0, 255, 0)); //установка цвета свечения для очередного светодиода
      pixels.show();                                    //показать цвет светодиода
      delay(100);
    }

    delay(400);
    pixels.clear();
    pixels.show();
  }
}

void setup()
{
  pixels.begin();               //инициализация светодиодов
}

void loop()
{
  clap_q = 0;               //Сброс количества хлопков
  claps_quantity();         //Подсчёт количества хлопков

  light();                  //Вывод количества хлопков

  if (clap_q == 1) {        //Если был один хлопок
    robot.move_stop();      //Остановка робота
  } else if (clap_q == 2) { //Если было два хлопка
    robot.move_forward();   //Двигаться вперёд
  } else if (clap_q == 3) { //Если было три хлопка
    robot.move_back();      //Двигаться назад
  } else if (clap_q == 4) { //Если было четыре хлопка
    robot.move_right();     //Двигаться вправо
  } else if (clap_q == 5) { //Если было пять хлопков
    robot.move_left();      //Двигаться влево
  }
}
</file>

==== Шаг 5. Результат ====
Управляйте роботом с помощью хлопков. В зависимости от полученной команды (количества хлопков) робот будет двигаться в определённом направлении.