compte a rebours TM1637

Bonjour à tous,

Je souhaite réaliser un compte à rebours avec un affichage led 4digits 7 segment monter sur un TM1637.

J'ai chopé un bout de code qui me va plutôt bien sauf que je ne sais le faire décompter 127 secondes soit 02:07...à 128 il me remet le compteur a zéro quand j'appuie sur start.

voici le code en question :

//********************************************************
// Afficheur 4 chiffres 7 segments
// avec Driver TM1637 et Arduino
// demo_7segment_i2c_clock
//
// Affiche une horloge 12:00 sous format hh:mm ou mm:ss
//
//********************************************************

#include <TimerOne.h>
#include "TM1637.h" //librairie du driver du 7 segments
#define ON 1
#define OFF 0
#define hhmm 1 //0 pour afficher HH:MM et 1 pour MM:SS

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00}; //Tableau des 4 chiffres
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char halfsecond = 2;
unsigned char second = 00;
unsigned char _second = 0;
unsigned char minute = 20;
unsigned char _minute = 0;
unsigned char hour = 12; //Heure 12:00:00 pour initialiser
boolean Flag_ReadTime;
signed char temps = 90; //??? minutes en secondes (max127???)
int b_start;
boolean etat_start; //Etat
int b_pause;
boolean etat_pause;
int b_reset;
boolean etat_reset;

// branchement TM1637 sur CLK A1 et DIO A0
#define CLK A1
#define DIO A0
TM1637 tm1637(CLK,DIO); //Objet tm1637

void setup()
{
Serial.begin(9600);
tm1637.set(2); //0 éclairage faible réglable jusqu'à 7 le plus intense
tm1637.init(); //Initialisation du driver
tm1637.point(POINT_ON);
//Affichage de départ ABCD (le module peut afficher abcdef)
//TimeDisp[0] = 10; //Affichage a
//TimeDisp[1] = 11; //b
//TimeDisp[2] = 12; //c
//TimeDisp[3] = 13; //d
//tm1637.display(TimeDisp);
//delay(5000); //Pendant 5 sec

//Horloge mise à jour 2 fois par seconde pour faire clignotter le :
Timer1.initialize(500000); // timing pour 500ms
Timer1.attachInterrupt(TimingISR); //declare l'interruption qui déclenche TimingISR
Serial.println("Please send command to control the stopwatch:");
Serial.println("S - start");
Serial.println("P - pause");
Serial.println("R - reset");
stopwatchPause();

// Boutons
b_start = 11;
etat_start = 0;
b_pause = 12;
etat_pause = 0;
b_reset = 13;
etat_reset = 0;

// définition des modes
pinMode(b_start, INPUT_PULLUP);
pinMode(b_pause, INPUT_PULLUP);
pinMode(b_reset, INPUT_PULLUP);
}


void loop()
{
// Déclenchement chrono/pause/reset
 etat_start = digitalRead(b_start); 
    if(etat_start == LOW) 
    {
        stopwatchStart(); 
    }

 etat_pause = digitalRead(b_pause); 
    if(etat_pause == LOW) 
    {
        stopwatchPause(); 
    }

 etat_reset = digitalRead(b_reset); 
    if(b_reset == LOW) 
    {
        stopwatchReset(); 
    }

  //Commande chrono
char command;
command = Serial.read();

switch(command)
{
//case 'S':stopwatchStart();Serial.println("Start timing...");break;
//case 'P':stopwatchPause();Serial.println("Stopwatch was paused");break;
case 'R':stopwatchReset();Serial.println("Stopwatch was reset");break;
default:break;
}
if(Update == ON)
{
TimeUpdate();
tm1637.display(TimeDisp);
}
}
 void TimingISR()
{
  halfsecond --;
  Update = ON;
  if (halfsecond <= 0)
  {
    temps = max(temps-1,0);
    second  = temps%60;
    minute = temps/60;
    halfsecond = 2;
  }
 // Serial.println(second);
      ClockPoint = (~ClockPoint) & 0x01;
      if(Flag_ReadTime == 0)
    {
      _second = second;
      _minute = minute;
    }
  }



