Нужна помощь по обработке аналогово сигнала
- Войдите на сайт для отправки комментариев
Вс, 26/03/2017 - 20:57
Имеется датчик давления трехногий аналоговый, он выдает аналоговый сигнал определенной частоты (возьмем к примеру 35 Гц) как сделать так чтобы вместо всего сигнала получить на обработку пиковые значения осредненные за 1 секунду. Именно пиковые на не осредненные из разряда булеана.
Так они пиковые или усредненные?
необходимая мне величина = сумма пиковых значений за 1 сек / количество пиковых значений за 1 сек
к примеру сигнал 35 Гц пиковое напряжение 4 В если использовать булеан то напряжение выходит уже не 4 вольта, а нужно чтобы получалось именно 4. то есть он прибавит 35 четверок раздели на количество оно же 35 и получится 4 волька. помогите как это осуществить?
Совершенно не понятно что такое булеан в применении к данной задаче и как его можно использовать? Давление пропорционально напряжению импульса или частоте? Задача поиска пиковых значений всегда упирается в ширину рассматриваемого интервала. Например, если на интервале все значения монотонно убывают, то пикового значения нет. Есть максимальное, но оно не соответствует пиковому. Какие пиковые значения вам нужны? В каждом отдельном импульсе? Ваши 35 четвёрок из частоты 35 герц вытекают? К тому же обычно импульсы имеют выбросы на фронте и часто разной высоты - их приписывать пиковому значению, или всё же усреднённую верхнюю полку отдельного импульса? Точнее надо формулировать задачу. А если бы ещё рисунок сигнала был приведён с указанием в каком месте брать пиковые значения - тогда можно было начать думать, что посоветовать.
Давление пропорционально напряжению, интервал делается в 1 секунду и на нем имеется четкая синусоида, пример сигнала вот http://anderbot.com/wp-content/uploads/android/screenshot/3/com.spectroanalyz/image_12.png берутся пиковые значения напряжения каждого импульса и вычисляется среднее напряжение из количества взятых за интервал , в итоге получается напряжение 3212 мВ (грубо говоря), далее используя формулу 20log(P/P1) получают величину в дБ. даже если будут выбросы то сигнал через какое то время будет нормализоваться на стабильный как показано на рисунке, ну и получается что каждую секунду должно быть новое значение напряжения. примерно получается как измерение на осцилографе peak или peak to peak, но в данном случае интересно значение peak
В данном скетче от осцилографа производиться замер и вывод пикового сигнала и замер частоты, помогите разобраться как вытащить оттуда то что мне необходимо
#include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> #include <SPI.h> #include <FreqCount.h> #define DISPLAY_WIDTH 84 #define DISPLAY_HEIGHT 48 #define ARDUINO_PRECISION 1023.0 Adafruit_PCD8544 display = Adafruit_PCD8544(14, 13, 12, 11, 10); int channelAI = A4; //вход сигнала А5, частоту меряем на 5!!! int PINakum = A6; //вход замера аккумулдятора int delayAI = A5; //делитель нп потенциометре int razv = 0;// константы и пины добавления развертки #define DELAY_POTENTIMETER #ifdef DELAY_POTENTIMETER #endif float delayVariable = 0; float scale = 0; int xCounter = 0; int yPosition = 0; int readings[DISPLAY_WIDTH+1]; int counter = 0; unsigned long drawtime = 0; unsigned long lastdraw = 0; unsigned long count =0; int frames = 0; void setup() { FreqCount.begin(1000); display.begin(); display.setContrast(55); display.display(); display.clearDisplay(); display.setCursor(15,0); display.print("PULTOSCOPE"); display.setCursor(10,10); display.print("Mobile v1.1"); //#################тест аккумулятора if ((analogRead(PINakum)/ARDUINO_PRECISION*5.0)>3.3){ display.setCursor(5,25); display.print("Test Batt OK!"); } if ((analogRead(PINakum)/ARDUINO_PRECISION*5.0)<3.3){ display.setCursor(5,25); display.print("Test Batt NO!"); } display.setCursor(25,35); display.print(analogRead(PINakum)/ARDUINO_PRECISION*5.0); display.print("V"); display.display(); delay(3000); //####################### } void loop() { #ifdef DELAY_POTENTIMETER delayVariable = analogRead(delayAI); delayVariable = (delayVariable/100);//делитель регулирует выборку #endif //scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION; scale = 47.0/1210.0; //ограничиваем диаграмму на один символ сверху //##############################################разделение шкалы по сигналу for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++) { yPosition = analogRead(channelAI); readings[xCounter] = (yPosition*scale); #ifdef DELAY_POTENTIMETER delay (delayVariable); #endif } display.clearDisplay(); //##############################################шкала напряжений display.drawLine( 10, 7, 10, DISPLAY_HEIGHT-1, BLACK); display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK); display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK); display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK); display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK); display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3); display.print((int)(5.0*0.2)); display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3); display.print((int)(5.0*0.4)); display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3); display.print((int)(5.0*0.6)); display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3); display.print((int)(5.0*0.8)); //##############################################отрисовка сигнала for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++) { display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK); if(xCounter>1){ display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK); } } //############################вывод частоты учитывая килогерцы if (count<1000){ display.setCursor(32,0); display.print(count); display.print("Hz"); } if (count>1000){ display.setCursor(32,0); display.print((count)/1000); display.print("KHz"); } display.setCursor(66,0); display.print(razv); //############################################вывод напряжения display.setCursor(0,0); display.print(analogRead(channelAI)/ARDUINO_PRECISION*5.0); display.print("V"); display.display(); //##############################################расчет частоты if (FreqCount.available()) { count = FreqCount.read(); } if(digitalRead(2)==HIGH) // проверяем состояние кнопки { razv=razv+5; } if(digitalRead(3)==HIGH) // проверяем состояние кнопки { razv=razv-5; if(razv<0) // проверяем состояние кнопки { razv=0; } } delay(razv);//регулирует частоту выборки }Во первых не плохо бы ознакомится с этим http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Во вторых, вы не ответили почти ни на один вопрос.
В третих вы представляете, что делает выми приведённый скетч? На первый взгляд он рисует 4 линии и подписывает их значениями частоты из FreqCount.read(); и напряжения в произвольный момент времени. Судя по display.clearDisplay(); в начале цикла, каждый цикл идёт затирание предыдущей информации.
Из всех ваших обьяснений тики всё же не понятно, что вы хотите сделать на ардуине? Нарисовать такую же красивую картиночку как на телефоне? Вы вести число давления? Мне кажется, что решение вашей задачи надо делить на две части. Сначало получить данные, потом уже их отрисовывать. Что бы получить данные нужно в цикле, максимально быстро оцифровывать вход и сравнивать полученные значения. При нахождение пика запоминать его в массив и начинать снова искать пик. И так 35 раз. Затем остановиться. Усреднить полученные значения, если надо измерить частоту и вывести всё на экран. Вывод на экран очень медленная функция и если после каждого измерения вы будите его перерисовывать, то никогда не получите правильный результат, не сможите правильно найти максимумы.
Смысл в том что я хочу построить на ардуино датчик звукового давления который на экран будет выводить только значения в дБ и частоту. Ничего отрисовывать не надо. Да первая задача идет получение данных и их обработка. Эта задача на данный момент для меня не совсем посильна так как я являюсь новичком данного дела. "Что бы получить данные нужно в цикле, максимально быстро оцифровывать вход и сравнивать полученные значения. При нахождение пика запоминать его в массив и начинать снова искать пик. И так 35 раз. Затем остановиться. Усреднить полученные значения, если надо измерить частоту и вывести всё на экран." Это я и пытался объяснить. Я надеюсь на понимание так как чтение материалов сделало из головы кашу. Я могу осуществить данную задачу физически с помощью осцилографа и калькулятора. но мне интересен способ как это сделать программно. Вопрос по цитате что выделина выше, как правильно сделать так чтобы он находил все пики и осреднял их? Еще раз извиняюсь за возникшее недопонимание
Заводите пременные текущего и максимального значения, счетчики максимумов, массив максимумов http://arduino.ru/Reference/Array
В цикле http://arduino.ru/Reference/DoWhile или http://arduino.ru/Reference/For
читаете аналоговые данные с порта http://arduino.ru/Reference/AnalogRead
сравниваете полученное значение со старым http://arduino.ru/Reference/If
Если старое меньше нового старому присваиваете значение нового иначе http://arduino.ru/Reference/Else если новое меньше максимального на заданный вами интервал - значит нашли максимум - запоминаете его в массиве, прибавляем единицу в счетчик максимумов, если счетчик больше максимального значения - выходим из цикла http://arduino.ru/Reference/Break усредняем массив.
Измеряем частоту.
if (FreqCount.available()) { count = FreqCount.read(); }Выводим на экран.
... на экран будет выводить ... Ничего отрисовывать не надо.
Вы уж определитесь, нужно Вам что-то выводить на экран или нет.
Я могу осуществить данную задачу физически с помощью осцилографа и калькулятора. но мне интересен способ как это сделать программно.
Программно это делается абсолютно так же.
То есть Вам нужно:
1. Подробно по-русски описать, как бы Вы стали решать эту задачу с помощью осциллографа и калькулятора.
2. Заменить в тексте "осциллограф" на "АЦП".
3. Перевести текст с русского на Си.
данные - понятно. а частоту?