Go Down

Topic: [RESOLU] Clignotement sur afficheur 7 Segments avec SEVSEG (Read 658 times) previous topic - next topic

Nico1510

Bonjour à tous !!

J'ai fait un petit chronomètre à l'aide d'un Arduino Nano et d'un afficheur 7 segments 4 digits couplé à deux boutons poussoirs classiques ( play/pause et reset).

J'ai utilisé la librairie Sevseg pour faire fonctionner tout ça et à ma grande joie, cela fonctionne !  :D

Mais malheureusement, impossible de faire clignoter les 2 points de séparations entre les heures et les minutes.

Si quelqu'un pouvait me dire la ligne ou la manie' à faire avec Sevseg, je serais ravi.  :D

L'afficheur 7 segments est un CL5642BH-30 : http://mklec.com/displays/7-segment-4-digit-12-pin-common-anode-display et je vous mets en pièce jointe les branchements entre l'Arduino et l'afficheur.

Voici également le programme :

Code: [Select]
// Importation biblio sevseg
#include "SevSeg.h"

// assignation 7-segment
SevSeg sevseg;

// Assignation bouton chronometre : play/pause bouton 1 et reset bouton 2
int pinBouton1 = 3;
int pinBouton2 = 2;

// Variable pour definir si le chrono est en route
boolean run = false;

// Definition des etats boutons
int etatBouton1 = LOW;
int lastEtatBouton1 = LOW;
int etatBouton2 = LOW;
int lastEtatBouton2 = LOW;

long lastPressedBtn1 = 0;
long lastPressedBtn2 = 0;

// Variables utiles
long timer = 0;
int tenth = 0;
int secondes = 0;
int minutes = 0;
int heures = 0;

void setup(){
  Serial.begin(9600);
  
  byte numDigits = 4; // 7segments avec 4 digits
  byte digitPins[] = {12, 13, A0, A1}; // Correspondance 7segments : Digit1 Digit2 Digit3 Digit4
  byte segmentPins[] = {11, 9, 7, 5, 4, 10, 8, 6}; // Correspondance 7segments : A B C D E F DP
  bool resistorsOnSegments = false; // 'false' => resistances sur les pins digitales
  byte hardwareConfig = COMMON_ANODE;
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = false; // Mettre 'true' pour afficher les 0 'avant' les chiffres
  
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);
  
}

void loop(){
  
  if((timer - millis()/100) >= 100 || timer == 0)
  {  
    if(run)
    {
            
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      // afficher les minutes et secondes sur afficheur 7 segments
      sevseg.setNumber(heures * 100 + minutes, 0);
      
      if(tenth == 9)
      {
        tenth = 0;
        
        if(secondes == 59)
        {
          secondes = 0;
          minutes++;      
        }
        else if(minutes == 59)
        {
          minutes = 0;
          heures++;
        }
        else
        {
          secondes++;
        }
      }
      else
      {
        tenth++;
      }
    }
    timer = millis()/100;
  }
    
  etatBouton1 = digitalRead(pinBouton1);
  etatBouton2 = digitalRead(pinBouton2);
  
  if(etatBouton1 != lastEtatBouton1) // Verifier si l'etat bouton1 a change
  {    
    if(etatBouton1 == HIGH && (millis()-lastEtatBouton1) > 100 || lastEtatBouton1 == 0)
    {
      lastPressedBtn1 = millis();
      run = !run; // Changement d'etat entre play et pause
    }    
  }
  
  lastEtatBouton1 = etatBouton1;    // Recuperer etat bouton1 comme dernier etat bouton1
  
  if(etatBouton2 != lastEtatBouton2) // Verifier si l'etat bouton2 a change
  {
    if(etatBouton2 == HIGH && (millis()-lastEtatBouton2) > 100 || lastEtatBouton2 == 0) // Remise a 0
    {  
      lastPressedBtn2 = millis();
      run = false;
      secondes = 0;
      minutes = 0;
      heures = 0;
      tenth = 0;
      
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      // afficher les minutes et secondes sur afficheur 7 segments
      sevseg.setNumber(heures * 100 + minutes, 0);    
    }    
  }
  
  lastEtatBouton2 = etatBouton2;   // Recuperer etat bouton2 comme dernier etat bouton2

  sevseg.refreshDisplay();
  
}

void affichage()
{  
  // Affichage Serial
  if(heures < 10) // Si les heures n'ont pas 2 digits
  {
    Serial.print("0");    
  }
  Serial.print(heures);
  Serial.print(":");
  
  if(minutes < 10) // Si les minutes n'ont pas 2 digits
  {      
    Serial.print("0");
  }  
  Serial.print(minutes);
  Serial.print(":");
  
  if(secondes < 10) // Si les secondes n'ont pas 2 digits
  {    
    Serial.print("0");
  }
  Serial.print(secondes);
  Serial.print(".");
  
  Serial.println(tenth);
}


