Помогите в написании программы для определения частоты звука(240-280Гц)

Mynlait
Offline
Зарегистрирован: 17.11.2012

Нужна программа для определения частоты звука с условием. К примеру если частота повторяется и она равна 240-280Гц то делает определённое действие. С ардуино знаком но в програмировании не селён так сказать я больше по технической а не программной. Подскажите с чего можно начать, может есть какие то библеотоеке по работе со звукаом? 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015
wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Библиотека fft для ардуино. Секретом не является. Описана везде. Какая-то еще помощь нужна?

-----------------------------------------------

Подумав о том, кто и с каким бэкграундом читает форум, вынужден добавить: fft это фаст Фурье трансформ, то есть быстрое преобразование Фурье. Как оно связано с определением частоты звука? Ликбез только за деньги!

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

wdrakula пишет:

Библиотека fft для ардуино. Секретом не является. Описана везде. Какая-то еще помощь нужна?

Да. Еще нада всё это реализовать, сюда выложить и рассказать как USB-шнур патключить к ордуине или по радмину залить. А так - болши ничеаво...

DIYMan! А ты вот не можеш не потъепнуть живова чилавека, да? ))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Buzzer2010 пишет:

DIYMan! А ты вот не можеш не потъепнуть живова чилавека, да? ))

Ну чтобы потъепнуть мьортвага - у меня как-то ещё не получалось :) А если серьёзно - ну видно же, что очередное "дайте мне фсьо и прямо здесь!". Если бы чел имел хоть грамм желания разобраться самому - ввёл бы строчку поиска в гугле. А так как я действительно хотел помочь - я просто немного поработал lmgtfy, вот и всё.

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

Mynlait пишет:

Подскажите с чего можно начать

Начните либо с изучения программирования, либо с заказа программы в разделе "Ищу исполнителя".

кутузов
Offline
Зарегистрирован: 22.06.2016

Частоту можно мерять измеряя период. Например при помощи pulseln(). Но со звуком не представляю как. Может проще поставить фильтр который отфильтрует все лишнее кроме 240-280Гц и подать сигнал на пин... но это уже не программирование.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

А что значит - "со звуком"? Имеется сигнал постоянной частоты и надо определить эту частоту?

Тогда надо подать этот сигнал на аналоговый вход, записать 1000 отсчетов в массив через АЦП, используя  analogread()

//============== измерения ================== 
  float  timeIZMsec, tdiskr;
  unsigned long timeB, timeE;
  int NumPoint=1000;
  int AnalogVal0[NumPoint]; // значения в ступеньках АЦП
  timeB = micros(); // начало периода измерений
  for (int i = 0; i < NumPoint; i++)
    {
AnalogVal0[i] = analogRead(A0); 
delayMicroseconds(100);//  задержка между отсчетами, выбирается такая, чтобы 
// всего было измерено например 10 периодов сигнала
    }
    timeE = micros(); // время окончания измерений
    timeIZMsec = double(timeE - timeB) / double(1000000); // длительность измерений в сек
    // 6888 мкс на 1000 отсчетов 147 кгц 
    // 4100 мкс на 1000 отсчетов 240 кгц 
    tdiskr = float(timeE - timeB) / NumPoint; // частота дискретизации

Затем пробежаться в цикле по полученному массиву и найти переходы через 0 (или другой уровень) и померять. сколько микросекунд между этими переходами

int PeriodSignala=0 
int Uroven=555; //в ступеньках АЦП. сигнал должен пересекать этот уровень
int p1,p2, ip;

for (int i = 1; i < NumPoint; i++)
    {
        if (AnalogVal0[i-1] <Uroven)&&(AnalogVal0[i+1] >Uroven)
          {
             if (p1==0) p1=i;
             else
               { 
                  p2=i;
                  PeriodSignala=PeriodSignala+ (p2-p1);
                  ip++;
               }

          }
    }

PeriodSignala=PeriodSignala/ip;//среднее значение периода

