Образно все выглядит вот так: Код (C++): void setup() { // put your setup code here, to run once: } void loop() { buttonState(); blinck(); timer(); } void buttonState(){ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX } void blinck(){ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY } void timer(){ ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ } Каждый блок по отдельности работает как надо, вопрос как правильно их объединить. Блоки "buttonState" и "blinck" по такой схеме то же работают, но как только добавляю "timer" (он около 30 мин), блоки кнопок и светилок перестают работать. Если я правильно понимаю пока не отработает таймер остальные блоки не прочитаются. Как расположить чтоб во время работы таймера можно было вносить изменения в "buttonState"
"А вы друзья, как ни садитесь...." (с) Дедушка Крылов Дело не в расположении блоков, а в их содержании. Ни один блок не должен захватывать исполнение надолго. Чтобы программа нормально работала, в ней ни в коем случае не должно быть блоков. исполняющихся дольше, чем 50-100мс. А лучше, чтобы все время цикла loop() (в вашем коде - это сумма длительности всех трех блоков) не превышало 1-5мс.
Расположение блоков в скетче не зависит от их очередности вызовов в программе. К слову, loop() лучше переместить в конец скетча, ибо новые версии IDE более строго относятся к размещению блоков в скетче.
Зачем?Пусть тикает millis отмеряя нужные интервалы.И для этого не надл отдельную программу "timer". Если же хотите чтобы устройство наглухо блокировалось на конкретный промежуток времени и исключить аппаратную отсебятину можно использовать delay-но только в этом случае.
Нет. неправильно. Легко можно обойтись одним контроллером. Но нужно процедуру timer переписать так, чтобы она не блокировала loop() больше чем на несколько микросекунд. Вы не приводите код, поэтому я не знаю, что происходит внутри timer(). Однако можно догадаться, что большую часть из этих 30 минут компьютер просто ждет, когда истечет время. Теперь подумайте, как вы сами поступаете в таких ситуациях. Предположим, вам через 2 часа нужно совершить важный звонок. Вы же не будете 2 часа сидеть перед телефоном и смотреть на него? - нет, вы заметите время и 2 часа будете заниматься другими делами, поглядывая на часы. Правильный отсчет интервалов в программе делается точно так же - нужно заметить время и регулярно его проверять, выполняя между проверками другие задачи. Практический пример смотрите в статье "Блинк без delay"
а таймер вот Код (C++): #include "TM1637.h" // #define CLK A0 // CLK #define DIO A1 // DIO int ledPin = A2; // int ledState = LOW; // TM1637 tm1637(CLK,DIO); // int currentInterval =0; // int intervals[]={1800,300}; //длина интервалов в секундах, в массиве long startInterval =0; //время начала текущего интервала int currentTime =0; // прошедшее время с начала текущего интервала в секундах unsigned long previousMillis = 0; long OnTime = 10; // long OffTime = 10; // void setup() { tm1637.init(); // Сброс дисплея tm1637.set(BRIGHT_TYPICAL); // Уровень яркости // BRIGHT_DARKEST = 0,BRIGHTEST = 7 BRIGHT_TYPICAL = 2; tm1637.point(POINT_ON); // Активация точки посредине delay(1000); // Задержка 1 секунда } void loop() { currentTime =(millis()- startInterval)/1000; while(currentTime < intervals[currentInterval]){ if(currentInterval % 2 == 0){ tm1637.clearDisplay();// int showingTime = intervals[currentInterval] - currentTime; int seconds = showingTime % 60; // int mins = showingTime / 60; // tm1637.display(3,seconds%10); if(seconds > 9) tm1637.display(2,seconds/10); if(mins > 0) tm1637.display(1,mins%10); if(mins > 9) tm1637.display(0,mins/10); } currentTime =(millis()- startInterval)/1000; delay(200); } tm1637.clearDisplay(); // currentInterval =(currentInterval + 1 == sizeof(intervals)/sizeof(int)) ? 0 : currentInterval +1; startInterval = millis(); }
чтобы этот таймер нормально работал с другими частями программы. надо всего лишь раскрыть цикл while. Общий принцип - сейчас у вас исполнение крутится в цикле while до конца текущего интервала, не выходя в основную программу. Поэтому в программе ничего больше не работает. А вам просто нужно сделать так, чтобы контроллер, пройдя код таймера один раз, потом возвращался в основную программу, исполнял процедуры buttonState() и blinck() - и снова шел в таймер. И так по кругу
Когда требуется параллельно выполнять кучу дел с разной частотой я, чаще всего, раскидываю их по функциям в начале каждой проверяется не пора ли ее выполнить, а в конце заряжается тамер на следущую итерацию. В лупе же просто размещаю список этих самых функций. Получается наглядно и компактно. Еще есть прерывания, но это другая сказка.