Les deux points de separations sont branchés sur la pin6 de l'Arduino mais avec la librairie Sevseg, je ne vois pas comment l'activer indépendemment de l'affichage des heures/minutes.

Merci beaucoup à tous ceux qui voudront m'aider !  :smiley-kiss:

PS : je sais que mon programme n'est pas top, en effet, le compteur prend du retard dans le temps : chaque seconde, je perds 1 dixième, chaque minute je perds 1 seconde et chaque heure je perds 1 minute mais je verrai cela plus tard.

J-M-L

quelle est la librairie Sevseg que vous utilisez ? il y en a plusieurs - celle de sparkfun n'a pas été maintenue il faut prendre celle de Dean Reading qui gère le point décimal et votre doc produit dit
Quote
The first decimal point (farthest to the left) does not illuminate.  It's pin has been allocated to the colon instead so the colon can be illuminated separate from the other 3 decimal points.



pour faire clignoter quelque chose, il faut l'allumer puis l'éteindre puis l'allumer puis l'éteindre ... (cf BlinkWithoutDelay)


Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Nico1510

Merci beaucoup J-M-L pour la réponse mais j'ai toujours le même souci.

Après vérification j'ai bien la librairie de Dean Reading et dans le doute, j'ai pris la dernière version.

Après moult essais à trifouiller mes branchements, il s'avère que la doc est fausse, en effet les 2 points de séparations sont câblés avec le Digit 2 et non le 1.

J'ai regardé aussi le BlinkWithoutDelay et effectivement je pense que ça peut m'aider parce que lorsque j'utilise ce code :

Code: [Select]
const int ledPin =  6;// branchemet pin pour separation
int digit = 13; // branchement digit2

// Variables will change:
int ledState = LOW; // etat separtion bas
int stat = HIGH; // etat digit haut

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 500;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
  pinMode(digit, OUTPUT);
  digitalWrite(digit, stat); // digit toujours a l'etat haut
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}



J'ai bien mes séparations qui clignotent (j'ai aussi testé à coté avec une LED).

Par contre quand j'intègre ce code au mien :

Code: [Select]
// Importation biblio sevseg
#include "SevSeg.h"

// assignation 7-segment
SevSeg sevseg;

// Assignation bouton chronometre : play/pause bouton 1 et reset bouton 2
int pinBouton1 = 3;
int pinBouton2 = 2;

// Variable pour definir si le chrono est en route
boolean run = false;

// Definition des etats boutons
int etatBouton1 = LOW;
int lastEtatBouton1 = LOW;
int etatBouton2 = LOW;
int lastEtatBouton2 = LOW;

long lastPressedBtn1 = 0;
long lastPressedBtn2 = 0;

// Variables utiles
long timer = 0;
int tenth = 0;
int secondes = 0;
int minutes = 0;
int heures = 0;

//**********************
// Variables will change:

const int ledPin =  6; // separation
int digit = 13; // digit2
int ledState = LOW;             // ledState used to set the LED
int stat = HIGH;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;
const long interval = 500;
 
//**********************



void setup(){
  Serial.begin(9600);
 
  byte numDigits = 4; // 7segments avec 4 digits
  byte digitPins[] = {12, 13, A0, A1}; // Correspondance 7segments : Digit1 Digit2 Digit3 Digit4
  byte segmentPins[] = {11, 9, 7, 5, 4, 10, 8, 6}; // Correspondance 7segments : A B C D E F DP
  bool resistorsOnSegments = false; // 'false' => resistances sur les pins digitales
  byte hardwareConfig = COMMON_ANODE;
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = false; // Mettre 'true' pour afficher les 0 'avant' les chiffres
 
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);

  //**************
  pinMode(ledPin, OUTPUT);
  pinMode(digit, OUTPUT);
  digitalWrite(digit, stat);
  //***************
 
}

