Сенсор вибрации и не только

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Rudium, 23 июн 2014.

  1. Rudium

    Rudium Нуб

    Приветствую!
    Предыстория: Я работаю инженером-конструктором, а по образованию инженер-механик. Следовательно с программированием и электроникой знаком слабо. Начальство поставило задачу: перед продажей устройства (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. Если связь можно получить экспериментально, то нужно устройство у которого мы точно знаем частоту. Что можно использовать в качестве этого устройства? Тогда мы получим значения колебаний в вольтах этого устройства и зная его частоту получим переводной коэффициент.
     

    Вложения:

    Последнее редактирование: 23 июн 2014
  2. ANV

    ANV Гуру

    1. Чтобы понять что это, надо иметь исходный код. Это могут быть как сырые значения АЦП, так и частота. Откуда мы знаем что там программист наделал?
    2. Нет, и не будет. Напряжение на выходе будет больше зависеть от амплитуды колебаний, нежели от частоты.
    3. Никак
    4. Вам не нужны эти игрища. Просто используйте датчик как измеритель частоты, а не амплитуды

    Первое что нужно Вам понять - это устройство с метрологическими амбициями (тогда полный перечень) или только для того, чтобы шеф мог сказать "какие претензии, вот все работает".

    И еще:
    Какая все-таки частота? Вы говорите про 200Гц, в описании килогерцы
     
  3. Rudium

    Rudium Нуб

    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 кГц).
     
    Последнее редактирование: 23 июн 2014
  4. ANV

    ANV Гуру

    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 и постройте график.

    Да, это все работает если пьезодатчик не имеет у себя конденсаторов. Так что приложите фото платы датчика.
     
  5. ANV

    ANV Гуру

    Еще вариант - подключить датчик к счетному входу и измерить таймером/счетчиком частоту.
     
  6. Rudium

    Rudium Нуб

    ANV
    Фото платы с датчиком прикрепить не получается http://uploads.ru/9fF86.jpg. Конденсатора не вижу :)
    Программисту отдал на доработку код.
     
    Последнее редактирование: 23 июн 2014
  7. acos

    acos Официальный гик Администратор

    Давайте так.
    Частота нужна 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;
    }
     
    Далее можно задуматься о возможности обработки значений прямо "на борту", подключив несложную математику. Например, запоминать номер измерения и искать экстремумы, потом вычислять по ним время периода. Таким образом можно было бы слать в последовательный порт только частоту. А там и до построения зависимости амплитуды колебаний от напряжения недалеко (хотя бы по сравнению с "эталоном" из парижской палаты мер и весов). В общем, вашему программисту есть чем заняться)
     
    Последнее редактирование: 24 июн 2014
  8. ANV

    ANV Гуру

    Если амплитуда сигнала больше чем Vih, то можно использовать Compare/capture/pwm модуль (так он называется в PIC контроллерах), т.е. подключить датчик к счетному входу и по таймеру смотреть сколько фронтов пришло за период измерения.

    А по-хорошему надо сначала глянуть осциллографом что там с датчика, а потом фантазировать насчет обработки :)
     
    Unixon нравится это.
  9. acos

    acos Официальный гик Администратор

    Я не спорю, но с этим кодом хотя бы можно начать работать) Если нет под рукой осциллографа (строго говоря для таких частот он точно есть - звуковая карта компьютера хотя бы) то можно проверить мои допуски вот так
    Код (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?
     
  10. ANV

    ANV Гуру

    Минимальное входное напряжение, которое клнтроллер считает за логическую единицу
     
  11. Unixon

    Unixon Оракул Модератор

    "Сенсор вибрации" с витрины - обычный пьезоэлектрический динамик, используемый в качестве датчика, выдает соответственно вольты как производную по времени от давления, с учетом собственных частотных свойств. Если нужно посчитать частоту - после датчика ставится развязка по переменке и притяжка к Vref=Vcc/2, потом на компаратор сравниваться с опорным Vref, потом на счетный вход таймера в МК.