void TimeUpdate(void)
{
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF); //OFF Pour clignotement
if (hhmm==0)
{
TimeDisp[0] = hour / 10; //Affichage hh:mm
TimeDisp[1] = hour % 10;
TimeDisp[2] = minute / 10;
TimeDisp[3] = minute % 10;
}
else
{
//Affichage mm:ss
TimeDisp[0] = minute / 10; //Affichage hh:mm
TimeDisp[1] = minute % 10;
TimeDisp[2] = second / 10;
TimeDisp[3] = second % 10;
}
Update = OFF;
}

void stopwatchStart()//timer1 on
{
Flag_ReadTime = 0;
TCCR1B |= Timer1.clockSelectBits;
}
void stopwatchPause()//timer1 off if [CS12 CS11 CS10] is [0 0 0].
{
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
}
void stopwatchReset()
{
stopwatchPause();
Flag_ReadTime = 0;
_second = 0;
_minute = 0;
second = 30;
minute = 1;
temps = 90;
Update = ON;
}

Merci d'avance pour votre aide, d'autant qu'après je risque de vous sollicité de nouveau car j'aimerais remplacer le bouton pause par un bouton qui ajoute 5min :smiley:

J'ai trouvé!

j'ai remplacer signed char temps = 1200; par signed short int temps = 1200;
Maintenant je vais voir pour ajouter des minutes lol

pour ajouter des minutes :

void stopwatchAddtime()
{
temps = temps + 300; //secondes ajouter avec bouton +
}

évidement cela ne fonctionne pas, trop simple :-p

Un char, c'est comme un byte : ça varie entre 0 et 255. Si ça sert à compter des secondes, ça te limite à 4 minutes et 15 secondes. S'il tu le déclares "signed", il varie entre -128 et 127. 127 secondes c'est 2 minutes 07. D'où ton résultat.

Donc :

  • A moins d'envisager des temps négatifs, ne déclares pas une variable de temps en "signed" car ça te fait perdre sur la durée. Utilise du "unsigned"
  • Choisis ton type de variable en fonction des valeurs qu'elle peut prendre. Un "unsigned int" utilisera 2 octets pour compter jusqu'à 65535 soit plus de 18 heures. Tu as de la marge.

Pour le bouton, ta fonction devrait marcher. Le problème est peut-être dans la lecture ou la connexion du bouton... Poste ton nouveau code (pour vérifier) et décris ta connexion.

Merci pour ta réponse,

J'ai fais les changements ça décompte nickel.

voici le code comme il est actuellement :

#include <TimerOne.h>
#include "TM1637.h" 
#define ON 1
#define OFF 0
#define hhmm 1 //0 pour afficher HH:MM et 1 pour MM:SS

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00}; 
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char halfsecond = 2;
unsigned char second = 00;
unsigned char _second = 0;
unsigned char minute = 20;
unsigned char _minute = 0;
unsigned char hour = 12; 
boolean Flag_ReadTime;
unsigned int temps = 1200; //minutes en secondes à décompter
int b_start;
boolean etat_start; //Etat
int b_pause;
boolean etat_pause;
int b_reset;
boolean etat_reset;
int b_addtime;
boolean etat_addtime;

// branchement TM1637 sur CLK A1 et DIO A0
#define CLK A1
#define DIO A0
TM1637 tm1637(CLK,DIO);

void setup()
{
Serial.begin(9600);
tm1637.set(2); 
tm1637.init(); 
tm1637.point(POINT_ON);


//Horloge mise à jour 2 fois par seconde pour faire clignotter le :
Timer1.initialize(500000); // timing pour 500ms
Timer1.attachInterrupt(TimingISR); //declare l'interruption qui déclenche TimingISR
Serial.println("Please send command to control the stopwatch:");
Serial.println("S - start");
Serial.println("P - pause");
Serial.println("R - reset");
Serial.println("A - Addtime");
stopwatchPause();

// Boutons
b_addtime = 10;
etat_addtime = 0;
b_start = 11;
etat_start = 0;
b_pause = 12;
etat_pause = 0;
b_reset = 13;
etat_reset = 0;

// définition des modes
pinMode(b_start, INPUT_PULLUP);
pinMode(b_pause, INPUT_PULLUP);
pinMode(b_reset, INPUT_PULLUP);
pinMode(b_addtime, INPUT_PULLUP);
}