void loop(){
 
  if((timer - millis()/100) >= 100 || timer == 0)
  { 
    if(run)
    {
      //*********************
        unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
   
        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }
   
        // set the LED with the ledState of the variable:
        digitalWrite(ledPin, ledState);
      }
      //*********************


     
           
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      // afficher les minutes et secondes sur afficheur 7 segments
      sevseg.setNumber(minutes * 100 + secondes, 0);
     
      if(tenth == 9)
      {
        tenth = 0;
       
        if(secondes == 59)
        {
          secondes = 0;
          minutes++;       
        }
        else if(minutes == 59)
        {
          minutes = 0;
          heures++;
        }
        else
        {
          secondes++;
        }
      }
      else
      {
        tenth++;
      }
    }
    timer = millis()/100;
  }
   
  etatBouton1 = digitalRead(pinBouton1);
  etatBouton2 = digitalRead(pinBouton2);
 
  if(etatBouton1 != lastEtatBouton1) // Verifier si l'etat bouton1 a change
  {   
    if(etatBouton1 == HIGH && (millis()-lastEtatBouton1) > 100 || lastEtatBouton1 == 0)
    {
      lastPressedBtn1 = millis();
      run = !run; // Changement d'etat entre play et pause
    }   
  }
 
  lastEtatBouton1 = etatBouton1;    // Recuperer etat bouton1 comme dernier etat bouton1
 
  if(etatBouton2 != lastEtatBouton2) // Verifier si l'etat bouton2 a change
  {
    if(etatBouton2 == HIGH && (millis()-lastEtatBouton2) > 100 || lastEtatBouton2 == 0) // Remise a 0
    { 
      lastPressedBtn2 = millis();
      run = false;
      secondes = 0;
      minutes = 0;
      heures = 0;
      tenth = 0;
     
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      // afficher les minutes et secondes sur afficheur 7 segments
      sevseg.setNumber(minutes * 100 + secondes, 0);   
    }   
  }
 
  lastEtatBouton2 = etatBouton2;   // Recuperer etat bouton2 comme dernier etat bouton2

  sevseg.refreshDisplay();
 
}

void affichage()

  // Affichage Serial
  if(heures < 10) // Si les heures n'ont pas 2 digits
  {
    Serial.print("0");   
  }
  Serial.print(heures);
  Serial.print(":");
 
  if(minutes < 10) // Si les minutes n'ont pas 2 digits
  {     
    Serial.print("0");
  } 
  Serial.print(minutes);
  Serial.print(":");
 
  if(secondes < 10) // Si les secondes n'ont pas 2 digits
  {   
    Serial.print("0");
  }
  Serial.print(secondes);
  Serial.print(".");
 
  Serial.println(tenth);
}



Les séparations ne clignotent pas et même ne s'allument pas alors que ma LED test est allumée...  :o
Petite précision j'ai bien mis les mêmes valeurs de résistances pour les séparations et LED test.

Je pense que ce qui pose problème dans ce dernier code c'est que je définis une 1ere fois le digit2 sur 13 et que je le définis une seconde fois avec "byte digitPins[] = {12, 13, A0, A1}; "
De même pour la séparation définie sur 6 une première fois et une seconde fois.

Enfin, j'ai également essayé d'accéder à la séparation de cette façon "segmentPins[7]" en citant l'index dans le tableau mais sans succès.

Tu m'as dit que Sevseg doit normalement pouvoir gérer les 2 points de séparation, as-tu une idée de comment y accéder ? Car je pense que c'est la clé pour ne serait-ce que les allumer avant de réussir à les faire clignoter.

Ne pas hésiter à me dire si des précisions manquent dans le post  :D

J-M-L

Il s'allume mais comme ensuite vous utilisez la librairie immédiatement pour afficher autre chose sans point, il s'éteint instantanément

Je pense qu'Il faut alterner demander au display d'afficher pendant un certain temps  un nombre avec un point (en conservant ou pas le 0 en tête) et ensuite pendant un autre certain temps  sans point - regardez l'esemple stringWithPeriod et mettez le point au bon endroit si votre module n'a pas été câblé avec le premier point replacé par le deux-points --> s'il est câblé sur le second . et qu'il est 17 min 12 secondes alors affichez alternativement « 17.12 » et « 1712 ». s'il est câblé normalement sur le premier afficheur alors il faudrait alterner « 1.712 » et « 1712 »
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Nico1510

Merci énormément J-M-L !

Il s'allume mais comme ensuite vous utilisez la librairie immédiatement pour afficher autre chose sans point, il s'éteint instantanément
Cette superbe phrase m'a donné le coup de pouce dont j'avais besoin !
J'ai résolu mon problème !

J'ai, comme suggéré, fait en sorte que ma séparation clignote avec une simple (ça m'a quand même pris la journée...) condition If :


Code: [Select]
if( tenth >= 9 && tenth < 10)
      {   
        // decimal a 0 => ne pas afficher les :   
        sevseg.setNumber(heures * 100 + minutes, 0);
      }
     
      if( tenth >= 0 && tenth < 9)
      {
        // decimal a 2 => afficher les :
        sevseg.setNumber(heures * 100 + minutes, 2);
      }



Et en définissant dans sevseg.setNumber(Variable, Dec) à quelle position je voulais faire apparaitre la séparation, je decide ou non de l'afficher sur le 7 segments.


