Ардуино millis не работает

Ардуино millis не работает

Chadin

Привет. Помогите понят, почему счетчик millis работает не стабильно? Почему-то отрабатывает только в первый раз а потом на 2-4 секунды меньше и каждый раз по разному.

#define key_pin 3 //подключение кнопки
#define led_pin 10 // подключение лампочки
#define led_time 6000 // время свечения
boolean led_flag, key_status;
unsigned long last_time_led ;

void setup() <
pinMode (key_pin, INPUT_PULLUP);
pinMode (led_pin, OUTPUT);

void loop() <
digitalWrite (led_pin, led_flag);
key_status = digitalRead (key_pin);
key_status = !key_status;
if (key_status == 1 ) <
led_flag = 1;
>

Arhat109

1. Код удобней оформлять при выкладке как-то так, тут есть спец. кнопка. Читать «поток сознания» не очень удобно и не каждый просто заглянет в него..

Далее. Не инициализированные переменные last_time_led, led_flag используются раньше чем им присваивается значение, то есть «что попало». Тут Вам конкретно повезло, т.к. Ардуино заполняет их нулями самостоятельно перед запуском программы, вместо «ученика».. проект-то учебный!

Строки 17-21 сработают «несколько раз» при нажатии кнопки, полезный результат будет в последнем разе срабатывания, а вот условие в строке 23 сработает (если кончился интервал) только первый раз. В целом, это приведет к нарушению длительности не более чем время дребезга кнопки. Но, если контакт фиговый и держать его 1-3сек .. то он столько и даст в нарушениях интервалов.

Интересно тут то, что изначально переменная led_flag равна нулю. То есть условие строки 23 не сработает ни разу до нажатия кнопки.. отсюда — вся проблема в величине дребезга, кмк.

Ну и ещё. Предпочитаю не запоминать приоритеты, а сложные условия по &&, || обрамлять скобками. Кмк, так и наглядней и надежней.

Источник

Arduino.ru

Глюки функции Millis()

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Коллеги, в казалось бы простом скетче где-то закралась странная ошибка.

Суть скетча в упрощенном варианте:

1. зажали концевик,

2. выполнили некую работу,

3. отпустили концевик,

4. подождали 1,5 секунды,

5. вывели результат.

И вроде все по коду замечательно, но временами функция millis() возвращает некорректные значения.

Вот пример работы сего скетча 🙁

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Автора не смущает тот факт, что previousMillis время от времени обнуляется в скетче (строка 68), затем — получается currentMillis (строка 39), затем — заполняется previousMillis (строка 53)? При таком подходе вполне вероятен сценарий, когда previousMillis будет больше currentMillis. Это так — что заметил навскидку.

Зачем вообще обнулять previousMillis — не пойму. Эти испуги с переходом через ноль и якобы неправильным подсчётом промежутков связаны лишь с тем, что люди не знакомы с беззнаковой арифметикой. Те, кто знает — не парятся 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ну почему же неправильно, всё правильно, давай проанализируем код:

1. Строка 39, фиксируем текущий millis в currentMillis, это «0», точка отсчета, дальше время будет увеличиваться. Запомним это.

2. Строка 53, фиксируем текущий millis в previousMillis, при этом миллис уже укатился вперед, тем более там два вывода в Сериал, короче миллис стал чуть больше, чем был в 39 строке.

3. Строка 61, закономерный результат, currentMillis меньше, чем previousMillis.

Разумеется это происходит не каждый раз, потому что нужно чтобы карты сложились и это может происходить, например, когда идет дребезг концевика. Можешь сказать, что этого нет, потому что по монитору этого не видно, так тут везде еще есть вывод в Сериал, а это не мало по времени выполнения.

Для начала, попробуй в 53 строке присваивать не millis, а currentMillis, ситуация немного измениться, во всяком случае такого уже не будет, но будет что-нибуль другое. Но это совсем другая история.

Источник

Arduino.ru

millis() зависает

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Подскажите, пожалуйста, в какую сторону копать!

Вот этот кусок кода отлично работает, если поставить 10, 20, 30 секунд в условии. Но если ставим 40 секунд или больше, то во первых условие не срабатывает, а во вторых программа как бы подвешивается. И чтобы она заработала снова, нужно пару раз похлопать в ладоши, активизируя соответствующее условие двойного хлопка.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Комментарии писались для введения противника в заблуждение? Похоже на то.

Тут у Вас много чего намешано и кроме того условия. Давайте с начала.

Итак. самое начало времён. датчик движения пока ещё не сработал. Проверка в строке 28 даёт ложь (кстати, почему 1, а не HIGH?) и управление получает else-участок — строки 35-38. Здесь протсходит сравнение

