millis () не стабильно работает
- Войдите на сайт для отправки комментариев
На пины ... повешены светодиоды, которые управляются через входящий шим (с RC- приемника).
По условию, светодиоды должны загораться: второй с небольшой (1с) задержкой относительно первого. И гореть оба постоянно. Когда условие перестает быть верным (команда с пульта пропадает), оба светодиода гаснут.
При следующем включении всё повторяется, только светодиоды меняются в очерёдности зажигания. Реализовал это с помощью переменных.
Со сменой очередности - вроде все в порядке. Но вот задержка не всегда срабатывает: при включении команды -загораются оба диода сразу (как будто задержки нет). При повторном включении - уже по очереди. Далее если чуть -чуть подождеть - снова буду оба включаться. Работают как надо только при быстрых переключения, в общем.
Делал с помощью millis (), поэтому грешу на нее. Может ли это быть из-за кривых внутренних часов? Или всей платы кривой и китайской? Или millis () с платой не виноваты?
С переменными как только уже не игрался - результат один. При выполнении условия задержки пробовал присваивать значение миллис - еще одной переменной, чтобы по ней высчитывать интервал времени, но в итоге пришел к тому же результату: светодиоды в большинстве случаев включаются одновременно, и только при быстры переключениях - с должной задержкой.
#define tataPin 10 // Пуск, соединяется с приемником #define switPin 11 // Переключение пуска, соед с приемником /////////////////////////////Пины пуска \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #define AirsoftPin1 7 #define AirsoftPin2 12 long previousMillisTata = 0; // храним время последнего переключения (Эйрсофт) long interval_asinc = 1000; // интервал между включением первого и второго привода int gun1 = LOW; // Переменная первого привода int gun2 = LOW; //Переменная второго привода int tata = 0; // Переменная первого эйрсофт (для обсчета) int swit = 0; // переменная переключателя (Эйрсофт/Ракеты) (для обсчета) void setup() { pinMode (tataPin, INPUT); //Входной пин управление приводом pinMode (switPin, INPUT); //Входной пин переключение между 2-мя приводами pinMode (AirsoftPin1, OUTPUT); //Выход привод 1 pinMode (AirsoftPin2, OUTPUT); //Выход привод 2 } void loop() { { tata = pulseIn (tataPin, HIGH, 37880); //Обсчет входящего ШИМ swit = pulseIn(switPin, HIGH, 37880); //Обсчет входящего ШИМ } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Блок управления Эйрсофт!!!!!!!!!!!!!!!!!!!!!!!! static int asinc = 0; // Переменная асинхронности приводов static int por = 0; // Переменная порядка начала работы приводов digitalWrite(AirsoftPin1, gun1); // Значение переменной выводим на нужный пин digitalWrite(AirsoftPin2, gun2); // Сначавса начинает AirsoftPin1!!!!!!!!!!!!!!!!!!! if ((tata > 1200)&& (swit<1500) && gun1 == LOW && por==0&& asinc == 0) gun1 = HIGH, asinc = 1; if(asinc == 1 && gun1 == HIGH && gun2 == LOW && por==0 && (millis() - previousMillisTata > interval_asinc)) gun2 = HIGH, previousMillisTata = millis(), por=1; if (tata < 1100) gun1 = LOW, gun2 = LOW; ///// Теперь второй AirsoftPin1!!!!!!!!!!!!!!!!!!! if ((tata > 1200)&& (swit<1500) && gun2 == LOW && por==1 &&asinc == 1) gun2 = HIGH, asinc = 2; if(asinc == 2 && gun2 == HIGH && gun1 == LOW && por==1 && (millis() - previousMillisTata > interval_asinc)) gun1 = HIGH, previousMillisTata = millis(), asinc = 0, por=0; if (tata < 1100) gun1 = LOW, gun2 = LOW; } //Крайняя фигурная скобка
В коде не разбирался, но 99.9% кривой, копайте в нем. Вставьте сериалы в контрольных точках, смотрите какие значения какая переменная принимает. Кварц конечно на МК не супер, но его отклонения могут на суточных интервалах сказываться, а не на секундных. Где то у вас интервал проскакивает свое значение, попробуйте на 5000 изменить и посмотрите.
Да нет,bwn, этот гений время начала своих танцев не фиксирует. Когда подряд, то успевает к фиксации в строках 60 и 77. А «чуть погодя» запомненное время становится очень старым. И оба диодо стабатывают одновременно.... Задержка то уже случилась. Гы!
wdrakula, я в первом if-е забуксовал и даже читать дальше не стал. Serial.println наше фсе.
В коде не разбирался
Зря! Там песня, а не код! Получил большое удовольствие.
Зря! Там песня, а не код! Получил большое удовольствие.
А как прекрасны операторы через запятую?
В коде не разбирался, но 99.9% кривой, копайте в нем. Вставьте сериалы в контрольных точках, смотрите какие значения какая переменная принимает. Кварц конечно на МК не супер, но его отклонения могут на суточных интервалах сказываться, а не на секундных. Где то у вас интервал проскакивает свое значение, попробуйте на 5000 изменить и посмотрите.
Спасибо что развеяли сомнения на счет кварца.
Прямизной кода правда похвастаться не могу, в "теме" букавльно пару месяцев, и факультета IT за плечами нет. Гуманитарий я :) Но хочу учиться)
Пробовал поменять интервал на 5000 - задержка начинает работать, но 5с - это много, я собирался настраивать ее в пределах до 1с.
Как правильно фиксировать это "время начала"? Достаточно одного раза в начале цикла? Или при каждом обращении к millis () ? Пробовал записывать время в переенную, которая потом участвует в условии
Издеваетесь?
в 55 и 72 строки добавьте previous-bla-bla-bla=millis()
----------------
остальные свои косяки сами ищите... или Женя поможет - он добрый. ;) Клапауция еще можно попросить.
а у меня возник вопрос - Вы вообще как это создавали? Просто есть серьезное подозрение, что Вы не очень понимаете, что в этом коде происходит?
То есть Вы что-то взяли за основу, не понимая, а потом стали приделывать костыли из говна и палок. Так?
1. К Лешаку, находим там и читаем про миллис, пока не наступит просветление. Правда сейчас что то у меня не сконнектилось, попозже попробуйте.
2. Что стать адептом тележурнала "Хочу все знать", берем сериалпринты и расставляем в контрольных точках, какие значения у наших переменных.
3. На основании полученной информации, курим что нибудь забористое и начинаем креативить на предмет, почему моя переменная делает не так.
курим что нибудь забористое ... почему моя переменная делает не так.
Так вроде уже всё выкурено. Миллис вон уже нестабилен.
Помнится в 80ы-е юзера так задолбали апломбными заявлениями, что у нас что-то не так работает, что на дверь комнаты дежурной смены мы повесили табличку: "Да, у нас фортран не работает, и чо?"
курим что нибудь забористое ... почему моя переменная делает не так.
Так вроде уже всё выкурено. Миллис вон уже нестабилен.
Помнится в 80ы-е юзера так задолбали апломбными заявлениями, что у нас что-то не так работает, что на дверь комнаты дежурной смены мы повесили табличку: "Да, у нас фортран не работает, и чо?"
У нас компьютер отчет стер.
Что делали?
Ничего, он сам.
Вот такие были у нас брутальные компьютеры.)))) ИИ отдыхает.
И это уже 486 и первые пеньки. Что в 80-х было вообще не представляю, я тогда еще деревянный в виде линейки юзал.
в 84-ом я распечатал себе свой первый экземпляр Кернигана и Ричи на АЦПУ, на СМ-4 (вроде Мера польская была).
Вы все врети. Стока люди не живут. :)
Вы все врети. Стока люди не живут. :)
Эт план такой, пенсионный фонд обанкротить.))))
Слёзы счастья!)))
Спасибо wdrakula, про 55 и 72 строки - это было круто!) Теперь все работает идеально
Даже видео снял на радостях)
https://vimeo.com/202012131
Так вроде уже всё выкурено. Миллис вон уже нестабилен.
Простите, только сейчас понял, на сколько провокационен заголовок!)
Да и китайцы не виноваты, отличные платы делают!)))
Спасибо за ресурс Лешака, буду вчитываться. Что касается остального кода, то пока одолевать людей не буду, раз он работает, возможно скоро сам буду так же смеяться над своими ошибками ;)
А я получается, писал эту фразу, писал, "previous-bla-bla-bla=millis()" , но не в действии, а где-то между ними. Поэтому, она не выполнялась или выполнялась не правильно...
это потому, что какой-то "гей" научил Вас писать операторы через запятую.
Поэтому чудо, что у Вас хоть что-то работает.
оператор if используется так:
это потому, что какой-то "гей" научил Вас писать операторы через запятую.
Поэтому чудо, что у Вас хоть что-то работает.
оператор if используется так:
Да, спасибо! Теперь только так!
Наверно уже надоел, но все же спрошу)
Есть еще одна часть кода того же моего "масштабного" проекта.
Задачей было сделать так, чтобы светодиод включился один раз на определенное время (interval_Rok) и погас, до выключения и новго включения тумблера. Примерный код (кривой) у меня уже был. Сделал по тому же принципу, через millis (), постарался учесть замечания.
И всё вроде бы работает, вот только при превичном включении тумблера на пульте RC, диод не всегда загорается (в большинстве случаев не загорается).
В чем может быть дело? Кажется я не учел какой-то принципиальный момент.
По сериал-монитору значения на входе изменяются. А вот где его воткнуть еще раз, чтобы посмотреть переменные - не соображу.
Да, еще такой симптом - время включения светодиода - не всегда одинковое, не смотря на то, что интервал ничего не именяет. Пробовал объявлять интервал const, пробовал unsigned - та же петрушка
79 строка. Не каррент, а привиус.
представьте вместо контроллера самого себя, только ускоренного,как Флеш ;). с секундомером. Каррент - это то, что показывает секундомер сейчас, а привиус - то, что вы записали на бумажке. Так становится нагляднее?
Пробовал объявлять интервал const, пробовал unsigned - та же петрушка
Вы их таки не пробуйте, они не черешня, а разберитесь и усвойте, какое магическое слово что значит.))))
Не, у ТС что то все петрушка получается. Было б сало, еще куда ни шло.)))
представьте вместо контроллера самого себя, только ускоренного,как Флеш ;). с секундомером. Каррент - это то, что показывает секундомер сейчас, а привиус - то, что вы записали на бумажке. Так становится нагляднее?
Гораздо))) А я всё представляю время как что-то связанное с бесконечной вселенной)))
Но если в 79 строку ввернуть previousMillisRok вместо currentMillisRok, получается странная картина:
Диод загорается и горит. А когда кнопку выключаешь - через интервал гаснет. Но иногда и правильно стработает пару раз, а потом опять за своё.
Сижу, разбираюсь, но пока без сала:)
Но если в 79 строку ввернуть previousMillisRok вместо currentMillisRok, получается странная картина:
Диод загорается и горит. А когда кнопку выключаешь - через интервал гаснет. Но иногда и правильно стработает пару раз, а потом опять за своё.
Сижу, разбираюсь, но пока без сала:)
Вы, признак того, что цикл начался (OneRok) j обнуляете при окончании цикла, а нужно при НАЧАЛЕ.
Перенесите OneRok=0; в первый if, рядом с 79 строкой.
Понятно? Тогда это условие сработает ровно один раз, при нажатии кнопки.
wdrakula, добрый вы. Вот сериалпринты ТС явно пользовать не желает, предпочитает спросить, а это не гут.
предпочитает спросить
Никакие отладчики, сериалпринты и прочие эти ваши джитэги никогда не заменят живого человеческого общения! Долой виртуальную землю, резиновых женщин и безалкогольное пиво!
предпочитает спросить
Никакие отладчики, сериалпринты и прочие эти ваши джитэги никогда не заменят живого человеческого общения! Долой виртуальную землю, резиновых женщин и безалкогольное пиво!
Не, я лимит вопросов предпочитаю приберегать на случай, когда действительно в тупик залезу (мой личный).
wdrakula, добрый вы. Вот сериалпринты ТС явно пользовать не желает, предпочитает спросить, а это не гут.
Учусь и ими пользоваться)
И вот как раз сериал монитор показывает, что интервал уже как-бы прошел (хотя это не правда), и порой не зажигает мой свето-диод, или зажигает на меньшее время.
Время начала танцев обозначаю..., все по схеме вроде делаю... Странно, не пойму почему так.
Из кода убрал лишние переменные, теперь он сталь короче
Вы, все таки доведете меня до греха!
В первой версии кода, не надо ничего делать КРОМЕ ТОГО, что в 79 строке СТАРОГО, мля, кода, написать :
previousMillisRok = millis(); OneRok=1;
Всё. На этом мы прекратим изучение Ваших бессмерных творений. Оставьте их потомкам. Я - устал.
Вы, все таки доведете меня до греха!
В первой версии кода, не надо ничего делать КРОМЕ ТОГО, что в 79 строке СТАРОГО, мля, кода, написать :
previousMillisRok = millis(); OneRok=1;
Всё. На этом мы прекратим изучение Ваших бессмерных творений. Оставьте их потомкам. Я - устал.
Хорошо, Вы уже и так очень помогли!)