Wordclock arduino - Pb code !

Bonjour à tous,

Je travaille en ce moment à la réalisation d’une horloge de type wordclock.

J’ai pas mal avancé sur le code. J’ai enregistré l’heure dans le RTC DS1306.

Cependant étant très junior dans la programmation j’en appelle à votre aide !

#include "Wire.h"
#define DS1307_ADDRESS 0x68

#include <Adafruit_NeoPixel.h>
#define RGBLEDPIN    6
#define N_LEDS 114 // 11 x 10 grid + 4 aux coins

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_LEDS, RGBLEDPIN, NEO_GRB + NEO_KHZ800);

uint32_t WHITE = pixels.Color(255, 255, 255); // Défini la couleur

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//          Définition des mots
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void LEDSOFF() {
    for(int i=0;i<N_LEDS;i++){
       pixels.setPixelColor(i, pixels.Color(0,0,0)); 
      pixels.show();
 }
}
void showILEST()
{
  pixels.setPixelColor(1, WHITE);
  pixels.setPixelColor(2, WHITE);

  pixels.setPixelColor(4, WHITE);
  pixels.setPixelColor(5, WHITE);
  pixels.setPixelColor(6, WHITE);
}

void showVINGT()
{
  pixels.setPixelColor(90, WHITE);
  pixels.setPixelColor(91, WHITE);
  pixels.setPixelColor(92, WHITE);
  pixels.setPixelColor(93, WHITE);
  pixels.setPixelColor(94, WHITE);
}

void showVINGTCINQ()
{
  showVINGT();
  pixels.setPixelColor(95, WHITE);
  pixels.setPixelColor(96, WHITE);
  pixels.setPixelColor(97, WHITE);
  pixels.setPixelColor(98, WHITE);
  pixels.setPixelColor(99, WHITE);
}

// J'ai enlevé le reste des fonctions car cela ne rentrait pas dans le post mais vous avez l'idée. ;)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//          Appel de l'heure enregistrée sur la DS1307
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time

}

void isPast()
  { boolean (minute > 30 = true) 
  }

    
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//          Affiche leds en fonction de l'heure
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void AfficheLeds() {
    LEDSOFF(); 
    {
      showILEST();
    
  
     if(minute < 5 and hour == 1 ) {
        showHEURE();
        } else if(minute < 5 and (hour != 12 || hour != 0 || hour != 1) ){
          showHEURES
          
      } if(minute == 1) {
        showPLUSUN();
      } else if(minute == 2) {
        showPLUSDEUX();
      } else if(minute == 3) {
        showPLUSTROIS();
      } else if(minute == 4) {
        showPLUSQUATRE();  
      } else if(minute == 5)  {
        showCINQ();
        
      } else if(minute == 6)  {
        showPLUSUN();
        showCINQ();

meme idée jusqu'à 29

      } else if(minute == 30 and (hour != 12 || hour != 0 )) {
        showETDEMIE();
        } else {
          showETDEMI();
          
 meme idée jusqu'a 59 

      } else if(minute == 59) {
        showMOINS();
        showPLUSUN();
      }

      if(hour == 0) {
        if(isPast) {
          showMINUIT();
        } else {
          showUNE();
        }
      } else if(hour == 12) {
        if(isPast) {
          showMIDI();
        } else {
          showUNE();
        }
      } else if(hour == 1 || hour == 13) {
        if(isPast) {
          showUNE();
        } else {
          showDEUX();
        }
      } else if(hour == 2 || hour == 14) {
        if(isPast) {
          showDEUX();
        } else {
          showTROIS();
        }
      }  IDEM JUSQU'A MINUIT
   
       else if(hour == 23) {
        if(isPast) {
          showONZE();
        } else {
          showMINUIT();
        }
      }
    }

    pixels.show(); // cela actualise l'affichage des leds
}


void setup(){
  Wire.begin();
  pixels.begin();
}

void loop(){
  printDate();
  delay(1000);
  AfficheLeds();
}

Le principal problème que je rencontre est lié à la définition de certaines fonctions.

Je pensais pouvoir utiliser “minute” et “hour” tels quels mais visiblement ils ne sont pas bien définis…

Je pensais pourtant que le code définissait hour et minute pour une réutilisation. J’ai la bonne heure sur le serial.

int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time

Le deuxième point est le suivant : je n’arrive pas à définir une fonction qui indique que les minutes sont plus grandes que 30. Cette fonction “isPast” me servira ensuite dans ma suite if else (en gros elle permet d’afficher 10h moins 20 même si les heures indiquent 9)

void isPast()
  { boolean (minute > 30 ; true) 
  }

bien sûr étant donné que “minute” n’étant pas défini je ne peux même pas travaillé sur la structure de la fonction.

Enfin visiblement je me suis planté dans mes if else mais bon je devrais récuperer le coup en relisant plus en détails.

Merci d’avance pour l’aide apportée dans la réalisation de mon projet.

Louison

Louison: Le principal problème que je rencontre est lié à la définition de certaines fonctions.

Je pensais pouvoir utiliser "minute" et "hour" tels quels mais visiblement ils ne sont pas bien définis...

C'es à dire? Tu obtiens quoi? Qu'est-ce qui te fait dire que c'est mal défini?

Le compileur me sort cette phrase :

error: 'minute' was not declared in this scope error: 'hour' was not declared in this scope

donc visiblement il ne réutilise pas la formule int hour et int minute

