Go Down

Topic: créer Tableau de valeur qui varie (Read 1 time) previous topic - next topic

lesept

Voila, j'ai modifié la fonction master :
Code: [Select]
/*
  1) scan Badge Master --> ProgramMode ON
  2) select d'un chiffre correspondant à une chambre par l'appui successif du bouton_play (ex: N°3, après 3 appui sur bouton_play)
  3) scan nouveau badge inconnu
  4) enregistre le UID du nouveau badge dans l'EEPROM à la place de celui de la chambre 3
  5) scan Badge Master --> ProgramMode OFF
*/
void badge_master() {
  digitalWrite(LED_B, HIGH);
  tone(BUZZER, 1200, 100);  //Allume Led bleu+Buzzer
  // select d'un chiffre correspondant à une chambre par l'appui successif du bouton_play
  // (ex: N°3, après 3 appui sur bouton_play)
  byte roomNumber = 0;
  Serial.println("Appuyez sur le bouton pour selectionner la chambre");
  const unsigned long tempo = 3000ul; // temporisation : fin d'appui bouton
  unsigned long wait = millis();
  while (millis() - wait < tempo) {
    if (digitalRead(bouton_play) == HIGH) {
      delay (30);  // debounce
      ++ roomNumber;
      if (roomNumber > nbUser + 1) roomNumber = 1;
      Serial.print ("Chambre numéro :");
      Serial.println(roomNumber);
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, roomNumber);
      digitalWrite(latchPin, HIGH);

      wait = millis();
    }
  }
  if (roomNumber == 0) {
    Serial.println ("Aucune chambre selectionnee !");
    return;
  }

  // scan nouveau badge inconnu
  if (! rfid.PICC_IsNewCardPresent());
  if (! rfid.PICC_ReadCardSerial());
  serNumLu = *((uint32_t *)rfid.uid.uidByte);
  LED_Verte();                                     //allume LED Verte et buzzer ok
  //Affiche le serNumLu sur le moniteur série (UID Badge [........])
  Serial.print("UID Badge ["); Serial.print(serNumLu); Serial.println("] ");
  rfid.PICC_HaltA(); // Arrête de lire

  //  enregistre le UID du nouveau badge
  // dans l'EEPROM à la place de celui de la chambre sélectionnée
  Badge[roomNumber].sernum = serNumLu;
  //Affiche le serNumLu sur le moniteur série (UID Badge [........])
  Serial.println("Lecture du nouveau Badge...");
  Serial.print("UID Badge ["); Serial.print(Badge[roomNumber].sernum); Serial.println("] ");
  write_eeprom(roomNumber);   // Modification des données sur l'EEPROM
  read_eeprom(roomNumber);    // Vérification du changement
}


Par contre, n'ayant jamais utilisé d'afficheur 7 segments, je ne sais pas si ce que j'ai mis pour afficher est correct. Ce sont les lignes
Code: [Select]
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, roomNumber);
      digitalWrite(latchPin, HIGH);

J'ai mis une tempo de 3 secondes pour savoir la fin des appuis sur le bouton. Ça peut se modifier si c'est trop long.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

C'est super ce que tu m'as donné :D

J'ai réalisé quelques modifications sur la durée qui été un peu courte :)

Pour l'affichage sur le 7 segment tu avais oublié une bricole, je l'ai corrigé.

Code: [Select]

      // Affiche le numéro de la chambre sur le 7 segment
      byte chiffre = digit[roomNumber];  //<== SUR CETTE LIGNE
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, chiffre);
      digitalWrite(latchPin, HIGH);
      wait = millis();


Je viens de penser que j'ai oublié une fonction.. Durant le Mode Program, je selectionne toujours mon numéro de chambre avec le bouton et je scan un badge.
Seulement, si l'UID du badge scanné est le même que celui dans l'eeprom, j'aimerais qui me mette les crédits du numéro de badge à 5.

Exemple de résultat sur le moniteur série:
Quote
Date : 31/7/2020 17H44min 15Sec
UID Badge [3009340601]
Badge OK - CHAMBRE 11
Credits= 0

Date : 31/7/2020 17H47min 20Sec
UID Badge [2778220336]
=========================
MODE PROGRAM ACTIF
=========================
Appuyez sur le bouton pour selectionner la chambre
Chambre numéro :1
Chambre numéro :2
Chambre numéro :3
Chambre numéro :4
Chambre numéro :5
Chambre numéro :6
Chambre numéro :7
Chambre numéro :8
Chambre numéro :9
Chambre numéro :10
Chambre numéro :11

