Проблема переводчика Морзе с микрофоном

Я работаю над переводчиком Морзе. Теперь я могу использовать датчик освещенности и обычную клавишу в качестве устройства ввода и хочу добавить в систему микрофон. Я получаю ввод, преобразую его в текст и показываю на ЖК-дисплее 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 = "";                            // сбрасываем код в пустую строку
}

, 👍2

Обсуждение

распечатайте signal_len, @Juraj

Пожалуйста, не используйте goto, если только вам это действительно не нужно. Использование этого может привести к большим проблемам. Есть причина, по которой он редко используется в C/C+. Вы можете просто поместить convertor() внутри if, где находится goto, и добавить после него разрыв., @chrisl

В зависимости от того, какой «микрофон» вы используете, вам также может понадобиться предусилитель., @chrisl


1 ответ


Лучший ответ:

1

Я подключил контакты Out и Gnd к микрофону так же, как ключ и ВСС на 5В.

Это не работает. В отличие от ключа микрофон представляет собой аналоговое устройство, будет выводить постоянно изменяющийся аналоговый сигнал. Если вы подвергаете его воздействию чистый тон будет выдавать синусоиду. Если вы споете ноту перед ним, он уберет не только синус, но и множество гармоник. В любом случае, он также улавливает окружающий шум.

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

,