Всем привет! Уже два дня Ломаю голову и интернет в поисках информации по Простому таймеру. Пока все что удалось нарыть переделал под свои нужды но оно работает не так как нужно мне. Код (Text): unsigned long time; char ar = 0; int t; int s; int m; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0) { ar = Serial.read(); } if (ar == 's') { time = 1440000; byte s = ((time - millis()) / 1000ul) % 60; byte m = (((time - millis()) / 1000ul) / 60ul) % 60; Serial.print(m); Serial.print(":"); Serial.print(s); Serial.print("\n"); delay(1000); } else if (ar=='b'){ Serial.print("Stop time"); ar = ' ' } } Тут возникло три вопроса. Как начинать отсчет только после: if (ar == 's'). Как сделать чтоб по окончании заданного времени программа переходила в ожидание новой команды. И почему происходит такая фигня: Если что-то похожее уже было на форуме ткните ссылку пожалуйста.
Код (Text): ar = ' ' Исправьте на Код (Text): ar = ' '; Вы отнимаете от time = 1440000, значение millis(), которое всегда растет. Если можно напишите, что Вы хотите сделать. Просто не могу понять, вопросов. В идеале, примерно так: Если передали s начинаем отсчет от 10 и не прекращаем, пока не получили команду и т.д.
Я хочу сделать таймер с выводом на OLED дисплей времени, дисплей пока не приехал хочу накидать макет через ком-порт. Время должно начинать считаться от получения сигнала с компа через ком. Как это реализовать не понимаю... На скрине видно что время идет до 23:27 а потом становится 24:32. От чего это происходит?
С данным кодом такой проблемы не будет. Код (Text): unsigned long time; int t; int s; int m; // Номер команды byte comand; // Предыдущее значение millis unsigned long previousMillis = 0; // Интервал в мс. const long interval = 1000; void setup() { Serial.begin(9600); } void loop() { char ar = 0; if (Serial.available() > 0) { ar = Serial.read(); } if (ar == 's') { comand = 1; } else if (ar=='b') { comand = 2; } if (comand == 1) { // Текущее значение millis unsigned long currentMillis = millis(); // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу. if(currentMillis - previousMillis >= interval) { // Присваиваем предыдущему значению текущее. previousMillis = currentMillis; // Ваш код. time = 1440000; byte s = ((time - millis()) / 1000ul) % 60; byte m = (((time - millis()) / 1000ul) / 60ul) % 60; Serial.print(m); Serial.print(":"); Serial.print(s); Serial.print("\n"); } } else if(comand == 2) { Serial.print("Stop time"); comand = 0; } } У Вас как я понял, переда команда, начинается отсчет от какого-то значения, затем команда стоп. После повторной команды старт, время начинает отсчитываться от чего? UPD. Отсчет начинается, с 24 минут, каждый раз после следующей команды s. Код (Text): unsigned long time; int t; int s; int m; // Номер команды byte comand; // Предыдущее значение millis unsigned long previousMillis = 0; // Интервал в мс. const long interval = 1000; // Сохраняем начальное значение Millis для отсчета от него. unsigned long beginCountMillis = 0; void setup() { Serial.begin(9600); } void loop() { char ar = 0; if (Serial.available() > 0) { ar = Serial.read(); } if (ar == 's') { comand = 1; beginCountMillis = 0; } else if (ar=='b') { comand = 2; } if (comand == 1) { // Текущее значение millis unsigned long currentMillis = millis(); // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу. if(currentMillis - previousMillis >= interval) { // Присваиваем предыдущему значению текущее. previousMillis = currentMillis; // Ваш код. time = 1440000; // Если начальное значение равно 0. if (beginCountMillis == 0) { // Задаем начальное значение счетчика. beginCountMillis = previousMillis; } // Прибавляем начальное значение и time. time += beginCountMillis; byte s = ((time - previousMillis) / 1000ul) % 60; byte m = (((time - previousMillis) / 1000ul) / 60ul) % 60; Serial.print(m); Serial.print(":"); Serial.print(s); Serial.print("\n"); } } else if(comand == 2) { Serial.println("Stop time"); comand = 0; } } Да и не забываем о проверке данного значения на 0. Код (Text): (time - previousMillis) Если дойдет до 0, дальше будут одни нули. Можно остановить таймер, при достижении 0. Код (Text): unsigned long time; int t; int s; int m; // Номер команды byte comand; // Предыдущее значение millis unsigned long previousMillis = 0; // Интервал в мс. const long interval = 1000; // Сохраняем начальное значение Millis для отсчета от него. unsigned long beginCountMillis = 0; void setup() { Serial.begin(9600); } void loop() { char ar = 0; if (Serial.available() > 0) { ar = Serial.read(); } if (ar == 's') { comand = 1; beginCountMillis = 0; } else if (ar=='b') { comand = 2; } if (comand == 1) { // Текущее значение millis unsigned long currentMillis = millis(); // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу. if(currentMillis - previousMillis >= interval) { // Присваиваем предыдущему значению текущее. previousMillis = currentMillis; // Ваш код. time = 1440000; // Если начальное значение равно 0. if (beginCountMillis == 0) { // Задаем начальное значение счетчика. beginCountMillis = previousMillis; } // Прибавляем начальное значение и time. time += beginCountMillis; byte s = ((time - previousMillis) / 1000ul) % 60; byte m = (((time - previousMillis) / 1000ul) / 60ul) % 60; if (s>0 || m>0) { //byte s = ((time - previousMillis) / 1000ul) % 60; //byte m = (((time - previousMillis) / 1000ul) / 60ul) % 60; Serial.print(m); Serial.print(":"); Serial.print(s); Serial.print("\n"); } else { Serial.println("Finish"); comand = 0; } } } else if(comand == 2) { Serial.println("Stop time"); comand = 0; } } Код не оптимальный, но тут главное понять.
Там по факту команд несколько но с разным стартовым временем. Спасибо огромное! Теперь буду разбираться во всем этом. И у меня сразу возникает вопрос по скечу: Почему этот кусочек Код (Text): if (ar == 's') { comand = 1; beginCountMillis = 0; } отделяют от этого? Код (Text): if (comand == 1) { // Текущее значение millis unsigned long currentMillis = millis(); // Из текущего вычитаем предыдущее и проверяем больше или равно интервалу. if(currentMillis - previousMillis >= interval) { // Присваиваем предыдущему значению текущее. previousMillis = currentMillis; // Ваш код. time = 1440000; // Если начальное значение равно 0. if (beginCountMillis == 0) { // Задаем начальное значение счетчика. beginCountMillis = previousMillis; } // Прибавляем начальное значение и time. time += beginCountMillis; byte s = ((time - previousMillis) / 1000ul) % 60; byte m = (((time - previousMillis) / 1000ul) / 60ul) % 60; if (s>0 || m>0) { //byte s = ((time - previousMillis) / 1000ul) % 60; //byte m = (((time - previousMillis) / 1000ul) / 60ul) % 60; Serial.print(m); Serial.print(":"); Serial.print(s); Serial.print("\n"); } else { Serial.println("Finish"); comand = 0; } } } И можно ли их объединить для удобства чтения? Ведь по факту они являются одним целым но разнесенными в разные места.
Объединить нет, beginCountMillis = 0; ее надо взводить именно при получении данных. 1. Блок - if (ar == 's') срабатывает только при получении данных. 2. Блок if (comand == 1) крутится всегда, после получения команды 1. UPD. Но Вы можете, вставить этот код, так. Код (Text): if (Serial.available() > 0) { ar = Serial.read(); if (ar == 's') { beginCountMillis = 0; } } И тогда можно будет сделать 1 блоком. А дальше убрать comand, заменив ее на ar, и вынести ar за пределы функций, как у Вас было.