Поворотный и наклонный кронштейны перемещаются на звук, управляют серводвигателями с помощью микрофонных звуковых датчиков
Я пытаюсь запрограммировать поворотно-наклонный кронштейн на поворот в зависимости от того, где я говорю, я знаю, как перемещать серводвигатели, но мне действительно нужна помощь с распознаванием звука. Вот код, который у меня есть в настоящее время:
#include <Servo.h>
Servo myservo; // создать сервообъект для управления сервоприводом
Servo myservo2; // в sound1 может быть создано не более восьми сервообъектов
int sound1;
int sound2;
int pos = 0; // переменная для сохранения положения сервопривода
void setup()
{
Serial.begin(9600);
myservo.attach(5); // присоединяет сервопривод на выводе 9 к
myservo2.attach(6);
}
void loop()
{
sound1 = analogRead(A0);
sound2 = digitalRead(7);
if (sound1 > 50)
for(pos = 0; pos < 180; pos += 1) // переходит от 0 градусов к 180 градусам
{ // с шагом в 1 градус
myservo.write(pos); // скажите сервоприводу перейти в положение в переменной 'pos'
delay(15); // ожидает 15 мс, пока сервопривод достигнет нужного положения
}
for(pos = 180; pos>=1; pos-=1) // переходит от 180 градусов к 0 градусам
{
myservo.write(pos); // скажите сервоприводу перейти в положение в переменной 'pos'
delay(15); // ожидает 15 мс, пока сервопривод достигнет нужного положения
}
if (sound2 > 50)
for(pos = 0; pos < 180; pos += 1) // переходит от 0 градусов к 180 градусам
{ // с шагом в 1 градус
myservo2.write(pos); // скажите сервоприводу перейти в положение в переменной 'pos'
delay(15); // ожидает 15 мс, пока сервопривод достигнет нужного положения
}
for(pos = 180; pos>=1; pos-=1) // переходит от 180 градусов к 0 градусам
{
myservo2.write(pos); // скажите сервоприводу перейти в положение в переменной 'pos'
delay(15); // ожидает 15 мс, пока сервопривод достигнет нужного положения
}
}
Я работал над этим некоторое время, но по какой-то причине всякий раз, когда я пытаюсь закодировать звуковой датчик, он всегда игнорируется, так что, например, если в моем коде написано: "если звуковой датчик номер 1 обнаруживает звук, переместитесь на 90 градусов по вертикали или горизонтали", он всегда игнорирует это, если заявление и просто непрерывно перемещается на 90 градусов куда угодно. Мне нужно, чтобы он следовал за моим голосом, или, если это слишком сложно, хорошо, если он просто следует за любым звуком. Поэтому, если я повернусь на 30 градусов вправо на кронштейне панорамирования и наклона и заговорю, мне нужно, чтобы он повернулся ко мне лицом. Кроме того, я использую звуковой датчик KY-037, красную версию с 4 контактами. Любой совет был бы действительно полезен, спасибо.
@Kevin Zefi, 👍1
Обсуждение1 ответ
То, чего вы пытаетесь достичь, нелегко. Ожидайте, что вы потратите много времени на его разработку, тестирование и настройку.
Первым шагом будет проработка акустики вашего устройства. Звуковые датчики не чувствительны к направлению входящего звука, поэтому вам придется использовать два из них, обращенных в разные стороны, как уши на вашей голове обращены в разные стороны. Было бы полезно иметь полярный график ваших микрофонов: если они недостаточно направлены, возможно , вам придется создать какое-то звуковое препятствие между ними (“головка” между ушами или, может быть, даже пара “ушных раковин”), чтобы улучшить угловую избирательность. С кардиоидными микрофонами вам может сойти с рук, если вы просто повернете их на 180° друг от друга.
Чтобы сделать это правильно, может потребоваться значительное усилие. Двухканальный осциллограф и синусоидальный источник звука очень помогли бы: следите за сигналами, выходящими из обоих микрофонов, и смотрите, как меняются их амплитуды при повороте головы. Вы хотите, чтобы они были достаточно чувствительны к этой ориентации. Затем отрегулируйте потенциометры внутри звуковых модулей, чтобы иметь одинаковые амплитуды, когда голова обращена к источнику звука.
Затем вам нужно будет попробовать эти сигналы с помощью вашего Arduino. Частота
дискретизации Arduino по умолчанию (analogRead ()
в замкнутом цикле) составляет около
8,93 кГц для одного канала или 4,46 кГц на канал при
чередовании двух каналов. Этого может быть достаточно для получения приблизительной
оценки интенсивности голоса, но она как бы на грани слишком
низкой. Возможно, вы захотите увеличить частоту дискретизации: способ сделать это
обсуждался здесь и находится всего в нескольких шагах.
В analogRead()
частота дискретизации также непоследовательна и
зависит от того, что делает скетч: чем больше работает процессор, тем
медленнее частота дискретизации. Я бы настоятельно рекомендовал разрешить АЦП
работать в свободном режиме и извлекать выборки из
процедуры обслуживания прерываний. Для этого вам придется сначала прочитать и понять
глава об АЦП из спецификации микроконтроллера.
Затем вы должны оценить интенсивность по образцам, которые вы прочитали. В принципе, это означает низкочастотную фильтрацию квадрата переменной части сигнала. Если это слишком много работы, вы можете обойтись простым определением пика.
Возможно, вы захотите взглянуть на этот скетч звукометра для вдохновения. Он использует технологию автономного АЦП и оценивает амплитуду звука, используя надлежащую “фильтрацию нижних частот по квадрату Переменный ток часть сигнала”. Однако это одноканальный, и вам придется адаптировать его для отслеживания двух каналов. Это потребовало бы изменения настроек мультиплексора в ISR.
Наконец, вам нужно будет заставить сервопривод панорамирования реагировать на разницу в интенсивности между двумя ушами. Это самая простая часть, она может выглядеть примерно так:
void loop() {
float intensity_right = get_sound_intensity(RIGHT_MIKE);
float intensity_left = get_sound_intensity(LEFT_MIKE);
// Двигайте головой только в том случае, если мы действительно слышим звук.
if (intensity_right >= intensity_threshold
|| intensity_left >= intensity_threshold) {
float difference = intensity_right - intensity_left;
// Двигайте головой только в том случае, если разница в интенсивности
// значимый.
if (fabs(difference) >= difference_threshold) {
if (difference > 0 && servo_position < 180) {
servo_position += 1;
servo.move(servo_position);
} else if (difference < 0 && servo_position > 0) {
servo_position -= 1;
servo.move(servo_position);
}
}
}
}
Я пытаюсь запустить этот код, и "get_sound_intensity" выдает ошибку, в нем говорится, что он не объявлен в этой области, как это определить? Кроме того, есть ли у вас личная электронная почта? Я хочу прислать вам более подробную информацию о том, что я делаю. Мне нужно закончить это до 9 апреля, и мне действительно нужна помощь специалистов прямо сейчас, @Kevin Zefi
@KevinZefi: Re “_ как определить [get \ _sound \ _intensity]_”: большая часть моего ответа посвящена тому, как его определить. Вы прошли через это? Я бы предпочел не сообщать свой личный адрес электронной почты., @Edgar Bonet
Хорошо, проблема с осциллографами, я на самом деле не могу использовать их для проекта, мой проект - это система камеры для отслеживания голоса, основные цели этого проекта - закодировать серводвигатели и отслеживать мой голос И мое лицо, мне удалось завершить отслеживание лица. Если то, что я просил, слишком сложно, тогда я могу просто получить более простой код, мне нужно, чтобы код имел такую логику: если звук сначала достигает датчика 1, поверните на 90 градусов, что-то в этом роде. Мне нужно, чтобы проект был переносимым, если это имеет смысл, мне нужно будет представить это моим преподавателям, и я не могу подключить его к области O., @Kevin Zefi
Конечным результатом будет создание одного блока, который содержит все внутри, поэтому я не могу допустить, чтобы проект зависел от подключения его к осциллографам всякий раз, когда я его включаю. "Я бы предпочел не сообщать свой личный адрес электронной почты" Хорошо, извините, что я спросил, есть ли какой-нибудь другой способ, которым я могу отправить вам подробную информацию о моем проекте?, @Kevin Zefi
Кроме того, с помощью функции отслеживания лиц мне удалось закодировать вращение сервоприводов в зависимости от того, где находится мое лицо, это была просто догадка, но могу ли я просто добавить к этому коду изменение восприятия звука?, @Kevin Zefi
@КевинЗефи: Осциллограф предназначен только для этапа разработки и не должен храниться как часть проекта., @Edgar Bonet
Мозг человека (и других животных) делает гораздо больше, чем просто смотрит на различную интенсивность звука, чтобы вычислить угол и расстояние звука. Он также сравнивает разность фаз, что используется "3D sound" из стереодинамиков / наушников. Кстати, трудно определить направление по более высокому и размашистому звуку, вот почему дрозды используют такой звук в качестве сигнала тревоги для воздушных хищников - другие птицы знают, что это значит, но ястреб над головой не может определить, откуда исходит сигнал..., @Majenko
- Последовательная связь Arduino с Python: отправка массива
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Сброс последовательного порта Arduino в последовательном мониторе и Python
- Код для 2 ультразвуковых датчиков
- Последовательная связь между python и arduino
- Динамически обновить масштаб виджета Tkinter из портов Arduino с помощью python и firmata
- Связь между Arduino и python: последовательный порт отправляет пустые данные
- Почему нужно использовать latin-1 вместо utf-8 при использовании python с arduino?
Почему вы используете
digitalRead ()
дляsound2
? Он вернет только 0 или 1. Так чтоif(sound2> 50)
никогда не будет истинным. Кроме того, в настоящее время ваш код сообщает сервоприводу перемещаться на 180 градусов вперед и назад. Ничего с углом наклона 90° или следующего за вами. Какие звуковые датчики у вас есть? Я не совсем понимаю, чего вы хотите добиться. Вы хотите, чтобы сервоприводы следовали за вами линейно (например, двигаясь на 30 °, когда вы говорите с 30 °)? Или вы хотите, чтобы он менялся между 2 позициями? Что должно произойти, если оба датчика обнаружат достаточно громкий звук?, @chrisl