На простом скейче спустя время лагает функция millis()
- Войдите на сайт для отправки комментариев
Сижу уже месяц над одним проектом. Собираю можно сказать умный террариум.
Задача ардуины отследить температуру если нужно подогреть, так же с влажностью, так же на ней весит задача в нужное время включать выключать определенные лампы, к ардуине подключен модуль реального времени. Да вобшем не суть.
Собралось 5 переменных для функции millis() искал способ разгрузить ардуинку, а то выходит рез в секунду количество ее действий подскакивает к примеру с 10 до 100. когда можно было бы распределить на всю секунду. Связано с тем что много операций выполняется раз в секунду. И тут написал для теста и столкнулся с глюком.
При запуске контроллера все работает четко но спустя пол часа или час. передача в Serial становиться примерно отправил "1" спустя примерно 0.4 секунды отправил "2" спустя так же 0.4 секунды "3" и тд. что я недопонимаю? из за чего такое происходит? плата китайская нана 328Р атмегой.
unsigned long startLOOP; unsigned long startLOOP1; unsigned long startLOOP2; unsigned long startLOOP3; unsigned long startLOOP4; void setup() { Serial.begin(9600); } void loop() { if (millis() - startLOOP > 5000) { startLOOP = millis(); Serial.println("1"); } if (millis() - startLOOP1 > 5001) { startLOOP1 = millis(); Serial.println("2"); } if (millis() - startLOOP2 > 5002) { startLOOP2 = millis(); Serial.println("3"); } if (millis() - startLOOP3 > 5003) { startLOOP3 = millis(); Serial.println("4"); } if (millis() - startLOOP4 > 5004) { startLOOP4 = millis(); Serial.println("5"); } }
почему переживаю за это. Есть коварный увлажнитель к его кнопкам для контроля подключено 4 реле. и все они должны успевать сработать по 0.3 секунды каждое в определенном порядке. боюсь что ардуина пропустит одну из реле. Да и просто не хочется в один прекрасный момент увидеть в террариуме жаркое из своего питомца, от того что перегрелся термошнур из за тормозов ардуины. В программирование не селен просто знаю некторые моменты, в остальном самоучка, по этому если можно на пальцах объяснить из за чего такое происходит.
не хочется в один прекрасный момент увидеть в террариуме жаркое из своего питомца, от того что перегрелся термошнур из за тормозов ардуины
для этого не вумные алгоритмы нужны, а - тупой механический реле-отсекатель максимального нагрева.
каждый следующий цикл длинее предыдущего на 1 мс. За полчаса эти циклы исполняются примерно 600 раз - сл-но набегает разница в 0.6 секунды.
Хотите чтобы разница не накапливалась - задайте один общий интервал на все пять условий
Тут не все так просто. Днем температура одна, ночью другая. В вентиляции есть спираль для того что бы подогревать воздух, с термошнуром это быстрее пример. Там все горазда сложнее. Есть кулер от компьютера в фоновом режиме он крутиться 300 оборотов в минуту. С обогревом он выбирает оптимальную скорость так чтоб быстрее согреть террариум. Так же на эту спираль я подаю ШИМ сигнал, в Зависимости от разнице температуры между комнатой и внутри террариума. Это в 1 очередь позволит экономить электроэнергию. Есть другая сторона этого. К примеру попала солнце на террариум. Стенки вроде холодные шнур вроде тоже, термостат запустил подогрев не смотря на то что в террариуме как в парнике. В моей задумке все иначе, Датчик dht22 определил температуру. В моем случаи это 2 датчика dht22 один стоит с низу другой с верху, и в расчет берётся среднее значение. Увидел что температура большая из за тех же лучей солнца. не стал включать подогрев(по сколько не прислонен к стеклу которое в любом случаи на полу будет прохладное) А добавил обороты вентилятора выронив температуру до нужной, не затратив при этом лишний электроэнергии.
Взять увлажнение Оно не будет включаться ночью если в террариуме температура ни будет на 2 градуса выше нужной, но зная о том что нужно увлажнить. Ардуина сама подымит температуру и уже в нужный момент увложнит. что с тем же термостатом сделать было бы сложнее. Вернее не знаю как его заставить адаптироваться без вмешательства на новые условия которые каждые пол часа могут меняться.
Говорю уже месяц колдую над кодом. Осталась только написать цикл для выбора частоты ворошения вентилятора, прописать пару аварийных моментов, например если отключился датчик чтоб сама ардуина выкинула из основного цикла цикл подогрева и увлажнения, подняла чуть обороты вентилятора и на лед дисплей вывила ошибку.
Но опять же, похвасться я люблю идеями, пусть и путь к ним долог. Я думаю продвинутые ардуиншики эти циклы написали за пару дней а не как я месяц копчу проверяя все по отдельности. НО ГЛАВНЫЙ ВОПРОС В ТОМ ПОЧЕМУ ЭТО ПРОИСХОДИТ? от куда взялся глюк? И может это быть из за того что плата ардуина нана слишком слабая? На нане я проверяю каждый режим в отдельности потом это все дела перемешается на мегу. По сколько из бюджетных у меге хватает памяти это все исполнять. У наны кончалась память уже после подключения часов ОЛЕД дисплея и 2х датчиков dht22.
во всем скейче что уже готово функция милис реализована так же. Есть ли способ исправить данный глюк не сильно переписывая кот?
каждый следующий цикл длинее предыдущего на 1 мс. За полчаса эти циклы исполняются примерно 600 раз - сл-но набегает разница в 0.6 секунды.
Хотите чтобы разница не накапливалась - задайте один общий интервал на все пять условий
Немного не понял. Да я понимаю на примере этого цикла проще одним условиям все сделать. Но исходя из того что уже много написано и я давал милис специально разные переменные чтоб в каждой функции был свой милис. И переделать это все под одну переменую мне пока кажется нереальным.
Или я снова что то не так понял? Как вы вычислили 0.6 секунды? и почему получается каждый новый цыкал длине? если постоянно идет приравнивание переменной к милес? немного не понял. Можете пояснить по проще на пальцах?
И еще есть такой вопрос, если переменные разные но интервал времени одинаковый. можно ли распределить как то все? к примеру чтоб чтоб не нагружать раз в секунду ардуину. а растянуть к примеру эти же 5 действий на всю секунду. к примеру имея такой код
Повторюсь обледенить в 1 милис их нельзя по сколько то где это нужно там разные функции. Можно как то сделать чтоб это выполнялась на протяжение секунды а не раз в секунду все 5 действия? хотелось немного оптимизировать работу.
Это мой первый большой проект и в первые я использую милис. Не ругайте сильно за тупые вопросы.
вы на марс летите или климатом в банке занимаетесь ?
нафига такие точности ?
да ещё и DHT22.
Вы себе просто голову ерундой забиваете.
а если учесть на сколько инертны и влажность и температура, да ещё правильность и точность ваших измерений, то есть над чем вам призадуматься - как сделать без фанатизма.
ТС, тебе запятых отсыпать? У мня есть, полно. И разные другие есть препинания.
Хорошим тоном считается задание начальных значений переменных.
В крайнем скетче задайте им значения от 0 до 800 с шагом в 200.
Это мой первый большой проект и в первые я использую милис. Не ругайте сильно за тупые вопросы.
мои первые проекты еще хуже, хоть и проще. Клапауций писал класс титановый велосипед для delay без delay(). можно использовать как библиотеку, завести переменную и выполнять какие-либо действий по новому счетчику.
т.е. когда переменная счетчика станет равной заданной, а в конце ее скидывать и начинать цикл заново. Можно вообще календарь или "RTC" использовать.
Как вы вычислили 0.6 секунды? и почему получается каждый новый цыкал длине? если постоянно идет приравнивание переменной к милес? немного не понял. Можете пояснить по проще на пальцах?
Я там выше немного обсчитался, не 0.6 сек, а 0.4. Но суть та же.
Каждый следующий цикл длиннее, потому что вы их так задали. Вот смотрите - в первом у вас интервал 5000 мс, во втором - 5001. То есть выполнение второго цикла длинеее на 1мс, и с каждым запуском второй цикл все больше отстает от первого. 5000 мс - это 5 сек, значит за минуту циклы запускаются 12 раз и между первым и вторым циклом накопится расхождение в 12 мс. За 30 минут - 30*12 = 360мс, то есть примерно 0.4 секунды
Не пишите ерунды, ардуина тут совершенно не причем - причина исключительно в вашем коде. Код работает ровно так, как вы его написали.
Не пишите ерунды, ардуина тут совершенно не причем - причина исключительно в вашем коде. Код работает ровно так, как вы его написали.
Огромное спасибо) не догадался сразу, привык пользоваться функцией делейт. И то что каждый раз как первый. Жестока я тупанул ахахаха)))
Еще такой вопросик из куска кода. Не будит тут не каких глюков? попробую собрать код как можно проще.
Принцип работы. Обычный бытовой увлажнитель воздуха, к кнопкам подпаяны реле. Отслеживаем уровень влажности, если он ниже заданного включаем увлажнитель на несколько минут.
Увлажнения по часам нужно для того чтобы на стеклах собрались капли. Странная привычка питомца пить не из поилки, или фонтанчика, а слизывать влагу со стекал.
Вопрос в том что будут ли тут глюки со временим?
При тесте были глюки. Но они были связаны с тем что реле не успевала выключиться или включиться. пока не подобрал оптимальное количество миллисекунд. причем глюк был хаотичный. тестил минут 10. Но все равно бывает какое то реле во включенном состояние дольше какое то меньше. С накоплением Милис проблем не будет? не появиться какая-нибудь разница? Просто прошу проверить)))) дабы не вышло того что я снова тупанул))))
Комментарий оставлял изначально для себя, прошу не ругать за грамматику.
Первое, что заметил - есть в скетче отсыл к часам реального времени, но работы с ними я не наблюдаю. Следовательно, проверить в "режиме vlagaON == 2" никогда не представится.
ЗЫ: Может быть это вообще для вас и не нужно, но есть много вопросов по написанию кода. Самый первый вопрос - зачем в loop() вызывать всего одну функцию vlaga()? Суть функций в другом. Чаще всего - вынести повторяющийся код в функцию.
Первое, что заметил - есть в скетче отсыл к часам реального времени, но работы с ними я не наблюдаю. Следовательно, проверить в "режиме vlagaON == 2" никогда не представится.
ЗЫ: Может быть это вообще для вас и не нужно, но есть много вопросов по написанию кода. Самый первый вопрос - зачем в loop() вызывать всего одну функцию vlaga()? Суть функций в другом. Чаще всего - вынести повторяющийся код в функцию.
Первое что надо сделать это прочитать полностью. В идеале пробежаться по всей теме.
Объясняю! в данном коде нет библиотеки, и кода работы с часами реального времени, по сколько это часть кода вернее 1 функция вырванная из большого скейча. В скейче этих функций достаточно. Но чтоб не объяснять длинный код я взял всего его кусочек. По этому отсутствует библиотека работы с часами реального времени. к данной библиотеке вопросов не каких. А поместив ее суда, пришлось бы прикреплять саму библиотеку и грузить людей лишней информацией. Вопрос весь связан функцией милес. Я с ней работаю в 1 раз и какие то нюансы упускаю. По этому прощу подсказать гуру в этой теме точно ли я не получу лагов через день или другой. как в шапке темы.
Почему в loop() я вызываю только эту функцию как сказана выше первое это часть кода в остальное вникать бессмысленно и большинство людей пройдет мимо увидев 30-40 переменных и 300-400 строк кода. Также в дальнейшем в цикле loop() будут прописаны ворожения. К примеру если температура в террариуме ниже заданной то к функции vlaga() орошаться не нужно. Так же если температура в комнате это t3 которого тут нету выше заданной температуре обрушаться и уж точно выполнять функцию обогрева и тратить на нее ресурс контролёра не нужно, а еще просто удобно. Я писал каждый цикл отдельно испытывая на ардуине нано. Далее просто капиравал в общий скейч и из цикла делал функцию зная что данный кусок кода рабочий. И когда Я все помещу в ардуину мегу меньше будет проблем!
Я спросил это все не просто так. Если есть часы реального времени, не проще ли работать с ними по "всем пунктам логики программы"?
По типу как у вас сделано вот тут:
В библиотеке (по типу такой) есть все что нужно для реализации ваших хотелок. Скеч упростится. Но может я чего-то не знаю/не понимаю в вашей логике... Не исключаю этого.