Je vais maintenant faire un test sur 24h pour voir si le chronomètre fonctionne bien et si je n'ai pas trop de secondes perdues au fil des heures.

 Pour ceux que ça intéresse voici le code final :

Code: [Select]
// Importation biblio sevseg
#include "SevSeg.h"

// assignation 7-segment
SevSeg sevseg;

// Assignation bouton chronometre : play/pause bouton 1 et reset bouton 2
int pinBouton1 = 3;
int pinBouton2 = 2;

// Variable pour definir si le chrono est en route
boolean run = false;

// Definition des etats boutons
int etatBouton1 = LOW;
int lastEtatBouton1 = LOW;
int etatBouton2 = LOW;
int lastEtatBouton2 = LOW;

long lastPressedBtn1 = 0;
long lastPressedBtn2 = 0;

// Variables utiles
long timer = 0;
int tenth = 0;
int secondes = 0;
int minutes = 0;
int heures = 0;

byte numDigits = 4; // 7segments avec 4 digits
byte digitPins[] = {12, 13, A0, A1}; // Correspondance 7segments : Digit1 Digit2 Digit3 Digit4
byte segmentPins[] = {11, 9, 7, 5, 4, 10, 8, 6}; // Correspondance 7segments : A B C D E F DP


void setup(){
  Serial.begin(9600);
 
  bool resistorsOnSegments = false; // 'false' => resistances sur les pins digitales
  byte hardwareConfig = COMMON_ANODE;
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = true; // Mettre 'true' pour afficher les 0 'avant' les chiffres

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);

  // initialiser le compteur à 00:00
  sevseg.setNumber(heures * 100 + minutes, 2);

}


void loop(){
 
  if((timer - millis()/100) >= 100 || timer == 0)
  { 
    if(run)
    {
           
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      //**********************
      //Afficher heures et minutes avec clignotement des : de separations
      //**********************
      if( tenth >= 9 && tenth < 10)
      {   
        // decimal a 0 => ne pas afficher les :   
        sevseg.setNumber(heures * 100 + minutes, 0);
      }
     
      if( tenth >= 0 && tenth < 9)
      {
        // decimal a 2 => afficher les :
        sevseg.setNumber(heures * 100 + minutes, 2);
      }
      //**********************

      if(tenth == 9)
      {
        tenth = 0;
       
        if(secondes == 59)
        {
          secondes = 0;
         
          if(minutes == 59)
          {
            minutes = 0;
            heures++;
          }
          else
          {
            minutes++;
          }
        }
        else
        {
          secondes++;
        }
      }
      else
      {
        tenth++;
      }
    }
    timer = millis()/100;
  }
   
  etatBouton1 = digitalRead(pinBouton1);
  etatBouton2 = digitalRead(pinBouton2);
 
  if(etatBouton1 != lastEtatBouton1) // Verifier si l'etat bouton1 a change
  {   
    if(etatBouton1 == HIGH && (millis()-lastEtatBouton1) > 100 || lastEtatBouton1 == 0)
    {
      lastPressedBtn1 = millis();
      run = !run; // Changement d'etat entre play et pause
    }   
  }
 
  lastEtatBouton1 = etatBouton1;    // Recuperer etat bouton1 comme dernier etat bouton1
 
  if(etatBouton2 != lastEtatBouton2) // Verifier si l'etat bouton2 a change
  {
    if(etatBouton2 == HIGH && (millis()-lastEtatBouton2) > 100 || lastEtatBouton2 == 0) // Remise a 0
    { 
      lastPressedBtn2 = millis();
      run = false;
      secondes = 0;
      minutes = 0;
      heures = 0;
      tenth = 0;
     
      //****************
      // POUR DEBUGGING
      affichage();
      //***************

      // afficher les minutes et secondes sur afficheur 7 segments
      // avec le decimal en 2 les : toujours affiches
      sevseg.setNumber(heures * 100 + minutes, 2);   
    }   
  }
 
  lastEtatBouton2 = etatBouton2;   // Recuperer etat bouton2 comme dernier etat bouton2

  sevseg.refreshDisplay();
 
}

void affichage()

 
  // Affichage Serial
  if(heures < 10) // Si les heures n'ont pas 2 digits
  {
    Serial.print("0");   
  }
  Serial.print(heures);
  Serial.print(":");
 
  if(minutes < 10) // Si les minutes n'ont pas 2 digits
  {     
    Serial.print("0");
  } 
  Serial.print(minutes);
  Serial.print(":");
 
  if(secondes < 10) // Si les secondes n'ont pas 2 digits
  {   
    Serial.print("0");
  }
  Serial.print(secondes);
  Serial.print(".");
 
  Serial.println(tenth);
}



Encore une fois, merci beaucoup J-M-L pour l'aide apportée !  :D

Go Up