что не так с pulseIn() ?

Тема в разделе "Arduino & Shields", создана пользователем DrProg, 28 май 2015.

  1. DrProg

    DrProg Вечный нерд

    Потребовалось измерить длину импульса от моностабильной схемы на базе таймера 555. Казалось бы легкотня, запускаю:
    int v = pulseIn(6, HIGH);
    Приходит всякая случайная ерунда. Разные типы данных пробовал в т.ч. unsigned long, все равно получает на входе всякую чушь без какой бы то ни было системы. Менял схему подключения пина, тоже не помогает. Опять плюнул, написал такое:
    Код (Text):
    while (digitalRead(6) == LOW);
    v1 = millis();
    while (digitalRead(6) == HIGH);
    v2 = millis();
    Serial.println(v2-v1);
    Точность до миллисекунд меня устраивает. Стало работать отлично, длительность импульса выдает очень похожую на настоящую и стабильную плюс минус пара процентов. Что не так с pulseIn? Что я опять забыл подготовить?
     
  2. ИгорьК

    ИгорьК Оракул Модератор

    Вы забыли поразмышлять на тему тайминга этой функции. Об этом написано в мануале. Не исключаю, что прочитав его самостоятельно у Вас возникнут новые мысли. По крайней мере в этом посте Вы о нем не упомянули.
     
  3. DrProg

    DrProg Вечный нерд

    О каких таймингах применительно к pulseIn Вы говорите? В описании функции на сайте о них умалчивается. В примере тамошнем тоже не упоминаются, пример точно такой как я и сделал. Подскажете как надо было?
     
  4. ИгорьК

    ИгорьК Оракул Модератор

    1. Как работает функция? Вот так: " waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing". Причем, "The timing of this function has been determined empirically and will probably show errors in longer pulses. Works on pulses from 10 microseconds to 3 minutes in length."
    Кроме того, "the number of microseconds to wait for the pulse to start; default is one second".
    При несоблюдении этих ограничений, функция может бредить.
    Из Вашего поста не усматривается - учитывали или нет Вы написанное выше.
    2. Из примера на сайте Ардуино видно, что принимающая нога устанавливается на прием:
    pinMode(pin, INPUT);
    Вы также не указали это - иногда ошибки бывают самые тупые, по себе знаю.
    Причем, Вы используете функцию digitalRead(6) - по умолчанию ногу можно и не инициализировать, а вот что касается pulseIn() - фиг его знает.
    3. Для самопроверки неплохо бы поменять номер ноги, или вообще железо.

    Эти три вещи Вы не указали (или не сделали?), прежде чем размышлять на тему pulseIn() .
    По своему опыту скажу, что лестница, которая круглосуточно использует pulseIn() для чтения датчиков расстояния работает уже два года и не разу не баловалась, кроме случаев выхода этих датчиков из строя.
     
    DrProg нравится это.
  5. DrProg

    DrProg Вечный нерд

    Вот весь скеч:

    Код (Text):
    unsigned long v1 = 0;
    unsigned long v2 = 0;

    void setup() {
    pinMode(6, INPUT);
    Serial.begin(9600);
    }

    void loop() {
    //v1= pulseIn(6, HIGH);
    while (digitalRead(6) == LOW);
    v1 = millis();
    while (digitalRead(6) == HIGH);
    v2 = millis();
    Serial.println(v2-v1);

    Serial.println("----------");
    }
    Вроде бы ничего не забыл, но pulseIn выдает отсебятину.
     
  6. ИгорьК

    ИгорьК Оракул Модератор

    Вы вроде бы забыли поразмышлять на тему п. 1 и п.3 моего поста.
     
  7. DrProg

    DrProg Вечный нерд

    п. 3 сделано, менял пины. Более того, с этим же пином вариант с циклами работает.
     
  8. ИгорьК

    ИгорьК Оракул Модератор

    :) просто чувствую себя фашистом, истязающим партизана: ну, а что по пункту 1?
     
  9. DrProg

    DrProg Вечный нерд

    По первому пункту я вроде бы ответил в самом начале. Нет в этом описании явных указаний на какие либо подготовки к запуску функции, как это было с shifhIn например. Возможны ошибки при времени от 10мкс до 3 минут, но в этот диапазон я вписываюсь с многослойным запасом. Не вижу что не так.
     
  10. ИгорьК

    ИгорьК Оракул Модератор

    Ну, наконец, выяснены все детали. Ок, задача усложнилась, но не фатально.
    Давайте размышлять дальше.
    Ардуина вроде работает в целом правильно, но на одной обычной операции дает странные, на Ваш взгляд, результаты.
    А если предположить что эти результаты все таки правильные?
    Ну, например, Вы используете конструкцию while (digitalRead(6) == LOW);
    Как Вы считаете, она быстрее или медленнее отрабатывает старт измерения по сравнению с pulseIn(6, HIGH);?
    Что будет, если отработка Вашего решения занимает бОльшее время, чем pulseIn? С достаточно большой долей вероятности можно предположить, что источник, перед переходом из одного стабильного состояния в другое «сыплет» пачку импульсов или переход этот имеет какую-то зубастую картинку, которая ловится pulseIn но не распознается Вашим решеием. Есть мысли, как это хотя бы косвенно проверить без осциллографа? Простое размышление может подсказать ответ.
    А если есть осциллограф - тогда вообще просто.
     
    Последнее редактирование: 29 май 2015
  11. DrProg

    DrProg Вечный нерд

    Осциллографа нет. Сигнал идет с 555, по заверению авторов сигнал этот ровный без перепадов и дребезга, длительность зависит от конденсаторов и сопротивления обвязки. Один из вариантов использования этой схемы как раз таки подавление дребезга, то есть получение нуля на входе выливается в единицу на выходе четко определенной продолжительности. Замер проводится именно на выходе. Длительность его варьировалась от 0,1 до 20 сек, то есть достаточно много чтобы быть зафиксированной.
    pulseIn мало того что выдавал случайные числа, так еще и иногда срабатывал просто так с результатом 0, как будь то помехи идут какие то. Почему же эти помехи не видит digitalRead? У pulseIn выше чувствительность на той же ноге? Такое возможно?
     
  12. ИгорьК

    ИгорьК Оракул Модератор

    Чувствительность (как распознавание 1/0)у него не выше, а скорость,не исключаю, - выше. И дело не в digitalRead, скорее всего, а во времени перехода от вашего цикла торможения к нему. Так как же получить косвенное предположение о шуме? (хотя я из Вашего поста уже с достаточной степенью вероятности его вижу)
     
  13. DrProg

    DrProg Вечный нерд

    То есть считаете, что pulseIn отлавливает шумы невидимые для digitalRead за счет того, что более быстр? Возможно, но тогда откуда он берет огромные цифры импульса за доли секунды? А отрицательные числа откуда? А нулевые? От того что события происходят быстрее тех самых помянутых в инструкции 3мкс?
     
  14. Megakoteyka

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

    Покажите код с pulseIn и числа, которые он выдает.
     
  15. ИгорьК

    ИгорьК Оракул Модератор

    Откуда он берет нулевые - написано в мануале. И подтверждается тем что Вы иногда пытались измерять интервалы длиннее ... (какого значения)? Я же предлагал - читайте мануал! Про нолик там рассказано.
    Остальное с большой долей вероятности следствие двух вещей:
    - коротких импульсов;
    - ошибки в IDE, что все таки маловероятно, но может быть (особенно с учетом последних событий в Ардуино). IDE какая?
     
  16. ИгорьК

    ИгорьК Оракул Модератор

    Код вот, был раньше. Обратим внимание, что сигнал ловится с перехода 0 на 1, что повышает вероятность ловли коротких импульсов:
    Код (Text):
    void loop() {
    //v1= pulseIn(6, HIGH);
    while (digitalRead(6) == LOW);
    v1 = millis();
    while (digitalRead(6) == HIGH);
    v2 = millis();
    Serial.println(v2-v1);
     
  17. ИгорьК

    ИгорьК Оракул Модератор

  18. DrProg

    DrProg Вечный нерд

    IDE 1.6.5. Длиннее 3х минут измерять не пытался, самый длинный импульс секунд 25. Обычно данные появлялись после импульса и каждый раз очень разные. Что характерно, иногда результат выдавался и во время импульса. Со случаем менее 3 мкс согласен, наверное при этом и появлялся тот самый ноль, но остальные? Схема довольно простая, если есть время можете попробовать проверить, может быть у меня что то с платой не так?

    [​IMG]
     
  19. ИгорьК

    ИгорьК Оракул Модератор

    "the number of microseconds to wait for the pulse to start; default is one second". - Отсюда нули.

    Конденсаторы на питание. Бааааааааальшие!
    Ноль появляется не отсюда, см. выше. Ноль появляется тогда, когда pulseIn ждет смены сигнала больше одной секунды, установленной по умолчанию.
    Когда что-то происходит с длительностью менее 3 мкс - ардуина выдает бред.

    Но если pulseIn ловит что-то на не сменяющемся сигнале, и особенно когда он ноль, то это говорит о сильных наводках.
     
  20. ИгорьК

    ИгорьК Оракул Модератор

    Схема видимо из мануалов и вполне рабочая. И плата рабочая. И puliseIn работает нормально.
    И если бы Вы эту схему использовали как подавление дребезга кнопки - все тоже работало бы. Можете проверить.
    Ведь схема не превращает сигнал в идеальный, это не возможно в принципе. Она лишь уменьшает этот дребезг (точнее - полностью подавляет дребезг кнопки, но добавляет свой) до такого такого значения, когда алгоритмы обработки кнопки не успевают его заметить.