uSpeech + микрофон + Arduino Uno R3, помогите разобраться с командами.

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Приветствую. Юзаю uSpeech либу с 3 Pin-ым микрофон-модулем при Arduino Uno R3.

Я брал пример отсюда: http://cyber-place.ru/showthread.php?t=454

Здесь вроде бы всё написано: https://www.polesite.ru/?p=2001

[ я не понимаю принцип присвоения ].

Скажем, "Люмус", "Алахамора", "Bravo", "Fiasco", "Lingarvium Leviosa"
Как мне получить такие команды? Спасибо ...
 

countervectorbase
Offline
Зарегистрирован: 04.10.2020

А еще у меня не работает не один пример ( из данных ссылок ). Сегодня только получаю товар. Может быть не подключено к ардуино модульное устройство микрофона, а я ... 
 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

countervectorbase пишет:

А еще у меня не работает не один пример ( из данных ссылок ). Сегодня только получаю товар. Может быть не подключено к ардуино модульное устройство микрофона, а я ... 

А у меня ни один пример не работает. Может быть, у меня нет ни ардуино, ни микрофона? Не подскажете, куда копать?

 

lilik
Offline
Зарегистрирован: 19.10.2017

ЕвгенийП пишет:

countervectorbase пишет:

А еще у меня не работает не один пример ( из данных ссылок ). Сегодня только получаю товар. Может быть не подключено к ардуино модульное устройство микрофона, а я ... 

А у меня ни один пример не работает. Может быть, у меня нет ни ардуино, ни микрофона? Не подскажете, куда копать?

 

Это Властелин колец.

https://arduino.ru/forum/apparatnye-voprosy/kak-podobrat-rezistor-dlya-k...

Как там кольца?, кстати.

countervectorbase
Offline
Зарегистрирован: 04.10.2020

А!?! - Привет это я, ту вишь ишь батур. А вы про Кольцо то, что от дядюшки Бильбо, еще работают.  
Кстати, у меня неплохой алгоритм получился. А по теме что делать?
У меня не один пример не работает пишет ошибку.

Нашел,

#define sensorPin 7

// Переменная для хранения времени, когда произошло последнее событие
unsigned long lastEvent = 0;

void setup() 
{
  // Настраиваекм вывод, к которому подключен датчик, как вход
  pinMode(sensorPin, INPUT); 
  Serial.begin(9600);
}

void loop() 
{
  // Прочитать показания датчика
  int sensorData = digitalRead(sensorPin);

  // Если на вывод подан низкий логический уровень, то звук обнаружен
  if (sensorData == LOW) 
  {
    // Если прошло 25 мс с момента последнего состояния низкого логического уровня,
    // это значит, что обнаружен хлопок, а не какие-либо ложные звуки
    if (millis() - lastEvent > 25) 
    {
      Serial.println("Clap detected!");
    }

    // Запомнить, когда произошло последнее событие
    lastEvent = millis();
  }
}

 

зато: для хлопка код рабочий, что выше, а как теперь все это для голосовых команд сделать:
Но из примера библиотеки LEDtest не работает: вот, что пишет:

C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:18:32: warning: extra tokens at end of #ifdef directive
     #ifdef ARDUINO_ENVIRONMENT > 0
                                ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:28:36: warning: extra tokens at end of #ifdef directive
         #ifdef ARDUINO_ENVIRONMENT > 0
                                    ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp: In member function 'signal::maxPower()':
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:75:24: warning: iteration 31 invokes undefined behavior [-Waggressive-loop-optimizations]
         avgPower+=arr[i];
                   ~~~~~^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:69:13: note: within this loop
     while (i<32){
            ~^~~
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:75:24: warning: iteration 31 invokes undefined behavior [-Waggressive-loop-optimizations]
         avgPower+=arr[i];
                        ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:69:13: note: within this loop
     while (i<32){

 

lilik
Offline
Зарегистрирован: 19.10.2017

https://radioded.ru/raspoznavaniye-golosa-na-arduino/

По теме... вот это повторить, если заработает идти дальше, нет - значит идея сырая.

lilik
Offline
Зарегистрирован: 19.10.2017

countervectorbase пишет:

...то, что от дядюшки Бильбо, еще работают.  
Кстати, у меня неплохой алгоритм получился. 

Пора на матрицу переходить (8*32 пикселя) и делать огонь из Роковой горы :)

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Та же фигня с кодом. Lilik, этот пример тоже сбоит.

C:\Users\u1\AppData\Local\Temp\7zO0968C4C7\voice_recognition\voice_recognition.ino: In function 'char* guessWord(char*)':

C:\Users\u1\AppData\Local\Temp\7zO0968C4C7\voice_recognition\voice_recognition.ino:102:12: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
     return "";
            ^~
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:18:32: warning: extra tokens at end of #ifdef directive
     #ifdef ARDUINO_ENVIRONMENT > 0
                                ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:28:36: warning: extra tokens at end of #ifdef directive
         #ifdef ARDUINO_ENVIRONMENT > 0
                                    ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp: In member function 'signal::maxPower()':
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:75:24: warning: iteration 31 invokes undefined behavior [-Waggressive-loop-optimizations]
         avgPower+=arr[i];
                   ~~~~~^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:69:13: note: within this loop
     while (i<32){
            ~^~~
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:75:24: warning: iteration 31 invokes undefined behavior [-Waggressive-loop-optimizations]
         avgPower+=arr[i];
                        ^
C:\Users\u1\Documents\Arduino\libraries\uSpeech-4.x-workingBranch\signal.cpp:69:13: note: within this loop
     while (i<32){
             ^
 
lilik
Offline
Зарегистрирован: 19.10.2017

Не знаю, я скачал архив по ссылке, установил библиотеку и пример скомпилировался нормально. У меня версия иде 1.8.2.

countervectorbase
Offline
Зарегистрирован: 04.10.2020

У меня ардуино IDE 1.8.19. Вот такая ошибка, ардуино плату другую подключил.

Я просто выбрал порт из меню Инструменты/Порт/COM4, и тогда ошибка уменьшилась до такой, что я должен сделать теперь, когда вижу такую ошибку:
 

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':
C:\Program Files (x86)\Arduino\libraries\uSpeech\signal.cpp:85:24: warning: iteration 31 invokes undefined behavior [-Waggressive-loop-optimizations]
         avgPower+=arr[i];
                        ^
C:\Program Files (x86)\Arduino\libraries\uSpeech\signal.cpp:79:13: note: within this loop
     while (i<32){
             ^
 
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

countervectorbase пишет:
что я должен сделать теперь, когда вижу такую ошибку:

Прочитать сообщение (если надо, подключив переводчик). А затем исправить. Кода я не вижу, но скорее всего, проблема с типом avgPower, который на 31 шаге может переполнится. Но это не точно, т.к. кода я не вижу.

Upper
Offline
Зарегистрирован: 23.06.2020

  Надо в файле signal.cpp исправить

        i++;
        avgPower+=arr[i];

на

        avgPower+=arr[i];
        i++;

Иначе массив выходит за границу.

 

lilik
Offline
Зарегистрирован: 19.10.2017

ЕвгенийП пишет:

Но это не точно, т.к. кода я не вижу.

#include <uspeech.h>
#define ledGreen 7
#define ledOrange 6
#define ledWhite 5
#define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
signal voice(A0);
const int BUFFER_MAX_PHONEMES=32;
char inputString[BUFFER_MAX_PHONEMES]; // Allocate some space for the string
byte index = 0; // Index into array; where to store the character
//
const int DICT_MAX_ELEMNTS=3;
char dict[DICT_MAX_ELEMNTS][BUFFER_MAX_PHONEMES]={"vvvoeeeeeeeofff","hhhhhvoovvvvf","hooooooffffffff"};
int LOWEST_COST_MAX_THREASHOLD=20;
void setup(){
  /*
  Phoneme      |   Literal       
  --------------------------------------------------------------------
  e            | The e sound.
  --------------------------------------------------------------------   
  h            | The `/sh/` sound. It can also be raised by 
               | `ch`, `j` and `z`
  --------------------------------------------------------------------
  v            | The `v` sound, occasionally triggered by  , 'z'
               | (may need to be fixed)
  --------------------------------------------------------------------
  f            | The `f` sound. 
  --------------------------------------------------------------------
  s            | The 's' sound.
  --------------------------------------------------------------------
  o            | 'a','o','i','r','l','m','n' and 'u' sounds. 
  --------------------------------------------------------------------
  ' '          | Too Quiet for anything
  --------------------------------------------------------------------
  */
  voice.f_enabled = true;
  voice.minVolume = 1500;
  voice.fconstant = 500;
  voice.econstant = 2;
  voice.aconstant = 4;
  voice.vconstant = 6;
  voice.shconstant = 10;
  voice.calibrate();
  Serial.begin(9600);
  pinMode(ledGreen, OUTPUT); 
  pinMode(ledOrange, OUTPUT); 
  pinMode(ledWhite, OUTPUT);
}
 
void loop(){
    voice.sample();
    char p = voice.getPhoneme();
    if(p==' ' || index >= BUFFER_MAX_PHONEMES){
      if(strLength(inputString)>0){
         Serial.println("received:"+String(inputString));
         parseCommand(inputString);
         inputString[0]=0;//clear string char array
         index=0;
      }
    }else{
      //printArray(voice.arr);
      inputString[index] = p; // Store it
      index++;
      inputString[index] = '\0'; // Null terminate the string
    }
}
 
char* guessWord(char* target){
  int len = strlen(target);//held target length
   
  for(int i=0;i<DICT_MAX_ELEMNTS;i++){
    //simple validation
    if(dict[i]==target){
      return dict[i];
    }
  }
   
  unsigned int cost[DICT_MAX_ELEMNTS];//held minimum distance cost
 
  //calculating each words cost and hits
  for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
      cost[j]=levenshtein(dict[j],target);
      Serial.println("dict[j]="+String(dict[j])+" target="+String(target)+" cost="+String(cost[j]));
  }    
   
  //Determining lowest cost but still all letters in the pattern hitting word
  int lowestCostIndex=-1;
  int lowestCost=LOWEST_COST_MAX_THREASHOLD;
  for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
    //Serial.println("dict[j]="+dict[j]+" dict[j].length()="+String(strlen(dict[j]))+" cost="+String(cost[j])+" hits="+String(hits[j])+" j="+String(j));
    if(cost[j]<lowestCost){
      lowestCost = cost[j];
      lowestCostIndex=j;
    }
  }
   
  //Serial.println("lowestCostIndex="+String(lowestCostIndex)+" lowestCost="+String(lowestCost));
   
  if(lowestCostIndex>-1){
    //Serial.println("lowestCost="+String(lowestCost)+" lowestCostIndex="+String(lowestCostIndex));
    return dict[lowestCostIndex];
  }else{
    return "";
  }
}
 
void parseCommand(char* str){
  char *gWord = guessWord(str);
  Serial.println("guessed :"+String(gWord));
  if(gWord==""){
    return;
  }else if(gWord==dict[0]){
    digitalWrite(ledGreen, HIGH);
    digitalWrite(ledOrange, LOW);
    digitalWrite(ledWhite, LOW);
  }else if(gWord==dict[1]){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledOrange, HIGH);
    digitalWrite(ledWhite, LOW);
  }else if(gWord==dict[2]){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledOrange, LOW);
    digitalWrite(ledWhite, HIGH);
  }
}
 
