Обратный отсчет когда-нибудь остановится
Я сделал игру с 3 обратными отсчетами и 1 общим обратным отсчетом.
Когда мы начнем, глобальный, иди с 45:00 до 00:00.
1 идет с 15:00 до 00:00, а если доходит до 00:00:
2 начинаются и продолжаются с 15:00 до 00:00, а если доходят до 00:00:
Три стартуют и идут с 15:00 до 00:00
Если вы выиграли небольшую игру, вы можете остановить обратный отсчет и начать следующую. Если вы выиграете 3 игры, вы остановите обратный отсчет 3 и глобальный тоже.
Но иногда мой второй обратный отсчет останавливается сам, где-то в 13:58 или 10:54…
Возможно ли, что millis() вызывает эту ошибку? У вас есть идея улучшить мой код и исправить это?
Забавный факт: иногда обратный отсчет идет от 01 до 60 вместо 00 до 59……
Извините за мой английский, я не носитель языка.
//14-06-17 Индикатор коррекции
//10-06-17 Коррекция Жеу 1
#include "musical_notes.h"
#include "TM1637.h"
#include "SevenSegmentTM1637.h"
#include "OnewireKeypad.h"
#include "Password.h"
SevenSegmentTM1637 displaya(4, 5);
SevenSegmentTM1637 displayb(6, 7);
SevenSegmentTM1637 displayc(8, 9);
SevenSegmentTM1637 displayd(50, 51);
TM1637 tm1637a(50, 51); //ТАЙМЕР ГЛОБАЛЬНЫЙ 45
TM1637 tm1637b(4, 5); // ТАЙМЕР 1 15
TM1637 tm1637c(6, 7); //ТАЙМЕР 2 15
TM1637 tm1637d(8, 9); //ТАЙМЕР 3 15
char KEYS[] = {
'1', '4', '7', '*',
'2', '5', '8', '0',
'3', '6', '9', '#',
'A', 'B', 'C', 'D'
};
OnewireKeypad <Print, 16 > KP(Serial, KEYS, 4, 4, A0, 4700, 1000, ExtremePrec );
Password password = Password( "8751" );
//ПРЕМЬЕР ЖЕУ
int checkbranche = 23;
int checkbrancheb = 22;
int checkbranchec = 24;
int state = HIGH;
int reading;
int readingb;
int readingc;
int previous = LOW;
int previousb = LOW;
int readingstart;
int checkstart = A1;
int speakerPin = 52;
int runOPEN = 0;
int runJEU1 = 0;
int runJEU2 = 0;
int runJEU3 = 0;
int runFAILGLOBAL = 0;
int winJEU1 = 0;
int winJEU2 = 0;
int winJEU3 = 0;
int winGLOBAL = 0;
int looseGLOBAL = 0;
int LED_jeu1_V = 30;
int LED_jeu1_R = 31;
int LED_jeu2_V = 33;
int LED_jeu2_R = 32;
int LED_jeu3_V = 35;
int LED_jeu3_R = 34;
int LED_jglobal1 = 36;
int LED_jglobal2 = 37;
int LED_jglobal3 = 38;
int LED_jglobal4 = 39;
int runcode = 0;
int second=0, minute=45, hour=0; // объявление временных переменных
int second1=0, minute1=15, hour1=0; // объявляем временные переменные
int second2=0, minute2=15, hour2=0; // объявляем временные переменные
int second3=0, minute3=15, hour3=0; // объявляем временные переменные
long previousTime = 0;// хранит предыдущее время в мс
long previousTime1 = 0;// хранит предыдущее время в мс
long previousTime2 = 0;// хранит предыдущее время в мс
long previousTime3 = 0;// хранит предыдущее время в мс
long previousDelay = 0;// хранит предыдущее время в мс с момента активации зуммера
long previousDelay1 = 0;// хранит предыдущее время в мс с момента активации зуммера
long previousDelay2 = 0;// хранит предыдущее время в мс с момента активации зуммера
long previousDelay3 = 0;// хранит предыдущее время в мс с момента активации зуммера
long interval = 60000;//задержка 60 секунд
long interval1 = 60000;//задержка 60 секунд
long interval2 = 60000;//задержка 60 секунд
long interval3 = 60000;//задержка 60 секунд
int dismentel1 = 0; int fail1 = 0;
int dismentel2 = 0; int fail2 = 0;
int dismentel3 = 0; int fail3 = 0;
int dismentel4 = 0; int fail4 = 0;
char hour_str[4]; // Чтобы преобразовать int в char
char minute_str[4]; // Чтобы преобразовать int в char
char second_str[4]; // Чтобы преобразовать int в char
char timeInt_str[0]; // Чтобы преобразовать int в char
int accessgame = 3; //Активация светодиода за 3 минуты прибытия
unsigned char halfsecond=0;
void setup() {
Serial.begin(19200);
KP.SetHoldTime(3000);
KP.SetKeypadVoltage(5.0);
KP.ShowRange();
displaya.begin();
displayb.begin();
displayc.begin();
displayd.begin();
tm1637a.set(4);
tm1637a.init();
tm1637a.point(POINT_ON);
tm1637b.set(4);
tm1637b.init();
tm1637b.point(POINT_ON);
tm1637c.set(4);
tm1637c.init();
tm1637c.point(POINT_ON);
tm1637d.set(4);
tm1637d.init();
tm1637d.point(POINT_ON);
pinMode(checkbranche, INPUT);
pinMode(checkbrancheb, INPUT);
pinMode(checkbranchec, INPUT);
pinMode(checkstart, INPUT);
pinMode(speakerPin, OUTPUT);
pinMode(LED_jeu1_V, OUTPUT);
pinMode(LED_jeu1_R, OUTPUT);
pinMode(LED_jeu2_V, OUTPUT);
pinMode(LED_jeu2_R, OUTPUT);
pinMode(LED_jeu3_V, OUTPUT);
pinMode(LED_jeu3_R, OUTPUT);
pinMode(LED_jglobal1, OUTPUT);
pinMode(LED_jglobal2, OUTPUT);
pinMode(LED_jglobal3, OUTPUT);
pinMode(LED_jglobal4, OUTPUT);
delay(1000);
};
// запустить цикл (навсегда)
void loop() {
readingstart = digitalRead(checkstart);
reading = digitalRead(checkbranche);
readingb = digitalRead(checkbrancheb);
readingc = digitalRead(checkbranchec);
if (runcode < 1) {
Serial.println("WHAT");
if (readingstart == HIGH) {
for (; runOPEN < 1; runOPEN++) {
uhoh();
}
countdown();
Serial.print(halfsecond);
Serial.println(" ");
if (dismentel1 == 1) {digitalWrite(LED_jglobal1, HIGH);} else {digitalWrite(LED_jglobal1, LOW);}
if (dismentel2 == 1) {digitalWrite(LED_jglobal2, HIGH);} else {digitalWrite(LED_jglobal2, LOW);}
if (dismentel3 == 1) {digitalWrite(LED_jglobal3, HIGH);} else {digitalWrite(LED_jglobal3, LOW);}
if (dismentel4 == 1) {digitalWrite(LED_jglobal4, HIGH);} else {digitalWrite(LED_jglobal4, LOW);}
// ЖЕЛЕЗНАЯ ИНФОРМАЦИЯ 1 //
if (reading == LOW) { //ВЕРСИЯ 1 HIGH -> НИЗКИЙ
countdown1();
if (second1 > 0 && minute1 >= 0) {
int8_t timeDisp1[4];
timeDisp1[0] = minute1 / 10;
timeDisp1[1] = minute1 % 10;
timeDisp1[2] = second1 / 10;
timeDisp1[3] = second1 % 10;
tm1637b.display(timeDisp1);
if (minute1 < accessgame) {
digitalWrite(LED_jeu1_V, LOW);
digitalWrite(LED_jeu1_R, HIGH);
} else {
digitalWrite(LED_jeu1_V, HIGH);
digitalWrite(LED_jeu1_R, LOW);
}
dismentel1 = 0;
} else {
displaya.print("FAIL");
digitalWrite(LED_jeu1_V, HIGH);
digitalWrite(LED_jeu1_R, LOW);
for (; runJEU1 < 1; runJEU1++) {
squeak();
}
fail1 = 1;
}
} else {
displaya.print("--5-");
digitalWrite(LED_jeu1_V, LOW);
digitalWrite(LED_jeu1_R, HIGH);
for (; winJEU1 < 1; winJEU1++) {
wingame();
}
dismentel1 = 1;
}
// ЖЕЛЕЗНАЯ ИНФОРМАЦИЯ 1 //
// ЖЕЛЕЗНАЯ ВЕРСИЯ 2 //
if (readingb == HIGH) {
dismentel2 = 1;
}
if ((dismentel1 == 1 or fail1 == 1) && dismentel2 == 0) {
countdown2();
if (second2 > 0 && minute2 >= 0) {
int8_t timeDisp2[4];
timeDisp2[0] = minute2 / 10;
timeDisp2[1] = minute2 % 10;
timeDisp2[2] = second2 / 10;
timeDisp2[3] = second2 % 10;
tm1637c.display(timeDisp2);
if (minute2 < accessgame) {
digitalWrite(LED_jeu2_V, LOW);
digitalWrite(LED_jeu2_R, HIGH);
} else {
digitalWrite(LED_jeu2_V, HIGH);
digitalWrite(LED_jeu2_R, LOW);
}
dismentel2 = 0;
} else {
displayb.print("FAIL");
digitalWrite(LED_jeu2_V, HIGH);
digitalWrite(LED_jeu2_R, LOW);
for (; runJEU2 < 1; runJEU2++) {
squeak();
}
fail2 = 1;
}
} else if ((dismentel1 == 1 or fail1 == 1) && dismentel2 == 1){
displayb.print("-7--");
digitalWrite(LED_jeu2_V, LOW);
digitalWrite(LED_jeu2_R, HIGH);
for (; winJEU2 < 1; winJEU2++) {
wingame();
}
dismentel2 = 1;
} else {
displayb.print("----");
digitalWrite(LED_jeu2_V, HIGH);
digitalWrite(LED_jeu2_R, HIGH);
}
// ЖЕЛЕЗНАЯ ВЕРСИЯ 2 //
// ЖЕЛЕЗНАЯ ВЕРСИЯ 3 //
if (readingc == HIGH) {
dismentel3 = 1;
}
if ((dismentel2 == 1 or fail2 == 1) && dismentel3 == 0) {
countdown3();
if (second3 > 0 && minute3 >= 0) {
int8_t timeDisp3[4];
timeDisp3[0] = minute3 / 10;
timeDisp3[1] = minute3 % 10;
timeDisp3[2] = second3 / 10;
timeDisp3[3] = second3 % 10;
tm1637d.display(timeDisp3);
if (minute3 < accessgame) {
digitalWrite(LED_jeu3_V, LOW);
digitalWrite(LED_jeu3_R, HIGH);
} else {
digitalWrite(LED_jeu3_V, HIGH);
digitalWrite(LED_jeu3_R, LOW);
}
dismentel3 = 0;
} else {
displayc.print("FAIL");
digitalWrite(LED_jeu3_V, HIGH);
digitalWrite(LED_jeu3_R, LOW);
for (; runJEU3 < 1; runJEU3++) {
squeak();
}
fail3 = 1;
}
} else if ((dismentel2 == 1 or fail2 == 1) && dismentel3 == 1){
displayc.print("---1");
digitalWrite(LED_jeu3_V, LOW);
digitalWrite(LED_jeu3_R, HIGH);
for (; winJEU3 < 1; winJEU3++) {
wingame();
}
dismentel3 = 1;
} else {
displayc.print("----");
digitalWrite(LED_jeu3_V, HIGH);
digitalWrite(LED_jeu3_R, HIGH);
}
} else {
second=0; minute=45; hour=0; // объявляем временные переменные
second1=0; minute1=15; hour1=0; // объявляем временные переменные
second2=0; minute2=15; hour2=0; // объявляем временные переменные
second3=0; minute3=15; hour3=0; // объявляем временные переменные
previousTime = 0;// хранит предыдущее время в мс
previousTime1 = 0;// хранит предыдущее время в мс
previousTime2 = 0;// хранит предыдущее время в мс
previousTime3 = 0;// хранит предыдущее время в мс
previousDelay = 0;// хранит предыдущее время в мс, так как зуммер был активен
previousDelay1 = 0;// хранит предыдущее время в мс, так как зуммер был активен
previousDelay2 = 0;// хранит предыдущее время в мс, так как зуммер был активен
previousDelay3 = 0;// хранит предыдущее время в мс, так как зуммер был активен
interval = 60000;//задержка 60 секунд
interval1 = 60000;//задержка 60 секунд
interval2 = 60000;//задержка 60 секунд
interval3 = 60000;//задержка 60 секунд
runOPEN = 0;
dismentel1 = 0; fail1 = 0;
dismentel2 = 0; fail2 = 0;
dismentel3 = 0; fail3 = 0;
dismentel4 = 0; fail4 = 0;
displaya.print("- ");
displayd.print("- ");
}
}
// ЖЕЛЕЗНАЯ ВЕРСИЯ 3 //
// ПРОВЕРКА ГЛОБАЛЬНОГО ЦИФРОВОГО ПАРАМЕТРА //
char Key;
byte KState = KP.Key_State();
if (KState == PRESSED) {
if ( Key = KP.Getkey() ) {
Serial << "Pressed: " << Key << "\n";
switch (Key) {
case '*': checkPassword(); break;
case '#': password.reset(); break;
default: password.append(Key);
}
}
}
else if (KState == HELD) {
Serial << "Key:" << KP.Getkey() << " being held\n";
}
// ПРОВЕРКА ГЛОБАЛЬНОГО ЦИФРОВОГО ПАРАМЕТРА //
};
void beep (int speakerPin, float noteFrequency, long noteDuration)
{
int x;
// Преобразование частоты в микросекунды
float microsecondsPerWave = 1000000/noteFrequency;
// Подсчитаем, сколько циклов HIGH/LOW приходится на миллисекунду
float millisecondsPerCycle = 1000/(microsecondsPerWave * 2);
// Умножить noteDuration * количество циклов в миллисекунду
float loopTime = noteDuration * millisecondsPerCycle;
// Воспроизведение ноты в течение рассчитанного цикла loopTime.
for (x=0;x<loopTime;x++)
{
digitalWrite(speakerPin,HIGH);
delayMicroseconds(microsecondsPerWave);
digitalWrite(speakerPin,LOW);
delayMicroseconds(microsecondsPerWave);
}
}
void waka() {
for (int i=1000; i<3000; i=i*1.05) {
beep(speakerPin,i,10);
}
delay(100);
for (int i=2000; i>1000; i=i*.95) {
beep(speakerPin,i,10);
}
for (int i=1000; i<3000; i=i*1.05) {
beep(speakerPin,i,10);
}
delay(100);
for (int i=2000; i>1000; i=i*.95) {
beep(speakerPin,i,10);
}
for (int i=1000; i<3000; i=i*1.05) {
beep(speakerPin,i,10);
}
delay(100);
for (int i=2000; i>1000; i=i*.95) {
beep(speakerPin,i,10);
}
for (int i=1000; i<3000; i=i*1.05) {
beep(speakerPin,i,10);
}
delay(100);
beep(speakerPin, note_Bb5,300); //Б б
delay(50);
beep(speakerPin, note_C6,300); //С
delay(50);
beep(speakerPin, note_Ab5,300); //А б
delay(50);
beep(speakerPin, note_Ab4,300); //А б
delay(50);
beep(speakerPin, note_Eb5,500); //Е б
delay(500);
}
void squeak() {
// для (целое i=100; i < 5000; i=i*1.45) {
// звуковой сигнал (SpeakerPin, i, 60);
// }
// delay(10);
for (int i=3500; i>10; i=i/1.15) {
beep(speakerPin,i,60);
}
}
void wingame() {
for (int i=100; i<5000; i=i*1.45) {
beep(speakerPin,i,60);
}
}
void uhoh() {
for (int i=1000; i<2000; i=i*1.10) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i>500; i=i*.90) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i<2000; i=i*1.10) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i>500; i=i*.90) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i<2000; i=i*1.10) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i>500; i=i*.90) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i<2000; i=i*1.10) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i>500; i=i*.90) {
beep(speakerPin,i,10);
}
delay(50);
for (int i=1000; i<5000; i=i*1.05) {
beep(speakerPin,i,10);
}
delay(300);
for (int i=1000; i<3000; i=i*1.03) {
beep(speakerPin,i,10);
}
for (int i=3000; i>1000; i=i*.97) {
beep(speakerPin,i,10);
}
}
void checkPassword()
{
if (password.evaluate()) {
Serial.println("Success");
runcode = 1;
displayd.print(" YOU");
displayd.print(" YOU");
displaya.print(" ARE");
displaya.print(" ARE");
displayb.print(" THE");
displayb.print(" THE");
displayc.print("BEST");
displayc.print("BEST");
digitalWrite(LED_jglobal4, HIGH);
for (; winGLOBAL < 1; winGLOBAL++) {
waka();
}
password.reset();
} else {
Serial.println("Wrong");
password.reset();
for (; looseGLOBAL < 1; looseGLOBAL++) {
squeak();
looseGLOBAL = 0;
}
}
}
/**********************************************************************
* GLOBAL *
**********************************************************************/
void countdown(){
static unsigned long lastTick = 0; // устанавливаем локальную переменную для хранения последнего времени, когда мы уменьшаем значение на одну секунду
static unsigned long currentMillis = 0;
// (статические переменные инициализируются один раз и сохраняют свои значения между вызовами функций)
// уменьшаем до одной секунды каждые 1000 миллисекунд
if (second > 0) {
if (millis() - lastTick >= 1000) {
lastTick = millis();
second--;
int8_t timeDisp[4];
timeDisp[0] = minute / 10;
timeDisp[1] = minute % 10;
timeDisp[2] = second / 10;
timeDisp[3] = second % 10;
tm1637a.display(timeDisp);
tm1637a.point(POINT_ON);
}
} else {
displayd.print("FAIL");
for (; runFAILGLOBAL < 1; runFAILGLOBAL++) {
squeak();
}
}
// уменьшаем на одну минуту каждые 60 секунд
if (minute > 0) {
if (second <= 0) {
minute--;
second = 60; // сбросить секунды до 60
}
}
// уменьшаем на один час каждые 60 минут
if (hour > 0) {
if (minute <= 0) {
hour--;
minute = 60; // сброс минут до 60
}//закрыть, если
}//закрыть, если
//приведенный ниже код издает звуковой сигнал сирены раз в минуту.
currentMillis = millis();
if (currentMillis - previousTime > interval)
{
previousTime = currentMillis;
previousDelay = currentMillis;
}
if (currentMillis - previousDelay > 100) {//длительность щебета 100 мс
}
} // закрыть обратный отсчет();
/**********************************************************************
* JEU1 *
**********************************************************************/
void countdown1(){
static unsigned long lastTick1 = 0; // устанавливаем локальную переменную для хранения последнего времени, когда мы уменьшаем значение на одну секунду
static unsigned long currentMillis1 = 0;
// (статические переменные инициализируются один раз и сохраняют свои значения между вызовами функций)
// уменьшаем до одной секунды каждые 1000 миллисекунд
if (second1 > 0) {
if (millis() - lastTick1 >= 1000) {
lastTick1 = millis();
second1--;
}
}
// уменьшаем на одну минуту каждые 60 секунд
if (minute1 > 0) {
if (second1 <= 0) {
minute1--;
second1 = 60; // сбросить секунды до 60
}
}
// уменьшаем на один час каждые 60 минут
if (hour1 > 0) {
if (minute1 <= 0) {
hour1--;
minute1 = 60; // сброс минут до 60
}//закрыть, если
}//закрыть, если
//приведенный ниже код издает звуковой сигнал сирены раз в минуту.
currentMillis1 = millis();
if (currentMillis1 - previousTime1 > interval1)
{
previousTime1 = currentMillis1;
previousDelay1 = currentMillis1;
}
if (currentMillis1 - previousDelay1 > 100) {//длительность щебета 100 мс
}
} //закрыть обратный отсчет1();
/**********************************************************************
* JEU2 *
**********************************************************************/
void countdown2(){
static unsigned long lastTick2 = 0; // устанавливаем локальную переменную для хранения последнего времени, когда мы уменьшаем значение на одну секунду
static unsigned long currentMillis2 = 0;
// (статические переменные инициализируются один раз и сохраняют свои значения между вызовами функций)
// уменьшаем до одной секунды каждые 1000 миллисекунд
if (second2 > 0) {
if (millis() - lastTick2 >= 1000) {
lastTick2 = millis();
second2--;
}
}
// уменьшаем на одну минуту каждые 60 секунд
if (minute2 > 0) {
if (second2 <= 0) {
minute2--;
second2 = 60; // сбросить секунды до 60
}
}
// уменьшаем на один час каждые 60 минут
if (hour2 > 0) {
if (minute2 <= 0) {
hour2--;
minute2 = 60; // сброс минут до 60
}//закрыть, если
}//закрыть, если
//приведенный ниже код издает звуковой сигнал сирены раз в минуту.
currentMillis2 = millis();
if (currentMillis2 - previousTime2 > interval1)
{
previousTime2 = currentMillis2;
previousDelay2 = currentMillis2;
}
if (currentMillis2 - previousDelay2 > 100) {//длительность щебета 100 мс
}
} //закрыть обратный отсчет2();
/**********************************************************************
* JEU3 *
**********************************************************************/
void countdown3(){
static unsigned long lastTick3 = 0; // устанавливаем локальную переменную для хранения последнего времени, когда мы уменьшаем значение на одну секунду
static unsigned long currentMillis3 = 0;
// (статические переменные инициализируются один раз и сохраняют свои значения между вызовами функций)
// уменьшаем до одной секунды каждые 1000 миллисекунд
if (second3 > 0) {
if (millis() - lastTick3 >= 1000) {
lastTick3 = millis();
second3--;
}
}
// уменьшаем на одну минуту каждые 60 секунд
if (minute3 > 0) {
if (second3 <= 0) {
minute3--;
second3 = 60; // сбросить секунды до 60
}
}
// уменьшаем на один час каждые 60 минут
if (hour3 > 0) {
if (minute3 <= 0) {
hour3--;
minute3 = 60; // сброс минут до 60
}//закрыть, если
}//закрыть, если
//приведенный ниже код издает звуковой сигнал сирены раз в минуту.
currentMillis3 = millis();
if (currentMillis3 - previousTime3 > interval1)
{
previousTime3 = currentMillis3;
previousDelay3 = currentMillis3;
}
if (currentMillis3 - previousDelay3 > 100) {//100 мс продолжительность щебета
}
} //закрыть обратный отсчет2();
@Fluti, 👍0
1 ответ
Этот код беспорядок. Я уверен, что вы можете реорганизовать многое из этого. Для начала вот класс C++, который можно использовать в качестве таймера обратного отсчета. Я просто на скорую руку это, но это должно работать. Однако он не обрабатывает случай, когда millis()
переполняется (примерно через 50 дней).
class Countdown {
public:
const uint32_t ms_per_hour = 60l * 60l * 1000l;
const uint32_t ms_per_minute = 60l * 1000l;
const uint32_t ms_per_second = 1000l;
// Конструктор
Countdown(int hours, int minutes, int seconds) {
duration = hours * ms_per_hour +
minutes * ms_per_minute +
seconds * ms_per_second ;
started = false;
finished = false;
}
// Вызовите это, чтобы начать обратный отсчет
void start() {
started = true;
finished = false;
start_time = millis();
}
// Остановить таймер
void stop() {
finished = true;
}
// Таймер запущен?
bool is_running() {
return started == true && finished == false;
}
// Вызовите это, чтобы проверить, завершен ли обратный отсчет
bool times_up() {
if (finished) return true;
else if (!started) return false;
if (elapsed_time() >= duration) {
finished = true;
return true;
}
return false;
}
// Возвращает строковое представление того, сколько времени прошло
const char * get_elapsed(const char *format="hh:mm:ss") {
return ms_to_string(format, elapsed_time());
}
// Возвращает строковое представление того, сколько времени осталось
const char * get_remaining(const char *format="hh:mm:ss") {
return ms_to_string(format, duration - elapsed_time());
}
// Возвращает массив десятичных цифр для отображения прошедшего времени
const char * get_digits_elapsed(const char *format="mmss") {
return ms_to_digits(format, elapsed_time());
}
// Возвращает массив десятичных цифр для отображения оставшегося времени
const char * get_digits_remaining(const char *format="mmss") {
return ms_to_digits(format, duration - elapsed_time());
}
protected:
unsigned long elapsed_time() {
return millis() - start_time;
}
bool started, finished;
uint32_t duration, start_time;
char buffer[32];
char * ms_to_digits(const char *format, uint32_t ms) {
uint16_t hours = ms / ms_per_hour;
ms %= ms_per_hour;
uint16_t minutes = ms / ms_per_minute;
ms %= ms_per_minute;
uint16_t seconds= ms / ms_per_second;
int index = 0;
for (int i = 0; 0 != format[i]; i++) {
if ('h' == format[i] || 'm' == format[i] || 's' == format[i]) {
uint16_t val = 'h' == format[i] ? hours : ('m' == format[i] ? minutes : seconds);
if (format[i] == format[i+1]) {
buffer[index++] = (char)(val / 10);
i += 1;
}
buffer[index++] = char(val % 10);
}
}
return buffer;
}
char * ms_to_string(const char *format, uint32_t ms) {
uint16_t hours = ms / ms_per_hour;
ms %= ms_per_hour;
uint16_t minutes = ms / ms_per_minute;
ms %= ms_per_minute;
uint16_t seconds= ms / ms_per_second;
buffer[0] = 0;
int index = 0;
for (int i = 0; 0 != format[i]; i++) {
if ('h' == format[i] || 'm' == format[i] || 's' == format[i]) {
uint16_t val = 'h' == format[i] ? hours : ('m' == format[i] ? minutes : seconds);
if (format[i] == format[i+1]) {
index += sprintf(&buffer[index], "%02d", val);
i += 1;
}
else {
index += sprintf(&buffer[index], "%d", val);
}
}
else {
buffer[index++] = format[i];
}
}
buffer[index] = '\0';
return buffer;
}
};
Чтобы использовать его, вы должны создать 3 объекта:
Countdown cd1(0, 45, 0); // 45 минут
Countdown cd2(0, 15, 0); // 15 минут
Countdown cd3(0, 15, 0); // 15 минут
Затем запустите #1 в настройках:
void setup() {
cd1.start();
}
И в цикле:
void loop() {
if (cd3.times_up()) {
// игра закончена
}
else if (cd2.times_up()) {
// 2-й таймер истек, сделайте что-нибудь
if (!cd3.is_running()) cd3.start(); // Старт №3
// обновить дисплей
tm1637d.display(c3.get_digits_remaining());
}
else if (cd1.times_up()) {
// 1-й таймер истек, сделайте что-нибудь
if (!cd2.is_running()) cd2.start(); // Старт #2
// обновить дисплей
tm1637c.display(c2.get_digits_remaining());
}
else {
// обновить дисплей
tm1637b.display(c1.get_digits_remaining());
}
}
- Использование millis() и micros() внутри процедуры прерывания
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Использовать timer0, не влияя на millis() и micros().
- Сброс Arduino с помощью ПО (каждый день)
- Как отслеживать миллисекунды в спящем режиме
- Отрегулируйте расчет времени после изменения частоты Timer0
- Arduino Mega TIMER1 интервал в одну секунду
- Нельзя использовать millis() вместо задержки
Вы написали: «_это не обрабатывает случай, когда
millis()
переполняется_». Ваш код прекрасно обрабатывает ролловерmillis()
., @Edgar Bonet@EdgarBonet Ах, да. Ты прав. Спасибо что подметил это., @Johnny Mopp
Спасибо за ответ. Я понимаю ваш код, но я не знаю, как показать обратный отсчет на 4-значном дисплее с этим кодом., @Fluti
А также как остановить обратный отсчет с помощью
if (reading == LOW)
, но я попробую. Благодарю вас !, @Fluti@Fluti Хорошо, я добавил функцию для возврата времени в виде массива цифр. Также добавлена функция
stop()
., @Johnny Mopp