Lecture du Badge...
UID Badge [3009340601]
Badge connu
-----------------
CHAMBRE 11
3009340601
0
-----------------
Crédits réinitialisé !
La valeur modifiée dans l'EEPROM
-----------------
CHAMBRE 11
3009340601
5
-----------------
Date : 31/7/2020 17H44min 30Sec
UID Badge [2778220336]
=========================
ARRET MODE PROGRAM
=========================

Que dois-je ajouter ?

Code: [Select]
void badge_master() {
  digitalWrite(LED_B, HIGH);
  tone(BUZZER, 1200, 100);  //Allume Led bleu+Buzzer
  // select d'un chiffre correspondant à une chambre par l'appui successif du bouton_play
  // (ex: N°3, après 3 appui sur bouton_play)
  byte roomNumber = 0;
  Serial.println("Appuyez sur le bouton pour selectionner la chambre");
  const unsigned long tempo = 4000ul; // temporisation : fin d'appui bouton
  unsigned long wait = millis();
  while (millis() - wait < tempo) {
    if (digitalRead(bouton_play) == HIGH) {
      delay (500);  // debounce
      ++ roomNumber;
      if (roomNumber > nbUser + 1) roomNumber = 1;
      Serial.print ("Chambre numéro :");
      Serial.println(roomNumber);
      // Affiche le numéro de la chambre sur le 7 segment
      byte chiffre = digit[roomNumber];
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, chiffre);
      digitalWrite(latchPin, HIGH);
      wait = millis();
    }
  }
  if (roomNumber == 0) {
    Serial.println ("Aucune chambre selectionnee !");
    LED_Rouge();
    return;
  }

  // scan nouveau badge inconnu
  if (! rfid.PICC_IsNewCardPresent());
  if (! rfid.PICC_ReadCardSerial());
  serNumLu = *((uint32_t *)rfid.uid.uidByte);
  LED_Verte();                                     //allume LED Verte et buzzer ok
  rfid.PICC_HaltA(); // Arrête de lire

  //  enregistre le UID du nouveau badge
  // dans l'EEPROM à la place de celui de la chambre sélectionnée
  Badge[roomNumber].sernum = serNumLu;
  //Affiche le serNumLu sur le moniteur série (UID Badge [........])
  Serial.println("Lecture du nouveau Badge...");
  Serial.print("UID Badge ["); Serial.print(Badge[roomNumber].sernum); Serial.println("] ");
  write_eeprom(roomNumber);   // Modification des données sur l'EEPROM
  read_eeprom(roomNumber);    // Vérification du changement
}

lesept

Après la fin de la lecture (après le halt) tu compares
Code: [Select]
if (Badge[roomNumber].sernum == serNumLu) {
  Badge[roomNumber].credit = 5;
} else {
  Badge[roomNumber].sernum = serNumLu;
}

Ensuite tu mets les lignes d'affichage sur la console et le 7 segments

... à tester ...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

Tout marche du feu de Dieu ! tu es au top Lesept :D :D

Tu commence à connaître mon penchant pour les petits plus ^^

Pour finir, je souhaiterais réaliser un reset de tous crédits des badges au 1er jour de chaque mois (ex: 01/xx/20xx) afin qu'ils reviennent tous à 5 crédits.

Tu as s'en doute remarqué que j'avais pour cela rajouté un module DS3231 et que j'utilisais la library <Wire.h>

Sachant que toutes mes variables de temps sont dans cette void :

Code: [Select]
void date_heure() {
  //Affiche date et heure lors du badge sur le moniteur série
  dt = clock.getDateTime();
  //Exemple --> Date : 2/5/2020 16H 15min 31Sec
  Serial.print("Date : ");
  Serial.print(dt.day);    Serial.print("/");
  Serial.print(dt.month);  Serial.print("/");
  Serial.print(dt.year);   Serial.print(" ");
  Serial.print(dt.hour);   Serial.print("H");
  Serial.print(dt.minute); Serial.print("min ");
  Serial.print(dt.second); Serial.println("Sec");
}

lesept

Je vais te laisser faire celui-là.

Le principe ici est de tester que le jour vaut 1 et qu'il est exactement 0:00:00.