unsigned int levenshtein(char *s1, char *s2) {
    unsigned int s1len, s2len, x, y, lastdiag, olddiag;
    s1len = strlen(s1);
    s2len = strlen(s2);
    unsigned int column[s1len+1];
    for (y = 1; y <= s1len; y++)
        column[y] = y;
    for (x = 1; x <= s2len; x++) {
        column[0] = x;
        for (y = 1, lastdiag = x-1; y <= s1len; y++) {
            olddiag = column[y];
            column[y] = MIN3(column[y] + 1, column[y-1] + 1, lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1));
            lastdiag = olddiag;
        }
    }
    return(column[s1len]);
}
 
int strLength(char const* s) {
    int i = 0;
    while (s[i] != '\0' && s[i] != ' ')
        ++i;
 
    return i;
}

По идее этот должен быть.

lilik
Offline
Зарегистрирован: 19.10.2017

https://www.youtube.com/watch?v=_zlD2lvWB7k

Но говорить так слова у русского человека может не получится :)

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Upper пишет:

  Надо в файле signal.cpp исправить

        i++;
        avgPower+=arr[i];

на

        avgPower+=arr[i];
        i++;

Иначе массив выходит за границу.

 

 

Спасибо: исправил, но дело гиблое, все равно плохо распознается, завязываю с этим делом, и делаю хлопковый датчик: код не мой я его немного: "мооаддииффиицииорвал,"- и теперь - хлопок- релешка включается; хлопок - релешка выключается, и так бесконечно по четности срабатывает. Я столько парился с этой проблемой, можно было обычный clap sensor купить, в разы бы сэкономил, но что делать? В ардуино интересней от себя добавлять программу-скетч.Притом нужно еще потенциометром на почти максималку крутить нечувствительность. Но в целом было весело программировать.
 

