Приветствую! Предыстория: Я работаю инженером-конструктором, а по образованию инженер-механик. Следовательно с программированием и электроникой знаком слабо. Начальство поставило задачу: перед продажей устройства (http://www.vseinstrumenti.ru/stroit...ehnika/vibratory/wacker_neuson/iren_30__8958/) проверять его параметры (частота вибраций, амплитуда колебаний и т.д.) чтобы отсеивать бракованные изделия. Частота колебаний глубинного вибратора около 200 Гц. Что имеем: 1. Плата Arudino Uno http://amperka.ru/collection/boards/product/arduino-uno 2. Плата расширения Troyka Shield http://amperka.ru/product/arduino-troyka-shield 3. Сенсор вибрации с пьезодиском http://amperka.ru/collection/sensors/product/piezo-vibration-sensor 4. Программы (написанные программистом) для калибровки и снятия показаний с датчика. 5. Датчик прикрепили (с помощью изоленты) непосредственно к устройству и получили значения (файл прикрепил). Вопросы: 1. Правильно ли я понимаю, что полученные значения - это Вольты? 2. Есть ли график связи Вольт-Герц для используемого датчика? 3. Если нет, то, как я понимаю, связь можно получить экспериментально? 4. Если связь можно получить экспериментально, то нужно устройство у которого мы точно знаем частоту. Что можно использовать в качестве этого устройства? Тогда мы получим значения колебаний в вольтах этого устройства и зная его частоту получим переводной коэффициент.
1. Чтобы понять что это, надо иметь исходный код. Это могут быть как сырые значения АЦП, так и частота. Откуда мы знаем что там программист наделал? 2. Нет, и не будет. Напряжение на выходе будет больше зависеть от амплитуды колебаний, нежели от частоты. 3. Никак 4. Вам не нужны эти игрища. Просто используйте датчик как измеритель частоты, а не амплитуды Первое что нужно Вам понять - это устройство с метрологическими амбициями (тогда полный перечень) или только для того, чтобы шеф мог сказать "какие претензии, вот все работает". И еще: Какая все-таки частота? Вы говорите про 200Гц, в описании килогерцы
ANV Пока нужно только знать вибрацию. В дальнейшем нужна будет амплитуда, сила тока, вольтаж и т.д. Есть трехосный акселерометр http://amperka.ru/collection/sensors/product/triple-axis-accelerometer. Про это пока можно забыть. - так хорошо бы знать, в чем датчик выдает цифры. Если в вольтах, то придется вывести зависимость, если в Герцах, то вопрос сам отпадает и я иду дальше. Вот сам код: int z; // Калибровка датчика int val = 0; void setup() { Serial.begin(9600); } void loop() { // Значения осей с датчика z = analogRead(A3)- val; // Выводв Serial monitor Serial.println(z); //Период опроса delay(1); } По поводу частоты: http://www.wacker-russia.ru/product...al-vibrator/high-frequency-vibrators/iren-30/ (да и по моей первой ссылке я не увидел 200 кГц).
1. Не надо делать сначала одно, потом остальное добавлять. Получится костыль на костыле. 2. Определитесь с параметрами измеряемых характеристик: максимальная частота, амплитуда и пр. 3. Определитесь с метрологией, т.е. с методикой измерения и повторяемостью результатов. Это минимум с чем Вам надо определиться перед тем, как покупать все датчики подряд. Из всего этого будет следовать какие датчики Вам нужны и как их подключать. Перечень решений варьируется от "Ардуино с датчиком", до измерительных комплексов, например ноутбук с USB-АЦП модулем. Теперь конкретно по Вашему коду. Он измеряет амплитуду сигнала и отсылает ее в СОМ-порт. Делая этим способом частоту можно получить ознакомившись с теоремой Котельникова, которая в "гуманитарном" виде (этот термин тут не чтобы Вас обидеть, а чтобы гуру ЦОС меня не съели, если они тут есть) звучит так: чтобы оцифровать сигнал надо иметь частоту семплирования как минимум в 2 раза выше, чем частота сигнала. Это означает, что если частота сигнала 200Гц, то analogRead должен быть как минимум 400 раз в секунду. Более того, частота оцифровки должна быть постоянной, а в этом коде она переменная из-за недетерминированного времени выполнения команды Serial.println(z). Эта команда отсылает от 3 байт (код "0" + CR+ LF) до 6 (четырехзначное число + CR+LF). Чтобы в данный момент получить хоть какой-то результат, надо сделать следующее: 1. Повысить скорость до 115200 2. Сделать форматированый вывод в serial, чтобы числа передавались с одинаковым количеством символов, т.е. чтобы "15" передавалось как "015", а "3" как "оо3". Это даст постоянную частоту семплирования. 3. Все это в совокупности даст частоту семплирования 115200/11/5 ~ 2000 оцифровок в секунду. 4. Прислоните пьезодатчик к гитаре, запустите монитор СОМ-порта и возьмите что-нибудь из первых трех струн 5. Полученные данные сохраните в текстовый файл, переименуйте его с CSV, загрузите в Excel и постройте график. Да, это все работает если пьезодатчик не имеет у себя конденсаторов. Так что приложите фото платы датчика.
ANV Фото платы с датчиком прикрепить не получается http://uploads.ru/9fF86.jpg. Конденсатора не вижу Программисту отдал на доработку код.
Давайте так. Частота нужна 200 Гц или 200 кГц? Надеюсь, что всё-таки 200 Гц, буду из этого исходить. ANV конечно прав, чтобы понять - что же такое у вас нарисовалось нужно измерять четко в один и тот же промежуток времени. И очень желательно, чтобы частота измерений была как минимум в два раза больше максимально "интересной" нам частоты. Допустим, что верхний предел "Интересности" для нас - 1000 Гц. Тогда мы можем взять частоту сэмплирования - 2000 Гц Текущая версия здесь https://github.com/acosinwork/arduino_projects/blob/new/Rudium/Rudium.ino библиотека TimerOne http://playground.arduino.cc/Code/Timer1 Код (Text): #include <TimerOne.h> #define SAMPLE_RATE 2000 // частота дискретизации #define MICROSECONDS 1000000 // микросекунд в секунде #define SAMPLE_PERIOD MICROSECONDS/SAMPLE_RATE //период измерения равен вот этому #define FREQ_SENSOR_PIN A0 // или другое.. boolean volatile timeToReadValue = false; // эту переменную берём только из RAM void setup() { Timer1.initialize(SAMPLE_PERIOD); //Взводим таймер на срабатывание через каждый период дискретизации Timer1.attachInterrupt( timerIsr ); //эта функция будет вызываться SAMPLE_RATE раз в секунду Serial.begin(115200); //шустренько шоб } void loop() { // тут у нас код, который будут прерывать прерывания // if (timeToReadValue) // Если пора считать значение { Serial.println(analogRead(FREQ_SENSOR_PIN)); //будем надеяться, что это быстрее чем timerIsr() } } /// -------------------------- /// Custom ISR Timer Routine /// -------------------------- void timerIsr() { // измеряем напряженье. // Запомните, это очень, очень плохо измерять напряжение в Ардуино // в прерываниях. Так делать просто нельзя! // Потому что в прерываниях нельзя делат длительные операции // да ещё и с вложенными прерываниями - а они тут... ой. // Мы сделаем по другому // Будем просто оповещать о прерывании и надеяться на чудо timeToReadValue = true; } Далее можно задуматься о возможности обработки значений прямо "на борту", подключив несложную математику. Например, запоминать номер измерения и искать экстремумы, потом вычислять по ним время периода. Таким образом можно было бы слать в последовательный порт только частоту. А там и до построения зависимости амплитуды колебаний от напряжения недалеко (хотя бы по сравнению с "эталоном" из парижской палаты мер и весов). В общем, вашему программисту есть чем заняться)
Если амплитуда сигнала больше чем Vih, то можно использовать Compare/capture/pwm модуль (так он называется в PIC контроллерах), т.е. подключить датчик к счетному входу и по таймеру смотреть сколько фронтов пришло за период измерения. А по-хорошему надо сначала глянуть осциллографом что там с датчика, а потом фантазировать насчет обработки
Я не спорю, но с этим кодом хотя бы можно начать работать) Если нет под рукой осциллографа (строго говоря для таких частот он точно есть - звуковая карта компьютера хотя бы) то можно проверить мои допуски вот так Код (Text): #include <TimerOne.h> #define SAMPLE_RATE 2000 // частота дискретизации #define MICROSECONDS 1000000 // микросекунд в секунде #define SAMPLE_PERIOD MICROSECONDS/SAMPLE_RATE //период измерения равен вот этому #define FREQ_SENSOR_PIN A3 // или другое.. boolean volatile timeToReadValue = false; // эту переменную берём только из RAM unsigned long volatile interruptCounter = 0; //Счётчик прерываний - каждое значение учтём void setup() { Timer1.initialize(SAMPLE_PERIOD); //Взводим таймер на срабатывание через каждый период дискретизации Timer1.attachInterrupt( timerIsr ); //эта функция будет вызываться SAMPLE_RATE раз в секунду Serial.begin(115200); //шустренько шоб } void loop() { // тут у нас код, который будут прерывать прерывания // if (timeToReadValue) // Если пора считать значение { Serial.print(interruptCounter); Serial.print(" - "); Serial.println(analogRead(FREQ_SENSOR_PIN)); //будем надеяться, что это быстрее чем timerIsr() } } /// -------------------------- /// Custom ISR Timer Routine /// -------------------------- void timerIsr() { // измеряем напряженье. // Запомните, это очень, очень плохо измерять напряжение в Ардуино // в прерываниях. Так делать просто нельзя! // Потому что в прерываниях нельзя делат длительные операции // да ещё и с вложенными прерываниями - а они тут... ой. // Мы сделаем по другому // Будем просто оповещать о прерывании и надеяться на чудо timeToReadValue = true; ++interruptCounter; // номер прерывания увеличился } если interruptCounter будут приходить без пропусков чисел - то допущения верны. Что конкретно вы имеете ввиду под Vih?
"Сенсор вибрации" с витрины - обычный пьезоэлектрический динамик, используемый в качестве датчика, выдает соответственно вольты как производную по времени от давления, с учетом собственных частотных свойств. Если нужно посчитать частоту - после датчика ставится развязка по переменке и притяжка к Vref=Vcc/2, потом на компаратор сравниваться с опорным Vref, потом на счетный вход таймера в МК.