Но ведь timeoff пока ещё не получила НИКАКОГО значения! Результат операции непредсказуем. Можно, конечно, предположить, что после перезагрузки МК там 0, но . так не делается.

Теперь про Ваше «зависание».

Переменная globaltimeout получает значение в setup, а потом только при двойном хлопке. Это означает, что если условие в строке 59 единожды сработало, оно будет продолжать срабатывать в каждом такте пока не появится двойной хлопок, т.е. пока не поменяется переменная globaltimeout. Отсюда странное поведение. Думаю, что она должна как-то меняться внутри условия (при срабатывании), но это Вам виднее т.к. я не знаю чего Вы хотите достичь.

Читайте также:  Как перезагрузить айфон 12 про если сенсор не работает

Источник

Arduino.ru

Проблема в millis ()

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

значение переменной FlagPoliva почему то всегда = 1

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

никогда такого не было, и вот — снова. О_О

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ваша версия: почему он не должен быть всегда = 1?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Думаю что переменная должна изменится на 1 только по истечении 10 сек

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Она так и делает. Я проверил даже.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

а у вас в строке 20 условие выполняется?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

может чего-то где-то не обнуляется?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

У меня не меняется и она постояно = 1

Суть такова что надо включить на 10 сек светодиод в 15 часов и больше не включать

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

и еще могу подсказать, что millis() начинает считать с момента старта МК

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

У меня не меняется и она постояно = 1

Через 10 сек. после старта она меняет значение с 0 на 1. Вставьте digitalWrite(13, FlagPoliva); после Serial.println(FlagPoliva); и убедитесь сами — всё работает ровно так, как написано в скетче.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

sadman41, обратите внимание на строку 17

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

sadman41, обратите внимание на строку 17

Всё нормально, там имеется квалификатор static — значение не теряется при выходе из loop.

Суть тут не в миллисах, а в том, что ТС хочет одно, а в скетче пишет совсем другое. Потом сидит и ждет, пока ардуина угадает его потребности.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

проблема в том что оно =0

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Нет,даже при строчки digitalWrite(13, FlagPoliva); свеодиод после старта горит постоянно

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

может все-таки не обнуляется чего-то?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

проблема в том что оно =0

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

А зачем указана такая строчка №6? Что хотели-то? 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Переменная для примера

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

на ладно. Поставим вопрос по-другому: с какого будуна Вы ожидаете, что эта Ваша FlagPoliva опять станет равной нулю?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Я и не ожидаю от неё нуля,это не возможно,проблема заключается в другом

После старта программы она должна 10 сек быть = 0,а после уже принимать значение 1,а она уже после старта программы = 1 !

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Я и не ожидаю от неё нуля,это не возможно,проблема заключается в другом

После старта программы она должна 10 сек быть = 0,а после уже принимать значение 1,а она уже после старта программы = 1 !

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Может видео снимете, как она сразу же в 1 перекидывается? Так, как у меня она упрямо = 0 в течении 10 сек.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

для отладки — пусть ТС установит интервал не в 10 секунд, а 1000

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Выложите скрин начала вывода в монитор, чтобы убедиться что она сразу равна 1.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Это и есть самое начало вывода в монитор

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Значит тот скетч, что тут опубликован отличается от того, который Вы гоняете. Здесь нет такой проблемы о которой Вы пишете.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Сейчас видео сниму

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Это и есть самое начало вывода в монитор

где-то ты нас обманываешь — как минимум, первая строка вывода должна быть со значением 0

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Вот это выведет на чистую воду:

Serial .print(millis()); Serial .print(» => «); Serial .println(FlagPoliva);

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Почему у меня «не так»? Может Вам стоит в мониторе отключить «автопрокрутку» и сместиться на настоящее начало вывода? 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Очень плохо видно, но можно разглядеть что на вашем видео поначалу тоже идут нули и только потом 1-ки. Похоже что ваш буфер монитора не сохраняет начало вывода.

Попробуйте добавить в setup() типа такое:

И отмотайте до этого сообщения вывод в мониторе, что видно первым выводом?

Источник

Arduino.ru

Непонятная работа millis()

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Вообще-то не уверен, в программировании или в железе спрашивать надо. Простите, если что.

Читайте также:  Айфон задняя кнопка как настроить

Значит, с delay() наигрался, сел изучать millis(). Накатал первый скетч:

Открываю монитор порта и вижу вот такое:

Ну и, собственно, это что? Китайская железяка так себя ведет, или это секретная фишка такая?