Вот скетч для хлопка с тем же микрофоном + реле L1 и L2.
 

#define sensorPin 7 // Pin 7 для Микрофона
int led_13 = 13;
int L1 = 8; //Реле Pin 8;
int L2 = 9; //Реле Pin 9;
// Переменная для хранения времени, когда произошло последнее событие
unsigned long lastEvent = 0;
boolean Flag0=false;
void setup() 
{
  pinMode(L1,OUTPUT);
  pinMode(L2,OUTPUT);
  digitalWrite(L1,HIGH);
  digitalWrite(L2,HIGH);
  pinMode(led_13,OUTPUT);
  pinMode(sensorPin, INPUT); 
  Serial.begin(9600);
}

void loop() 
{
  // Прочитать показания датчика
  int sensorData = digitalRead(sensorPin);

  // Если на вывод подан низкий логический уровень, то звук обнаружен
  if (sensorData == LOW) 
  {
    // Если прошло 25 мс с момента последнего состояния низкого логического уровня,
    // это значит, что обнаружен хлопок, а не какие-либо ложные звуки
    if (millis() - lastEvent > 25) 
    {
      if(Flag0==true){
      Serial.println(String(Flag0));
      digitalWrite(led_13, HIGH);
      digitalWrite(L1, HIGH);
      digitalWrite(L2, HIGH);  
      Flag0=false;
      delay(150);
      }
      else if (Flag0==false){
       
      Serial.println(String(Flag0));
      digitalWrite(led_13, LOW);
      digitalWrite(L1,LOW);
      digitalWrite(L2,LOW);
      Flag0=true;
      delay(150);
      } 
    }

    // Запомнить, когда произошло последнее событие
    lastEvent = millis();
  }
}

 

countervectorbase
Offline
Зарегистрирован: 04.10.2020

lilik пишет:

ЕвгенийП пишет:

Но это не точно, т.к. кода я не вижу.

#include <uspeech.h>
#define ledGreen 7
#define ledOrange 6
#define ledWhite 5
#define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
signal voice(A0);
const int BUFFER_MAX_PHONEMES=32;
char inputString[BUFFER_MAX_PHONEMES]; // Allocate some space for the string
byte index = 0; // Index into array; where to store the character
//
const int DICT_MAX_ELEMNTS=3;
char dict[DICT_MAX_ELEMNTS][BUFFER_MAX_PHONEMES]={"vvvoeeeeeeeofff","hhhhhvoovvvvf","hooooooffffffff"};
int LOWEST_COST_MAX_THREASHOLD=20;
void setup(){
  /*
  Phoneme      |   Literal       
  --------------------------------------------------------------------
  e            | The e sound.
  --------------------------------------------------------------------   
  h            | The `/sh/` sound. It can also be raised by 
               | `ch`, `j` and `z`
  --------------------------------------------------------------------
  v            | The `v` sound, occasionally triggered by  , 'z'
               | (may need to be fixed)
  --------------------------------------------------------------------
  f            | The `f` sound. 
  --------------------------------------------------------------------
  s            | The 's' sound.
  --------------------------------------------------------------------
  o            | 'a','o','i','r','l','m','n' and 'u' sounds. 
  --------------------------------------------------------------------
  ' '          | Too Quiet for anything
  --------------------------------------------------------------------
  */
  voice.f_enabled = true;
  voice.minVolume = 1500;
  voice.fconstant = 500;
  voice.econstant = 2;
  voice.aconstant = 4;
  voice.vconstant = 6;
  voice.shconstant = 10;
  voice.calibrate();
  Serial.begin(9600);
  pinMode(ledGreen, OUTPUT); 
  pinMode(ledOrange, OUTPUT); 
  pinMode(ledWhite, OUTPUT);
}
 