Bonjour, Une solution est de faire de minute et hour des variables globales, et non locales comme actuellement. Pour ce faire il faut les déclarer avec les autres variables globales en début de sketch. Ex: int minute = 0;

puis dans printDate() supprimer la déclaration pour utiliser la variable locale: int minute = bcdToDec(Wire.read()); devient minute = bcdToDec(Wire.read());

Si isPast() est appelée après printDate() minute aura été initialisée correctement.

La syntaxe de isPast() semble aussi incorrecte. Elle devrait être

boolean isPast()
  { return (minute > 30 ? true:false) 
  }

Tu ne sembles pas bien maitriser les concepts de variables locales/globales et de définition de fonction.

Bonjour Patg

Effectivement je me suis aperçu de mon erreur et j'ai corrigé cette après midi de la façon suivante : (et tu as raison je débute avec la programmation et arduino...)

int minute = bcdToDec(Wire.read());
int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time


void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  minute ;
  hour ;

Est-ce correct ? Si j'écris int minute = 0 cela signifie-t-il que minute = 0 ou que la fonction peut être appelée ainsi ?(en fait pourquoi = 0)

Effectivement isPast() sera appelé après printDate()

Merci beaucoup pour ce bout de code, puis-je l'utiliser de la façon suivante :

boolean isPast()
  { return (minute > 30 ? true:false) 
  }

void AfficheLeds() {
    LEDSOFF(); 
    {
      showILEST();

if(hour == 0) {
        if(isPast() = true) {
          showONEHOUR();
        } else {
          showMIDNIGHT();
        }

Il y a 2 problèmes dans ce que tu proposes: Il faut simplement déclarer les variables globale minute et hour comme je te l'ai indiqué et laisser printDate() faire la lecture. Tu ne peux pas simplement appeler Wire.read() sans effectuer touts les appels Wire (I2C) qui sont fait avant dans printDate()

Ensuite tu as écrit if (isPast() = true) alors qu'il faut écrire if(isPast() == true) C'est une erreur commune de confondre l'opérateur d'affectation = avec celui de comparaison == et ça cause des bugs souvent difficiles à diagnostiquer.

Tu dis: Si j'écris int minute = 0 cela signifie-t-il que minute = 0 ou que la fonction peut être appelée ainsi ?(en fait pourquoi = 0)

Quelle fonction? Il s'agit ici de déclarer et d'initialiser une variable. En fait on pourrait simplement déclarer la variable, sans l'initialiser en écrivant: int minute;

Oui j'ai un peu de mal avec les termes. Effectivement je parlais d'une variable et non pas de la fonction.

Que se passe-t-il si on déclare une variable sans l'initialiser ?

Donc si je suis tout jusqu'ici je devrais écrire :

int minute = 0
int hour = 0

void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time

et

boolean isPast()
  { return (minute > 30 ? true:false) 
  }

void AfficheLeds() {
    LEDSOFF(); 
    {
      showILEST();

if(hour == 0) {
        if(isPast() = true) {
          showONEHOUR();
        } else {
          showMIDNIGHT();
        }

Il manque les points virgules après tes initialisations de variables et dans printDate() il ne faut pas redéfinir tes variables (il faut supprimer le int) car alors tu définis des variables locales de même nom qui vont masquer tes variables globales.

Sérieusement, essaie le code et compile le avant, c'est bien plus simple.

Si tu déclares une variable sans l'initialiser, si je me souviens bien ça dépend du type de variable (mes cours de C et C++ datent un peu). Pour une variable globale ça l'initialise à 0 je crois et pour une variable locale il me semble que la valeur n'est pas garantie.

Pour info je passe rarement sur ce forum mais cet après-midi j'avais quelques heures à tuer, alors n'attends pas de réponse rapide... et essaie par toi-même! :)

Louison: ``` int minute = 0 int hour = 0

void printDate(){

  // Reset the register pointer   Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;   Wire.write(zero);   Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());   int minute = bcdToDec(Wire.read());   int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time

Tu définis minute et hour une fois en global et une fois en local. Pour C ce sont des variables différentes. La valeur que tu donnes à ces variables dans printDate() sera perdue lors de la sortie de la fonction.

Merci à tous pour votre aide !

Effectivement je vais essayer de compiler tout ca avant d'avancer ;)

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

int minute = 0;
int hour = 0;

void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0b111111); //24 hour time

}

J'ai défini les variables minute et hour en amont. Puis enlever int dans la fonctions.

Ensuite dans mon code je vais appeler la fonction printdate() avant la réutilisation de "minute" et "hour". Est ce ok ?

Oui c'est OK.

Merci Patg, effectivement j'ai pu tester moi-même et le gros de l'horloge fonctionne donc je suis très content!

Cependant j'ai encore un petit probleme.

Les leds clignotent à intervalle fixe (normal car lié à l'actualisation de la RTC)

J'ai donc mis un delay(5000) et elles ne clignotent plus que toutes les 5 secondes.

Mais ce que j'aimerais faire c'est qu'elles clignotent uniquement quand il y a un changement de minute (donc quand les secondes reviennent à zero

J'ai essayé des choses mais cela ne semble pas fonctionner

void NEWMINUTE() {
  if (second == 0)
  delay(60000);
}

void loop(){
  printDate();
  delay(1000);
  LUMINOSITE();
  AfficheLeds();
  delay(NEWMINUTE());

Merci pour votre aide !

Louison

J’ai peut être trouvé une solution :

 void loop(){
  LUMINOSITE();
  printDate();
  delay(1000);
  if(second == 1) { AfficheLeds(); }