Проблема переводчика Морзе с микрофоном
Я работаю над переводчиком Морзе. Теперь я могу использовать датчик освещенности и обычную клавишу в качестве устройства ввода и хочу добавить в систему микрофон. Я получаю ввод, преобразую его в текст и показываю на ЖК-дисплее nokia 5110. А также при вводе светодиод и зуммер включаются и выключаются одновременно. Когда я использую микрофон, светодиод работает так, как должен, но я не получаю правильного ввода на ЖК-дисплей. Я подключил контакты Out и Gnd микрофона так же, как я подключил бы ключ и vcc к 5v.
Ниже приведен код, который я использую
#define RST 12
#define CE 11
#define DC 10
#define DIN 9
#define CLK 8
#include "font.h";
unsigned long signal_len,t1,t2; //время, в течение которого кнопка нажата
int inputPin=2; //входной пин для кнопки
int ledPin=4; //выходной контакт для светодиода
String code=""; //строка, в которой хранится один алфавит
void LcdWriteString(char *characters){
while(*characters) LcdWriteCharacter(*characters++);
}
void LcdWriteCharacter(char character){
for(int i=0;i<5;i++) LcdWriteData(ASCII[character-0x20][i]);
LcdWriteData(0x00);
}
void LcdWriteData(byte dat)
{
digitalWrite(DC, HIGH); //вывод постоянного тока низкий для команд
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, dat); //передача последовательных данных
digitalWrite(CE, HIGH);
}
void LcdWriteCmd(byte cmd)
{
digitalWrite(DC, LOW); //вывод постоянного тока низкий для команд
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, cmd); //передача последовательных данных
digitalWrite(CE, HIGH);
}
void setup()
{
Serial.begin(9600);
pinMode(inputPin, INPUT_PULLUP); //внутренний подтягивающий резистор используется для упрощения схемы
pinMode(ledPin,OUTPUT);
pinMode(RST, OUTPUT);
pinMode(CE, OUTPUT);
pinMode(DC, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CLK, OUTPUT);
digitalWrite(RST, LOW);
digitalWrite(RST, HIGH);
LcdWriteCmd(0x21); // Расширенные команды LCD
LcdWriteCmd(0xA9); // устанавливаем LCD Vop (контрастность)
LcdWriteCmd(0x04); // установка временного коэффициента
LcdWriteCmd(0x14); // Режим смещения LCD 1:40
LcdWriteCmd(0x20); // Основные команды ЖК-дисплея
LcdWriteCmd(0x0C); // обычное видео LCD
for(int i=0;i<504;i++)LcdWriteData(0x00);
}
void loop()
{
NextDotDash:
while (digitalRead(inputPin) == HIGH) {}
t1 = millis(); //время нажатия кнопки
digitalWrite(ledPin, HIGH); //светодиод горит пока кнопка нажата
while (digitalRead(inputPin) == LOW) {}
t2 = millis(); //время отпускания кнопки
digitalWrite(ledPin, LOW); // светодиод гаснет при отпускании кнопки
signal_len = t2 - t1; //время, в течение которого кнопка нажата
if (signal_len > 50) //для учета устранения дребезга коммутатора
{
code += readio(); //функция для чтения точки или тире
}
while ((millis() - t2) < 500) //если время между нажатиями кнопки больше 0,5 сек, пропустить цикл и перейти к следующему алфавиту
{
if (digitalRead(inputPin) == LOW)
{
goto NextDotDash;
}
}
convertor(); //функция для расшифровки кода в алфавит
}
char readio()
{
if (signal_len < 150 && signal_len > 20)
{
return '.'; //если кнопка нажата менее 0.6сек, то это точка
}
else if (signal_len > 150)
{
return '-'; //если кнопка нажата более 0.6сек, это тире
}
}
void convertor()
{
static String letters[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "E"
};
int i = 0;
if (code == ".-.-.-")
{
Serial.print("."); //для перерыва
LcdWriteCharacter(".");
}
else
{
while (letters[i] != "E") //цикл сравнения входного кода с массивом букв
{
if (letters[i] == code)
{
Serial.print(char('A' + i));
LcdWriteCharacter(char('A' + i));
break;
}
i++;
}
if (letters[i] == "E")
{
Serial.println(""); //если входной код не соответствует ни одной букве, ошибка
LcdWriteCharacter("");
}
}
code = ""; // сбрасываем код в пустую строку
}
@E.Canberk, 👍2
Обсуждение1 ответ
Лучший ответ:
Я подключил контакты Out и Gnd к микрофону так же, как ключ и ВСС на 5В.
Это не работает. В отличие от ключа микрофон представляет собой аналоговое устройство, будет выводить постоянно изменяющийся аналоговый сигнал. Если вы подвергаете его воздействию чистый тон будет выдавать синусоиду. Если вы споете ноту перед ним, он уберет не только синус, но и множество гармоник. В любом случае, он также улавливает окружающий шум.
Что вам нужно сделать, так это как-то определить амплитуду звука сигнал, затем сравните его с некоторым порогом, чтобы решить, является ли амплитуда достаточно высока, чтобы считаться включенной. Вы можете использовать пиковый детектор на основе диодов и компаратор. Делать все это в коде какой-то хитрый. Вы можете взглянуть на этот измеритель уровня звука. скетч, но обратите внимание, что обнаружение пиков программного обеспечения может быть проще, чем обнаружение истинной среднеквадратичной интенсивности, реализованное в этом скетче.
- avrdude ser_open() can't set com-state
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Какое максимальное энергопотребление Arduino Nano 3.0?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Питание светодиодной ленты - Сколько ампер?
- Arduino nano как клавиатура HID
- Как я могу запитать Arduino Nano от батареи LiPo, желательно 3,7 В
- В чем разница между библиотеками Software Serial? Какая из них совместима с Arduino Nano?
распечатайте
signal_len
, @JurajПожалуйста, не используйте
goto
, если только вам это действительно не нужно. Использование этого может привести к большим проблемам. Есть причина, по которой он редко используется в C/C+. Вы можете просто поместитьconvertor()
внутри if, где находитсяgoto
, и добавить после него разрыв., @chrislВ зависимости от того, какой «микрофон» вы используете, вам также может понадобиться предусилитель., @chrisl