void loop()
{
// Déclenchement chrono/pause/reset/addtime
 etat_start = digitalRead(b_start); 
    if(etat_start == LOW) 
    {
        stopwatchStart(); 
    }

 etat_pause = digitalRead(b_pause); 
    if(etat_pause == LOW) 
    {
        stopwatchPause(); 
    }

 etat_reset = digitalRead(b_reset); 
    if(etat_reset == LOW) 
    {
        stopwatchReset(); 
    }

etat_addtime = digitalRead(b_addtime); 
    if(etat_addtime == LOW) 
    {
        stopwatchAddtime(); 
    }

  //Commande chrono
char command;
command = Serial.read();

switch(command)
{
case 'S':stopwatchStart();Serial.println("Start timing...");break;
case 'P':stopwatchPause();Serial.println("Stopwatch was paused");break;
case 'R':stopwatchReset();Serial.println("Stopwatch was reset");break;
case 'A':stopwatchAddtime();Serial.println("Stopwatch add 5 second");break;
//default:break;
}
if(Update == ON)
{
TimeUpdate();
tm1637.display(TimeDisp);
}
}
 void TimingISR()
{
  halfsecond --;
  Update = ON;
  if (halfsecond <= 0)
  {
    temps = max(temps-1,0);
    second  = temps%60;
    minute = temps/60;
    halfsecond = 2;
  }
//Serial.println(minute);
      ClockPoint = (~ClockPoint) & 0x01;
      if(Flag_ReadTime == 0)
    {
      _second = second;
      _minute = minute;
    }
  }



void TimeUpdate(void)
{
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF); //OFF Pour clignotement
if (hhmm==0)
{
TimeDisp[0] = hour / 10; //Affichage hh:mm
TimeDisp[1] = hour % 10;
TimeDisp[2] = minute / 10;
TimeDisp[3] = minute % 10;
}
else
{
//Affichage mm:ss
TimeDisp[0] = minute / 10; //Affichage hh:mm
TimeDisp[1] = minute % 10;
TimeDisp[2] = second / 10;
TimeDisp[3] = second % 10;
}
Update = OFF;
}

void stopwatchStart()//timer1 on
{
Flag_ReadTime = 0;
TCCR1B |= Timer1.clockSelectBits;
}

void stopwatchPause()//timer1 off if [CS12 CS11 CS10] is [0 0 0].
{
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
}


void stopwatchReset()
{
stopwatchPause();
Flag_ReadTime = 0;
_second = 0;
_minute = 0;
second = 00;
minute = 20;
temps = 1200;
Update = ON;
}


void stopwatchAddtime()
{
temps = temps + 300; //secondes ajouter avec bouton +
}

la fonction du bouton addtime est au fond du code...quand j'appuie sur le bouton, il m'affiche des trucs bizarre.

voici le montage :

Ajoute un Serial.println(temps); à la fin de ta fonction stopwatchAddtime pour voir ce que devient cette valeur.
Tu dis que la commande "A" ajoute 5 secondes (dans un println) mais elle ajoute en fait 5 minutes.

Au Clavier cela fonctionne, mais pas avec le bouton...

Please send command to control the stopwatch:
S - start
P - pause
R - reset
A - Addtime
Start timing...
1199
1199
1198
1198
1197
1497
Stopwatch add 5 minutes
1497
1496
1496
1495
1495
1494
1494
1493
1493
1492
Stopwatch was paused

Le problème vient du bouton...quand j'appuie, il ajoute bien les 300 secondes mais le temps de l'appuis ce qui monte le conteur a une vitesse folle :

A - Addtime
1199
1199
1198
1198
1197
1197
1497
1797
2097
2397
2697
2997....

je tente un delay?

Voila ^^ j'ai créer une variable addtime (pour ne pas changer les paramètres a 36 places dans le sketch) puis j'ai ajouter un delay :

void stopwatchAddtime()
{
temps = temps + addtime;
delay(500);
Serial.println(temps);
}

Merci beaucoup du coup :wink:

De rien
Le delay te bloque un peu, tu peux certainement descendre à 200 ms ou moins.
Au lieu d'une variable, tu peux faire un #define addtime 300 tu gagneras un peu de mémoire... :slight_smile:

Super ça tourne comme une horloge! lol

et j'en ai appris que demande le peuple :wink: merci encore

Cool !

Maintenant je reviendrais certainement, car la suite c'est un buzzer qui bip à 5min et qui bip a chaque secondes à partir de 10 sec...mais ça c'est une autre histoire lol

Dans ce cas, un peu de lecture préliminaire ne fera pas de mal :