зы. код на ошибки не проверял
 

Logik
Offline
Зарегистрирован: 05.08.2014

кутузов и diakin дали вредные советы. Фильтр снаружи - позапрошлый век, а еще и на такие частоты - вобще мрак, еще можна на грамофон записать и под микроскопом рассматривать. Сохранять в массив и потом ловить переходы через ноль плохо - постоянная составляющая, дрейф нуля, шумы и наводки приведут к тому что момент перехода через ноль будет "плавать". Но если уж очень хочется так - то буфер нахрена? Сразу после ввода и анализируйте налету что там выходит. Ну и float убрать конечно.

Правильные решения:

1. FFT то что Вы его не понимаете не важно, его 90% использующих не понимают.

2. Цифровой фильтр, гуглите БИХ, КИХ они менее ресурсоемки чем FFT.

Что лучше? Мало информации от вас чтоб выбрать. 

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Logik пишет:

ловить переходы через ноль плохо - постоянная составляющая, дрейф нуля, шумы и наводки приведут к тому что момент перехода через ноль будет "плавать".

Частотомер частоту реального сигнала как измеряет? С шумами, наводками и плавньем нуля...

 

Logik
Offline
Зарегистрирован: 05.08.2014

В частотомере для борьбы с этим имеет много схем формирования сигнала перед подсчетом.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Logik пишет:

В частотомере для борьбы с этим имеет много схем формирования сигнала перед подсчетом.

Это прошлый век. )))

Сейчас можно всю обработку сделать программно, но для этого нужно сначала сохранить данные в буфер.
В том числе и для последующего FFT.

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

diakin пишет:

Частотомер частоту реального сигнала как измеряет? С шумами, наводками и плавньем нуля...

Ну, не так же, как у Вас, правда?

Вы посмотрите на Ваш скетч и ответьте когда (и с какой периодичностью" Вы делаете измерения (т.е. вызываете analogRead)? Ответ: вызываю, когда loop до неё доберётся - как часто - как получится. Вот и ответ на точность Вашего метода - "как получится".

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Нет, не (совсем) так. Loop добирается туда с регулярной периодичностью )

Вернее даже не Loop, а цикл в котором формируется массив отсчетов.
AnalogVal0[i] = analogRead(A0); // выполняется на DUE примерно за 5 мкс
delayMicroseconds(100);//

Так что частота дискретизации и время измерения вполне стабильны.

 

 

 

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

diakin пишет:

Нет, не (совсем) так. Loop добирается туда с регулярной периодичностью )

Вернее даже не Loop, а цикл в котором формируется массив отсчетов.
AnalogVal0[i] = analogRead(A0); // выполняется на DUE примерно за 5 мкс
delayMicroseconds(100);//

Так что частота дискретизации и время измерения вполне стабильны.

Проверьте осциллографом. Узнаете много нового и интересного :))))

Стабильно было бы, если бы Вы при этом ещё и прерывания закрыли, а так ... см. осциллограмму вот здесь. Там и обсуждение есть почему такие фокусы случаются.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

>Видимо, в этот момент произошло прерывание от таймера и контроллер занялся своей работой по подсчёту >миллис и т.п., а наша программа покорно ждала пока там всё сделается.

Ну это да, может быть. Хотя зачем таймеру дергать прерывания.. По хорошему он должен непрерывно считать [предделённые] такты, и только по вызову millis контроллер будет читать значение из таймера и переводить его в мс\мкс. Это если по-хорошему. Хотя наверное так и есть )

 

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

diakin пишет:

Ну это да, может быть. Хотя зачем таймеру дергать прерывания.. По хорошему он должен непрерывно считать [предделённые] такты, и только по вызову millis контроллер будет читать значение из таймера и переводить его в мс\мкс. Это если по-хорошему. Хотя наверное так и есть )

Посмотрите как это реально сделано. Исходники же все есть, вместе с IDE приходят.