void loop(){
    voice.sample();
    char p = voice.getPhoneme();
    if(p==' ' || index >= BUFFER_MAX_PHONEMES){
      if(strLength(inputString)>0){
         Serial.println("received:"+String(inputString));
         parseCommand(inputString);
         inputString[0]=0;//clear string char array
         index=0;
      }
    }else{
      //printArray(voice.arr);
      inputString[index] = p; // Store it
      index++;
      inputString[index] = '\0'; // Null terminate the string
    }
}
 
char* guessWord(char* target){
  int len = strlen(target);//held target length
   
  for(int i=0;i<DICT_MAX_ELEMNTS;i++){
    //simple validation
    if(dict[i]==target){
      return dict[i];
    }
  }
   
  unsigned int cost[DICT_MAX_ELEMNTS];//held minimum distance cost
 
  //calculating each words cost and hits
  for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
      cost[j]=levenshtein(dict[j],target);
      Serial.println("dict[j]="+String(dict[j])+" target="+String(target)+" cost="+String(cost[j]));
  }    
   
  //Determining lowest cost but still all letters in the pattern hitting word
  int lowestCostIndex=-1;
  int lowestCost=LOWEST_COST_MAX_THREASHOLD;
  for(int j=0;j<DICT_MAX_ELEMNTS;j++){//loop through the dictionary
    //Serial.println("dict[j]="+dict[j]+" dict[j].length()="+String(strlen(dict[j]))+" cost="+String(cost[j])+" hits="+String(hits[j])+" j="+String(j));
    if(cost[j]<lowestCost){
      lowestCost = cost[j];
      lowestCostIndex=j;
    }
  }
   
  //Serial.println("lowestCostIndex="+String(lowestCostIndex)+" lowestCost="+String(lowestCost));
   
  if(lowestCostIndex>-1){
    //Serial.println("lowestCost="+String(lowestCost)+" lowestCostIndex="+String(lowestCostIndex));
    return dict[lowestCostIndex];
  }else{
    return "";
  }
}
 
void parseCommand(char* str){
  char *gWord = guessWord(str);
  Serial.println("guessed :"+String(gWord));
  if(gWord==""){
    return;
  }else if(gWord==dict[0]){
    digitalWrite(ledGreen, HIGH);
    digitalWrite(ledOrange, LOW);
    digitalWrite(ledWhite, LOW);
  }else if(gWord==dict[1]){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledOrange, HIGH);
    digitalWrite(ledWhite, LOW);
  }else if(gWord==dict[2]){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledOrange, LOW);
    digitalWrite(ledWhite, HIGH);
  }
}
 
unsigned int levenshtein(char *s1, char *s2) {
    unsigned int s1len, s2len, x, y, lastdiag, olddiag;
    s1len = strlen(s1);
    s2len = strlen(s2);
    unsigned int column[s1len+1];
    for (y = 1; y <= s1len; y++)
        column[y] = y;
    for (x = 1; x <= s2len; x++) {
        column[0] = x;
        for (y = 1, lastdiag = x-1; y <= s1len; y++) {
            olddiag = column[y];
            column[y] = MIN3(column[y] + 1, column[y-1] + 1, lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1));
            lastdiag = olddiag;
        }
    }
    return(column[s1len]);
}
 
int strLength(char const* s) {
    int i = 0;
    while (s[i] != '\0' && s[i] != ' ')
        ++i;
 
    return i;
}

По идее этот должен быть.

Пример из этой либы: на ура тот, что ... LEDtest  я поменял местами в либе как было сказано выше;

  Надо в файле signal.cpp исправить

        i++;
        avgPower+=arr[i];

на

        avgPower+=arr[i];
        i++;

Иначе массив выходит за границу.

Но этот код тоже дает ошибку, только другую:

C:\Users\u1\Desktop\MyClap\MyClap.ino: In function 'char* guessWord(char*)':
C:\Users\u1\Desktop\MyClap\MyClap.ino:102:12: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
     return "";
            ^~