Датчик звука, последовательное зажигание светодиодов.
- Войдите на сайт для отправки комментариев
Ср, 26/09/2018 - 22:39
Всем привет. Имеется задача следующего характера. Есть arduino Nano, датчик звука
также есть 12 светодидов. Человек кричит в микрофон, если кричит на протяжении 2 секунд = загорается первый светодиод, если 4 секунды = загорается 2 светодиод. К 24 секунде должны загореться все 12 светодиодов. Пробовал и так и эдак, и через analogRead() и через прерывание. Пока получается зажечь криком только один светодиод, но не знаю:
1. как заставить гореть этот светодиод
2. как отсчитать время сигнала (что уже прошло 2 секунды)
Из того, что пока получилось набрать:
volatile byte count; void setup() { Serial.begin(9600); pinMode(3, INPUT); // выход OUT pinMode(12, OUTPUT); // внешний светодиод attachInterrupt(1, myInterrupt, FALLING); } void loop() { Serial.println(count); digitalWrite(12,0); delay(500); } void myInterrupt() { digitalWrite(12,1); count++; }
Заранее всем спасибо. Надеюсь на ваши подсказки.
millis() знаете?
Читал у вас в справочнике. Если Вас не затруднит пример можете привести как я его могу задействовать?
Читал у вас в справочнике. Если Вас не затруднит пример можете привести как я его могу задействовать?
да все просто.
0. сначала у вас сигнала нет и переменная флаг =0
1. Читаете значение с микрофона.
2. Если есть сигнал и флаг ==0, то выставляем флаг =1 и запоминаем миллис
3. Если есть сигнал и флаг ==1 - берем разницу текущего миллис и запомненного в п.2, в зависмости от прошедшего времени зажигаем нужное число диодов
4. если сигнала нет, то флаг =0
5 GOTO 1
Еще проще, но не без нюансов:
1. Ждем сигнала с микрофона
2. Ждем 2 секунды и читаем микрофон
3. Если сигнал есть - включаем 1 светодиод, нет - идем на п.1.
4. Ждем 2 секунды... и т.д.
Еще проще, но не без нюансов:
1. Ждем сигнала с микрофона
2. Ждем 2 секунды и читаем микрофон
3. Если сигнал есть - включаем 1 светодиод, нет - идем на п.1.
4. Ждем 2 секунды... и т.д.
Если "ждем" - это dalay(), то решение явно неуниверсальное, а в противном случае - идейно не отличается от предыцдущего поста с чтением millis и выставлением флагов, но только более громоздкое и немасштабируемое.
Попробовал набросать код (следуя вашим советам) и получилось следующее.
Все равно до конца не могу понять как отследить сигнал точнее.
Для чтения сигнала я использую функцию micr = analogRead(A5);
Которая (если смотреть по монитору порта), выдаёт цифровые значения. При тишине 1023, в случае крика значение проседает в районе 32-41. НО даже если я кричу в микрофон (например "ААААА"), то значение 32 не постоянно и плавает туда-сюда..
Попробовал набросать код (следуя вашим советам) и получилось следующее.
Неправильно.
Вы не разобрались в логике алгоритма. что я давал в сообщении #4. Обратите внимание, что там переменная флаг проверяется на втором и третьем шаге, а в вашем коде переменная micr_flag совершенно бесполезна - вы нигде не проверяете ее значение.
Пробуйте еще
А как лучше проверять наличие сигнала? Путём чтения функцией (analogRead) в цикле loop или использование прерывания?
А как лучше проверять наличие сигнала? Путём чтения функцией (analogRead) в цикле loop или использование прерывания?
зачем тут прерывание? У вас весь код на 20 строк и совершенно не требует быстрой реакции. Вы для начала разберитесь с простейшей логикой, чтобы код работал правильно - а потом, если захотите, можете и прерывание подтянуть.
Да ну вас, тут разговоров не о чем - сначала простую программу написать, а затем украшательства, millis и т.д..
Делайте по частям.
Часть первая - засечь повышенный уровень громкости и засечь начало цикла, сохранив значение millis() в переменной. Применяйте переменную-защелку (флаг), чтобы засечь только один раз.
Часть вторая - засечь "тишину", сохранив значение millis() в переменную конца цикла. Вывести разницу между началом цикла и его концом один раз. Снова примените переменную-защелку (вторую).
Да ну вас, тут разговоров не о чем - сначала простую программу написать, а затем украшательства, millis и т.д..
Только наверное analogRead(A5)<1000, потому что всё что ВЫШЕ 1000 это тишина.
И ещё такой момент, как я уже говорил выше, даже если ты постоянно кричишь (или дуешь в микрофон) получаемое функцией analogRead - значение не постоянно, и плавает от минимума (31) к максимуму (1023). Хотя микрофон настроен на максимальную чувствительность (светодиод микрофона чуть подсвечивает даже в тишине).
Код немного доработал, теперь получается поддерживать постоянно включенным первый светодиод, через 2 секунды загорается второй. Но только из-за того, что получаемые значения бегают, иногда срабатывает else, ктр гасит светодиод и который затем сразу же включается..
Код немного доработал, теперь получается поддерживать постоянно включенным первый светодиод, через 2 секунды загорается второй. Но только из-за того, что получаемые значения бегают, иногда срабатывает else, ктр гасит светодиод и который затем сразу же включается..
Вот так вам более понятно?
У меня такой же датчик звука, только плата синего цвета. Он хорошо работает. На выходе у него сигнал низкого уровня (0) когда говоришь громко и высокого уровня (1) когда тишина. Чуствительность на громкость звука регулируется переменным резистором (синий такой кубик на плате). Настроить желаемую можно подав питание на датчик, вращая резистор, подавая звуки и глядя на сигнальный светодиод. И это без Ардуино. Вообще датчик имеет только два состояния по выходу.
Скорее всего у тебя цифровой, а у меня аналоговый.
Скорее всего у тебя цифровой, а у меня аналоговый.
А где такой купил? Дай ссылку, посмотреть. А то с аналоговым тоже хочется попробовать.
Скорее всего у тебя цифровой, а у меня аналоговый.
А где такой купил? Дай ссылку, посмотреть. А то с аналоговым тоже хочется попробовать.
Покупал не я, одолжил у товарища. Боюсь здесь нельзя кидать ссылку (посчитают за рекламу), поищи на али, думаю без проблем найдешь.
Тут пожалуй забыли про частоту, сколько может выдать наша глотка? ;) необходимо поставить на входе R/C цепочку, тогда уровень сигнала после апроксимации будет более стабильнее. Но это как вариант, второй - вариант - постоянно контролировать АЦП (ну к примеру) если уровень (max) появляется каждые ХХ мСек. вот тогда и держим в true переменную(булеан).
Тут пожалуй забыли про частоту, сколько может выдать наша глотка? ;) необходимо поставить на входе R/C цепочку, тогда уровень сигнала после апроксимации будет более стабильнее. Но это как вариант, второй - вариант - постоянно контролировать АЦП (ну к примеру) если уровень (max) появляется каждые ХХ мСек. вот тогда и держим в true переменную(булеан).
Это которая интегрирующая ?
Осталось только рассчитать номиналы деталек..
Осталось только рассчитать номиналы деталек..
Если никто не снял про это мультик, тогда бида!, бида!
также есть 12 светодидов. Человек кричит в микрофон, если кричит на протяжении 2 секунд = загорается первый светодиод, если 4 секунды = загорается 2 светодиод. К 24 секунде должны загореться все 12 светодиодов. Пробовал и так и эдак, и через analogRead() и через прерывание. Пока получается зажечь криком только один светодиод ..
Никто так и не обратил внимание, подскажу: Автор, ты ДВАДЦАТЬ ЧЕТЫРЕ секунды пробовал кричать в микрофон НЕПРЕРЫВНО? :)
Посидел за кодом, повникал. Спасибо ребятам за дельные советы. В итоге получился код следующего содержания:
Надо будет ещё оптимизировать (особенно с перечислением портов), а так в целом поставленную задачу решает.