Алгоритм Герцеля для массива нот.

Swat_III
Offline
Зарегистрирован: 08.09.2016

Всем здравствуйте, пишу в отчаяние и взываю о помощи вот по какому вопросу. Решил собрать вот такую шкатулку, но на свою Arduino Nano залить код так и не смог. Нашел в сети библиотеку Герцеля и пример использования, однако он расчитан на нахождение только одной ноты. 

 

И вот собственно вопрос как сделать так что бы алгоритм распознавал одну частоту (ноту) и переходил к следующей? 

Вот мой код с которым Я мучаюсь. Проблема его в том что изменение "target_freq" искомой частоты, происходит только в момент исполнения while и только на мгновение, а далее опять возвращается к значению глобальной переменной (587.33) Надеюсь на вашу помощь, заранее спасибо! 

#include <Goertzel.h>
int sensorPin = A0;
int led = 13;

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  static int pattern[] = { 587.33, 698.46, 775.33, 880.21 };

  float target_freq = target_freq;
  target_freq = 587.33; //must be an integer of 9000/N and be less than
  float spoon = target_freq + 2.0;
  float fork = target_freq - 2.0;

  //sampling_frequency/2 (thanks to Nyquist)
  float n = 20.0;
  float sampling_freq = 9000.0;

  Goertzel goertzel = Goertzel(target_freq, n, sampling_freq);

  goertzel.sample(sensorPin); //Will take n samples

  float magnitude = goertzel.detect();  //check them for target_freq

  while (magnitude >= target_freq && magnitude <= spoon) { //if you're getting false hits or no hits adjust this
    
    
    target_freq = 698.46;
    digitalWrite(led, HIGH);
    delay (100);
    digitalWrite(led, LOW);
    delay (100);

    goto P2;

  }

P2:

  while (magnitude >= target_freq && magnitude <= spoon) { //if you're getting false hits or no hits adjust this

    digitalWrite(led, HIGH);
    delay (500);
    digitalWrite(led, LOW);
    delay (500);

    target_freq = 775.33;//if found, enable led
    goto P3;

  }

P3:
  while (magnitude >= target_freq && magnitude <= spoon) { //while you're getting false hits or no hits adjust this

    digitalWrite(led, HIGH);
    delay (100);
    digitalWrite(led, LOW);
    delay (100);
    digitalWrite(led, HIGH);
    delay (100);
    digitalWrite(led, LOW);
    delay (100);
    target_freq = 880.21;//if found, enable led
    goto P11;

  }

P11:
  while (magnitude >= target_freq && magnitude <= spoon)
  {
    digitalWrite(led, HIGH);
    delay(3000);
    digitalWrite(led, LOW);
  }
  Serial.println(target_freq);
}

 

ptr
Offline
Зарегистрирован: 28.05.2016

Swat_III пишет:

Проблема его в том что изменение "target_freq" искомой частоты, происходит только в момент исполнения while и только на мгновение, а далее опять возвращается к значению глобальной переменной


  float target_freq = target_freq;

Так у Вас же это явно указано. Уберите эту строку, и все встанет на свои места.

ptr
Offline
Зарегистрирован: 28.05.2016

А строку

target_freq = 587.33;

перенесите в setup()