Заранее спасибо за ответы.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ну и, собственно, это что? Китайская железяка так себя ведет, или это секретная фишка такая?

обычное дело — китайцы миллис палёный прошили в контроллер.

рекомендую пользоваться российскими контроллерами — там всё по ГОСТу. О_О

* int currenttime = millis();

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Угу. millis() он большой в маленький холодильник int не помещается. Нужен большой двухкамерный unsigned long .

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Угу. millis() он большой в маленький холодильник int не помещается.

если свернуть в рулон, то помешается и в bool

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Угу. millis() он большой в маленький холодильник int не помещается. Нужен большой двухкамерный unsigned long .

Ну между прочим в моем крутом коде натурально unsigned long 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ну между прочим в моем крутом коде натурально unsigned long 🙂

В одном месте. А во втором — int. Код у тебя не крутой, а так — в мешочек 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

А. Понял. Спасибо 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ну между прочим в моем крутом коде натурально unsigned long 🙂

вместо выепываться — перечитал бы свой код: int currenttime = millis();

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Все, все, не пинайте сильно 😀 Спасибо!

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Какое спасибо! А где вопрос про переполнение и борьбу с ним?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

и, вдогонку — вот это nextmove=currenttime + timeout; не переживёт переполнения миллис.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Покурил, спасибо 🙂 Заодно и эту http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis, правда, не уверен, что все правильно понял, но что сложение — это плохо, уже, буду надеяться, усвоил 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Добрый совет — никогда так не говорите. Хотите задать вопрос — задавайте, но никогда не высказывайтесь столь пренебрежительно — выглядите не очень умно.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Кстати, раз уж Вы поняли про переполнение, чего не исправили свой код? Или исправили, просто сюда не выложили?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Исправил, да. Думал, чего ж людям голову морочить. В общем, задача у меня вполне конкретная (и, собственно, вряд ли я буду в тему ардуино дальше вгрызаться, пока/если не появится новое непреодолимое желание 🙂 ) — организовать подсветку в пруду на даче. Должны быть две группы по два RGB-прожектора, которые бы тупо переливались в классическом порядке перебора цветов (красный-оранжевый-желтый-зеленый-голубой-синий-фиолетовый-белый) с разной скоростью (на одной группе — медленно, на другой — очень медленно, фонари не должны притягивать взгляд динамикой вот этого перелива, но цвет таки должен меняться). В идеале было бы круто, если бы скорость можно было менять с радиопульта, но можно и обойтись.

Стандартными средствами (в смысле купленными на али фонарями и контроллером с управлением по радиоканалу) у меня это сделать так и не получилось — на самом деле проект этот тянется уже вот третий сезон. Фонари ip68 протекли :), контроллер глючит, сбиваясь без всякой системы с заданной программы на что-то свое. Фонари переделал, залил эпоксидкой, уж не протекут точно, правда, долговечность их пока неясна. Теперь вот взялся за контроллер 🙂

На данный момент сумел сделать управление ШИМ через millis() на один канал, правда, цикл выглядит по-дурацки, но я пока millis() же ковырял 🙂 Странная формула для PWM — c Вашей же, ЕвгенийП, подсказки, постарался осмыслить статью про нелинейную регулировку яркости http://radiolaba.ru/polezno-znat/regulirovka-yarkosti-svetodioda.html. Работает нормально, но значения ШИМ меньше 1, как выяснилось, к включению светодиода не приводят, поэтому там диапазон ограничен 16-100.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Задача решается в лет с помощью цифрового автомата. Но надо знать основы программирования, которые даже не синтаксис языка.

В следующей жизни, наверное 🙂 Но, с другой стороны, если у меня получится код допилить до нужного состояния, то на выходе ведь и получится цифровой автомат?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Не , не получится . Это как решение квадратного уровнения. Вроде просто. Но этому надо научиться. А вы «решение крадратного уровнения подбираете на ощуп с некоторой погрешностью»(разумеется это аналогия).

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Да, примерно так все и происходит. Но пока что есть ощущение, что прикладную задачу решить рано или поздно получится. Посмотрим, может, оно пройдет в процессе 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Позволю себе предложить Вам следующие простые правки :

Кстати, Вы уверены, что 16 и 100 выдавать не надо ?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Читайте также:  Киа селтос навигатор как настроить

и, вдогонку — вот это nextmove=currenttime + timeout; не переживёт переполнения миллис.

При беглом взгляде прочиталась купи пример.
Подумал: уже миллис на продажу выставили.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

GarryC, спасибо большое, мне только это осознать надо будет на досуге 🙂

С первого взгляда вот это не понял:

Это просто бесконечный цикл?