Si la condition est vraie, alors tu mets 5 crédits partout (boucle for) et tu ajoutes un delay (1000) pour faire en sorte que la condition devienne fausse, afin d'éviter de refaire ça plusieurs fois.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

#35
Aug 01, 2020, 07:11 pm Last Edit: Aug 01, 2020, 07:12 pm by tomobilus
Merci pour tes indications :)

J'ai essayé de bricoler quelque chose, mais je ne vois pas pourquoi ça ne se lance pas... :smiley-confuse:
(j'ai volontairement changé l'heure et les minutes pour accélérer le processus de test) :)

Code: [Select]
void loop() {
  if ((dt.day = 1) && (dt.hour = 19) && (dt.minute = 7) && (dt.second = 0)) {
    int count = nbUser - 1;
    while (count != nbUser) {
      for (int i = 1 ; i < count ; i++) {
        Badge[count].credit = 5;
        Serial.println(Badge[count].nom);
        Serial.print("Crédits= "); Serial.println(Badge[count].credit);
        write_eeprom(count);   // Modification des données sur l'EEPROM
        read_eeprom(count);    // Vérification du changement
        delay (1000);
        }
      }
  } else {
    do {
      ...... // Attend lecture d'un Badge à scanner

lesept

Les conditions, c'est == :)

Enlève le while qui ne sert à rien ainsi que la variable count, tu fais juste un for de 1 à nbusers

Et le delay va après la boucle for, c'est juste pour passer à 0 heures 1 seconde et éviter que la condition du if soit réalisée plusieurs fois
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

il y a un beug dans la matrix... :smiley-sweat:

Il ne se passe toujours rien malgré tes corrections... :smiley-confuse:

Code: [Select]
void loop() {
if ((dt.day == 1) && (dt.hour == 23) && (dt.minute == 40) && (dt.second == 0)) {
    for (int i = 1 ; i < nbUser ; i++) {
      Badge[nbUser].credit = 5;
      Serial.println(Badge[nbUser].nom);
      Serial.print("Crédits= "); Serial.println(Badge[nbUser].credit);
      write_eeprom(nbUser);   // Modification des données sur l'EEPROM
      read_eeprom(nbUser);    // Vérification du changement
    }
    delay (1000);
  } else {
    do {

lesept

Ajoute ceci avant ton if pour vérifier que tu entres ou non dans le if
Code: [Select]

  Serial.print("Date : ");
  Serial.print(dt.day);    Serial.print("/");
  Serial.print(dt.month);  Serial.print("/");
  Serial.print(dt.year);   Serial.print(" ");
  Serial.print(dt.hour);   Serial.print("H");
  Serial.print(dt.minute); Serial.print("min ");
  Serial.print(dt.second); Serial.println("Sec");
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

j'ai essayé avec ce que tu m'as dit, ça n'a pas été d'un grand succès :smiley-sweat:

J'obtiens un résultat en enlevant "dt.second" et après avoir scan un badge...

Quote
Présentez votre badge sur le lecteur ...

Date : 2/8/2020 10H58min 35Sec

Date : 2/8/2020 10H58min 43Sec
UID Badge [3009386505]
Badge OK - CHAMBRE 11
Credits= 2
Date : 2/8/2020 10H59min 18Sec

⸮
;⸮<%_
Crédits= 5
Impossible d'écrire le badge N° 12
Impossible de lire le badge numéro 12
⸮
;⸮<%_
Crédits= 5
Impossible d'écrire le badge N° 12
Impossible de lire le badge numéro 12
⸮
;⸮<%_
Crédits= 5
Impossible d'écrire le badge N° 12
Impossible de lire le badge numéro 12
⸮
;⸮<%_
le code :

Code: [Select]
void loop() {
  dt = clock.getDateTime();
  Serial.print("Date : ");
  Serial.print(dt.day);    Serial.print("/");
  Serial.print(dt.month);  Serial.print("/");
  Serial.print(dt.year);   Serial.print(" ");
  Serial.print(dt.hour);   Serial.print("H");
  Serial.print(dt.minute); Serial.print("min ");
  Serial.print(dt.second); Serial.println("Sec");

  if ((dt.day == 2) && (dt.hour == 10) && (dt.minute == 59) /*&& (dt.second == 0)*/) {
    for (int i = 1 ; i < nbUser ; i++) {
      Badge[nbUser].credit = 5;
      Serial.println(Badge[nbUser].nom);
      Serial.print("Crédits= "); Serial.println(Badge[nbUser].credit);
      write_eeprom(nbUser);   // Modification des données sur l'EEPROM
      read_eeprom(nbUser);    // Vérification du changement
    }
    delay (1000);
  } else {
    do {

lesept

Dans la boucle for, il faut changer Badge[nbUser] en Badge[ i ]
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

Oh qu'elle erreur bête...  :smiley-sweat:

Alors le fonctionnement marche MAIS...

La réinitialisation s'est déclenché après avoir fait un scan d'un badge et une fois qu'on fait apparaître dt = clock.getDateTime(); au début de la Loop. (j'ai volontairement enlevé dt.second dans mon test pour être sur que cela s'exécute)

J'en ai déduit que la fonction reset crédit ne se lance que s'il y a un affichage de dt = clock.getDateTime(); toutes les secondes, afin de comparer avec les valeur du "if" demandé.
Quote
if ((dt.day == 2) && (dt.hour == 13) && (dt.minute == 7) && (dt.second == 0)) {
Du coup comment faire pour que la void date_heure() se lance toutes les seconde, pendant que les autres fonctions de scan badge tourne ?

Code: [Select]
void date_heure() {
  //Affiche date et heure lors du badge sur le moniteur série
  dt = clock.getDateTime();
  //Exemple --> Date : 2/5/2020 16H 15min 31Sec
  Serial.print("Date : ");
  Serial.print(dt.day);    Serial.print("/");
  Serial.print(dt.month);  Serial.print("/");
  Serial.print(dt.year);   Serial.print(" ");
  Serial.print(dt.hour);   Serial.print("H");
  Serial.print(dt.minute); Serial.print("min ");
  Serial.print(dt.second); Serial.println("Sec");
}

Code: [Select]
void loop() {
  date_heure();
  if ((dt.day == 2) && (dt.hour == 13) && (dt.minute == 7) && (dt.second == 0)) {
    for (int i = 1 ; i < nbUser ; i++) {
      Badge[i].credit = 5;
      Serial.println(Badge[i].nom);
      Serial.print("Crédits= "); Serial.println(Badge[i].credit);
      write_eeprom(i);   // Modification des données sur l'EEPROM
      read_eeprom(i);    // Vérification du changement
    }
    delay (1000);
  } else {
    do {

lesept

Quote
Du coup comment faire pour que la void date_heure() se lance toutes les seconde, pendant que les autres fonctions de scan badge tourne ?
C'est simple. Tu utilises millis() pour mesurer une seconde. Lorsque la seconde est passée, tu appelles ta fonction date_heure() 
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

tomobilus

D'accord... J'ai aucune idée de comment intégrer cela... :smiley-confuse:

j'imagine que c'est quelque chose comme cela :

Quote
unsigned long previousMillis = 0;
previousMillis = millis();

(millis() - previousMillis < 1000)
Mais comment et à quel endroit je dois l'insérer...

Code: [Select]
void loop() {
  date_heure();
  if ((dt.day == 2) && (dt.hour == 13) && (dt.minute == 7) && (dt.second == 0)) {
    for (int i = 1 ; i < nbUser ; i++) {
      Badge[i].credit = 4;
      Serial.println(Badge[i].nom);
      Serial.print("Crédits= "); Serial.println(Badge[i].credit);
      write_eeprom(i);   // Modification des données sur l'EEPROM
      read_eeprom(i);    // Vérification du changement
    }
    delay (1000);
  } else {
    do {

lesept

Ça dépend de ce que tu veux faire.

Plus un code devient compliqué, plus il y a de possibilités, et plus il est important de bien spécifier ce qu'on veut faire. Si tout est bien spécifié, le code vient naturellement, et il n'est pas nécessaire d'y apporter des modifications par la suite...

Si je comprends bien, ce que tu veux c'est mettre à jour la variable dt chaque seconde ?

Mais cette partie ne doit pas être bloquante car le code peut faire autre chose en même temps. Exact ?

C'est la fonction date_heure qui fait la mise à jour. Si elle ne sert qu'à ça et ne sera jamais appelée par ton code pour autre chose que cette mise à jour chaque seconde, autant mettre millis dans la fonction.
Sinon, il faut le mettre à l'appel de la fonction.

Que choisis-tu ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Go Up