Ардуино 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. Отсюда странное поведение. Думаю, что она должна как-то меняться внутри условия (при срабатывании), но это Вам виднее т.к. я не знаю чего Вы хотите достичь.
Источник
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 и более пешеходов, то датчик переводит светофор в режим мигания зеленым (меняет состояние автомата «светофор») сразу после срабатывания. И сам переходит в состояние «выключен» и затем в состояние «ожидание включения».
Автомат шлакбаум или «закрыть» или «открыть» или «без изменений». Всего три состояния. Управляется извне, другими автоматами.
.. вот, берем это «ТЗ» и тупо пишем таблицы состояний, функции исполнения состояния и .. а всё. Остальное уже есть готовое. 🙂
Как показала практика — одного трехчасового занятия (при начальном знании языка) вполне достаточно для написания, освоения и даже на поиграть время остается навалом. Сейчас пробую при ПОЛНОМ незнании языка дать одновременно с языком. Правда только «С» версию .. сложнее, уже третье занятие пойдет на выходных. Но, тоже проблемы больше не в конечных автоматах, а в правилах самого языка, которые приходится давать постепенно в два-три захода, начиная с «тут пишем волшебное слово..», потом «да, и тут и вообще везде оно пишется так..» и только потом «это — синтаксическое правило ..». 🙂
Источник