Насчет 16 и 100 — я думал, что они будут как раз выдаваться последней итерацией в цикле?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

GarryC, спасибо за подсказку и изящное решение. Я, надо сказать, добился того же результата, но по сравнению с Вашим циклом совершенно трансанально 🙂 Единственное что, если i объявлять равным 16, то вот тут » if ((i==99) || (i==17)) di=0-di;» тоже надо » if ((i==99) || (i==16)) di=0-di;», иначе цикл на втором шаге сбивается и начинает творить полную хрень.

Попробовал таки объявить переменные как паблики и убрать цикл — хуже, вроде бы, не стало 🙂

Получилось вот так:

Еще раз спасибо! Дальше буду RGB пилить.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

22 unsigned long currenttime1 = millis();
23 unsigned long currenttime2 = millis();

Может одним обойдетесь.

А это правильно.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

qwone, ну да. Наверно, обойдусь 🙂 Спасибо.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Может одним обойдетесь.

Ничо-ничо! Запас он карман не тянет! 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Ну тогда еще в карман

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

qwone, спасибо. Это меня надолго заткнет 🙂

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Пух, привыкай использовать enum правильно, пора.

обращаться потом, кашеш, сложнее:

enumColor color = enumColor::Green;

зато имена внутри enum-ов наружу не светят и не пересекаются с глобальными именами.

А просто enum имеет смысл применять только когда нужны именованные константы.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Нашел откуда взялась такая странная вещественная арифметика для ШИМ. Там даже в статье сказано верно: заранее рассчитанные таблицы заполнения ШИМ. Округлите ШИМ до целого и сложите в программную память 1 раз для всех светодиодов. Оно ещё и места меньше займет и куда как ползеней будет.

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

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Arhat109-2, рассказ про цифровой автомат это самое важное ,что вы можете и должны объяснить детям.Но надо именно для и под Ардуину.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Форум слегка вырос, что несомненно радует. Когда я тут два года назад между путешествием на пляж заяснял что такое конченный автомат и как его можно обобщенно реализовать для управления МК — меня тут многие, что теперь «гуру» поднимали насмех от непонимания вопросу. Спасибо, повеселили. Это первое что им дается ещё с «вумным светофором» и без delay().

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Arhat109-2, а еще лучше научить детишек не «засирать» loop() «грязью». А всю грязь выносить в отдельные функции. Так же делать с setup()

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

В конечном варианте там и нет ничего кроме набора исполнителей конечных автоматов, типа так:

Собственно это и есть весь луп. 🙂 Все остальное прописывается в таблицах состояний и функций переходов.

Там тоже все строго по задаче:

«Светофор переключает «красный», «Желтый» и «Зеленый» сигналы по времени и по порядку. При этом, Зеленый перед выключением мигает 3 раза. Состояния светофора для авто: «красный-вкл» — 30сек, «желтый вкл» — 2сек, «зеленый вкл» — 30сек, макро «мигалка»: («зеленый выкл» — 0.5сек, «зеленый вкл» — 0.5сек) х 2 раза. При включенном одном цвете остальные — выключены. Состояние «Желтый» переводит автомат «датчик пешеходов» в состояние счет, если тот был в состоянии «ожидание включения». Состояние светофора «красный» — опускает шлакбаум. состояние светофора «зеленый» поднимает шлакбаум.

Датчик пешеходов имеет состояния: «Выключен» — 45сек, «Ожидание включения» — без ограничения времени, «Счет». Если в состоянии «счет», к светофору скопилось 5 и более пешеходов, то датчик переводит светофор в режим мигания зеленым (меняет состояние автомата «светофор») сразу после срабатывания. И сам переходит в состояние «выключен» и затем в состояние «ожидание включения».

Автомат шлакбаум или «закрыть» или «открыть» или «без изменений». Всего три состояния. Управляется извне, другими автоматами.

.. вот, берем это «ТЗ» и тупо пишем таблицы состояний, функции исполнения состояния и .. а всё. Остальное уже есть готовое. 🙂

Как показала практика — одного трехчасового занятия (при начальном знании языка) вполне достаточно для написания, освоения и даже на поиграть время остается навалом. Сейчас пробую при ПОЛНОМ незнании языка дать одновременно с языком. Правда только «С» версию .. сложнее, уже третье занятие пойдет на выходных. Но, тоже проблемы больше не в конечных автоматах, а в правилах самого языка, которые приходится давать постепенно в два-три захода, начиная с «тут пишем волшебное слово..», потом «да, и тут и вообще везде оно пишется так..» и только потом «это — синтаксическое правило ..». 🙂

Источник

Оцените статью