IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Détection de top synchro sur FI sur 162kh (fréquence étalon).


Sujet :

Arduino

  1. #61
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Voici


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
     
    //----- Adressage matériel -----
    LiquidCrystal_I2C lcd(0x27, 20, 4);
    //LiquidCrystal_I2C lcd(0x3F,20,4);
    //------------------------------
    #define interruptPin 2   
    #define led_bit 12      
    #define ledSeconde 13
     
    #define bitDonneesMinutesStart 21
    #define bitDonneesMinutesNbr 7
    byte bitDonneesMinutesCoeff[] = {1, 2, 4, 8, 10, 20, 40};
     
    #define bitDonneesHeuresStart 29
    #define bitDonneesHeuresNbr 6
    byte bitDonneesHeuresCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesJourSemaine 42
    #define bitDonneesJourSemaineNbr 3
    const char* jourSemaineNom[] = {"-", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
     
    #define bitDonneesJourStart 36
    #define bitDonneesJourNbr 6
    byte bitDonneesJourCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesMoisStart 45
    #define bitDonneesMoisNbr 6
    const char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"}; //byte bitDonneesMoisCoeff[] = {1, 2, 4, 8, 10};
     
    #define bitDonneesAnneesStart 50
    #define bitDonneesAnneesNbr 6
    byte bitDonneesAnneesCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define nombreDeSeconde 59
    byte infoDonnees[ nombreDeSeconde];
    byte donneeBit = 0;
     
    volatile boolean mesureEnCours = false;                    
    volatile boolean mesureNouvelle = false;
     
    volatile unsigned long tempoDepart = millis();
    volatile unsigned long topSyncMilliSec = millis();
    volatile unsigned long departMesure = millis();
    volatile unsigned long departbit_Importante = millis();
     
    const unsigned int topSyncMinimum = 800;
     
    int unsigned  compteurSeconde = 0; //compteur des secondes 
     
    boolean top = false;
    boolean top1 = false;
    boolean top2 = false;
    boolean top3 = false;
    int minute = 0;
     
    void setup()
    {
     
       for (byte s = 1; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
       {                                             // A faire avant chaque cycle de minute
         infoDonnees[s] = 0;          
       }
     
      lcd.init(); // initialisation de l'afficheur
     
      Serial.begin (115200);
      pinMode(interruptPin, INPUT_PULLUP);    // entrée interruption avec pull up
      pinMode(ledSeconde, OUTPUT);            // 
      digitalWrite(ledSeconde, LOW);
      pinMode(led_bit, OUTPUT);               //led_bit en sortie et low
      digitalWrite(led_bit, LOW);
      attachInterrupt(digitalPinToInterrupt(interruptPin), impulsion_Interruption, CHANGE); //interruption pour rechercher le top syncrho du debut de la pemière seconde
    }
    //-----------------------------------------------------------------------
    void loop()
    {
     
      if (mesureNouvelle == true)
      {
        mesureNouvelle = false;
        topSyncAction();
      }
     
      calibrage_Seconde();            // renvoie aux fonctions régulièrement
      lecture_Seconde_Et_Bits();   
      ecriture_Bit_Importante();
     
      affichage_I2c();
     
      //extraireMinute();
      //extraireHeure();
      //extraireJourSemaineNom();
      //extraireJour();
      extraireMoisNom();             //je ne peux pas supprimer  cette appelle , sinon bug
      //extraireAnnee();
    }
     
    //------------------------------------------------------------------------
    void impulsion_Interruption()
    {
      if (digitalRead(interruptPin) == LOW && !mesureEnCours)
      {
        tempoDepart = millis();                                 // machine à état pour récuperer le top synchro (début de la 1° seconde)
        mesureEnCours = true;
      }
     
      if (digitalRead(interruptPin) == HIGH && mesureEnCours)
      {
        topSyncMilliSec = millis() - tempoDepart;
        mesureEnCours = false;
        mesureNouvelle = true;
      }
    }
     
    //-------------------------------------------------------------------------
    void topSyncAction()
    {
     
      if (topSyncMilliSec >= topSyncMinimum)          //Dans cette routine ,on  teste si l'on a un temps sans donnée(sans interruption) de plus de 800ms
      {                                                                   // si c'est le cas on met au niveau haut la pin 13 des secondes  (la led s'allume)
        departMesure = micros(); 
        Serial.println("Syncro_seconde----->0");      // affiche la syncrho
        digitalWrite (ledSeconde, HIGH);             // puis on va dans la routine "calibrage_seconde" via la loop.
     
        lcd.clear();                                 // permet d'effacer les anciennes écitures sur l'afficheur (I2C)
        compteurSeconde = 0;                         // compteurSeconde à 0
     
        top3 = true;                                 //pour pouvoir rentrer dans la fonction affichage et afficher la seconde 0                    
     
      }
    }
    //-------------------------------------------------------------------------
     
    void calibrage_Seconde()
    {
     
        if (micros() - departMesure >= 140000 )              
      {     
        digitalWrite(ledSeconde, LOW);                        
     
     
        if (micros() - departMesure >=999420)       // 999550 ici le temps la 59° ne doit pas être inf. à une seconde sinon on n'affiche la seconde 60 puis seconde 0           
        {                                                           // donc il faut  régler les secondes quelques micros secondes en moins
          digitalWrite(ledSeconde, HIGH);           // pour que l'interrupt tombe av que le compteur ne s'incrémente (un peu tiré par les cheveux, on peut faire mieux)
          departMesure = micros();                            
          departbit_Importante = millis(); 
          compteurSeconde ++;
          top2 =true;
          top = true;
                                                    //top3 = true; en autorisant l'affichage ici, j'ai un retard du debut de la 1° seconde de 20ms par rapport a la syncro, 1 fois sur deux
                                                  //je ne sais pas encore pourquoi...je les ai mis dans lecture seconde et cela fonctionne.
        }
      }
    }
    //--------------------------------------------------------------------------
     
    void lecture_Seconde_Et_Bits()                      
    {
     
     
         if ( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == HIGH && top == true)
                                       //&&compteurSeconde >= 20 && compteurSeconde <= 59) //pour ne lire que les secondes importantes
        { 
          digitalWrite (led_bit, HIGH);                  //on met le bit de donnée à 1
                                                         //departbit_Importante = millis();                     
          donneeBit = 1;                                 //si les conditions sont ok , le bit est à  1                                           
          delay (25);                                    //delay de 25 ms pour visualiser à l'ecran le top plus facile à utiliser que milli()
          digitalWrite (led_bit,LOW);                    //après 25 ms ,on mais le bit de donnée à 0
          top =false;                                    //oblige à  rentrer dans le prg uniquement sur le front montant d'une nouvelle seconde
          top1 = true;                                   // autorisation d'utilisation de la fonction void ecriture_Bit-Importante ()
     
        }
           if( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == LOW && top == true)
                                       //&& compteurSeconde >= 20 && compteurSeconde <= 59)  //pour ne lire que les secondes importantes
          {
           donneeBit = 0;                                 // si les conditions sont ok, le bit est à 0
           top = false;                                   //idem que plus haut
           top1 = true;                                   //idem que plus haut
     
          } 
    }
     
    //-----------------------------------------------------------------------------
                                                      // une  partie de  "void ecriture_Bit_Importante" n'est nécessaire que pour la visualisation à l'écran       
    void ecriture_Bit_Importante()                    // des données    
    { 
      if( top1 == true)
      {
       //Serial.print ("seconde----->");Serial.print (compteurSeconde );Serial.print("    ");   Serial.print("Donnée------>"); Serial.println(donneeBit);
                                                          // test pour affichage liason serie
       infoDonnees[compteurSeconde] = donneeBit;          // mise en emoire des données pour chaque seconde 
     
       top1 = false;                                     // interdit de re-rentrer dans cette fonction par l'intermediaire de la loop , attente d'autorisation
       top3 = true;                                      // autorisation d'utiliser  la fonction afficheur i2c
     
      }                                              
    } 
     
    //------------------------------------------------------------------------------
     
    int extraireMinute()
    {
      if (compteurSeconde == 59)
      {
      int minute = 0;
     
      for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
      {
        minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
      }
     
      return minute;
      }
    }
    //----------------------------------------------------------------------------------------
     
    int extraireHeure()
    {
      if (compteurSeconde == 59)
      {
      int heure = 0;
     
      for (int mInd = 0; mInd < bitDonneesHeuresNbr; mInd ++)
      {
        heure += bitDonneesHeuresCoeff[mInd] * infoDonnees[bitDonneesHeuresStart + mInd];
      }
     
      return heure;
      }
    }
    //------------------------------------------------------------------------------------------
     
     const char* extraireJourSemaineNom()
    {
      byte jourSemaineIndex = 0;
     
      for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
      {
        jourSemaineIndex += infoDonnees[bitDonneesJourSemaine + jsn] << jsn;
      }
     
      return jourSemaineNom[jourSemaineIndex];
    } 
    //------------------------------------------------------------------------------------------
     
    int extraireJour()
    {
      if (compteurSeconde == 59)
      {
      int jour = 0;
     
      for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
      {
        jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
      }
     
      return jour;
      }
    }
     
    //------------------------------------------------------------------------------
    String extraireMoisNom()                           //bug avec const char*  
    {
      byte moisIndex = 0;
     
      for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
      {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
      }
     
      return mois[moisIndex];
    } 
     
    //--------------------------------------------------------------------------------
    int extraireAnnee()
    {
      if (compteurSeconde == 59)
      {
      int annee = 0;
     
      for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
      {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
      }
     
      return annee;
      }
    }
    //-------------------------------------------------------------------------------
    void affichage_I2c()
    {
     
     
       if( top3 == true ) 
       {                                               //autorisation donnée par la fonction void ecriture_Bit_Importante()
          int nouvelleMin = extraireMinute();
          int nouvelleHeure = extraireHeure(); 
          String nouveauJourSemaineNom = extraireJourSemaineNom();                                            //Serial.println(nouvelleMin); 
          int nouveauJour = extraireJour();
          String nouveauMois = extraireMoisNom(); 
          int nouvelleAnnee = extraireAnnee();
     
          lcd.backlight();
     
          if (compteurSeconde == 0 && nouvelleAnnee == 20 || nouvelleAnnee == 21) 
          {                                                                                                               
           //lcd.clear();                                                                                                                                     
           lcd.setCursor(0,1);
           lcd.print(nouvelleHeure);
           lcd.setCursor(2,1);
           lcd.print("hr");
     
     
           lcd.setCursor(7,1);
           lcd.print(nouvelleMin);           
           lcd.setCursor(9,1);
           lcd.print("min");
     
     
     
           lcd.setCursor(0,0);
           lcd.print(nouveauJourSemaineNom);
     
           lcd.setCursor(4,0);
           lcd.print(nouveauJour);  
     
           lcd.setCursor(7,0);
           lcd.print(nouveauMois); 
     
           lcd.setCursor(12,0);
           lcd.print("20");
           lcd.setCursor(14,0);
           lcd.print(nouvelleAnnee);           
           }
            if( nouvelleAnnee != 20)
            {
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("attente donnees");
            }
        lcd.setCursor(13,1);
        lcd.print( compteurSeconde); 
        lcd.setCursor(15,1);
        lcd.print("s");
     
        top3 = false;                          // on ne rentre qu'une fois par seconde dans cette fonction , sinon gros souci de timing car on vient la lire
                                               // de nbrs fois
      }
     
    }
    Bonne soirée

  2. #62
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    dans extraireMoisNom() vous ne testez pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (compteurSeconde == 59)
    ce qui fait que le calcul de moisIndex est erroné la plupart du temps

    Quelques autres commentaires:


    attention vous avez un bug de dépassement de tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define nombreDeSeconde 59
    byte infoDonnees[ nombreDeSeconde];
    ...
     
      for (byte s = 1; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
      { // A faire avant chaque cycle de minute
        infoDonnees[s] = 0;
      }
    les coordonnées d'un tableau vont de 0 à taille-1, pas de 1 jusqu'à taille.

    ==> il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      for (byte s = 0; s < nombreDeSeconde ; s++)   // Initialisation des bits de données
      { // A faire avant chaque cycle de minute
        infoDonnees[s] = 0;
      }

    -------
    En français vous ne dites pas "si (la lumière est allumée est vrai) alors ...", mais juste "si (la lumière est allumée) alors...."
    Il en va de même en programmation, quand vous avez une variable de type booléen, ce n'est pas la peine de mettre == true dans les test, c'est déjà une valeur de vérité en elle même. On n'écrit donc généralement pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if ( top3 == true ) ....
    mais simplement-------

    Dans la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        if (compteurSeconde == 0 && nouvelleAnnee == 20 || nouvelleAnnee == 21)
    je vous suggère de mettre des parenthèses pour grouper ce qui va ensemble.

    A moins d'être fort en priorité des opérateurs, il est difficile à la lecture de dire si c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        if (compteurSeconde == 0 && (nouvelleAnnee == 20 || nouvelleAnnee == 21))
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        if ((compteurSeconde == 0 && nouvelleAnnee == 20) || nouvelleAnnee == 21)
    qui sera retenu... Ici le && est plus prioritaire et gagne sur le || et donc c'est la seconde version que le compilateur retient. est-ce ce que vous souhaitez ??

    remarque annexe: que se passera-t-il en 2022 ??

    --------

    les fonctions d'extraction comme extraireMinute() etc doivent TOUJOURS retourner quelque chose, c'est la promesse que vous faites au compilateur en déclarant . Dans votre cas vous ne retournez rien si compteurSeconde ne vaut pas 59. je vous suggère de retourner -1 pour dire que l'info n'est pas dispo.


    ------

  3. #63
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Bonjour,

    j' ai pris compte de vos remarques et fait quelques corrections.

    le seule chose qui résiste, est toujours la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    String extraireMoisNom()                           //bug avec const char*  
    {
     
      byte moisIndex = 0;
     
      for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
      {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
     
      }
     
      return mois[moisIndex];
      }

    Impossible "d'écrire"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (compteurSeconde ==59)
    {
     
       String extraireMoisNom()                           //bug si encadré avec la fonction if
      {
     
        byte moisIndex = 0;
     
           for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
         {
          moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
         }
     
          return mois[moisIndex];
      }
    }
    }

    ou comme vous le préconisiez

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    const char* extraireMoisNom()                           //bug avec const char*  
    {
     
      byte moisIndex = 0;
     
      for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
      {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
      }
     
      return mois[moisIndex];
      }
    et encore moins supprimer l'appel


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //extraireMinute();
      //extraireHeure();
      //extraireJourSemaineNom();
      //extraireJour();
      extraireMoisNom();                                                //je ne peux pas supprimer  cette appelle , sinon bug
      //extraireAnnee();

    Dans tous ces cas , le pgr bug.

    C'est un pb qui dépasse mes compétences de "presque débutant"... Sinon le prg fonctionne impeccablement tel qu'il est écrit.

    Bonne soirée

    Pat

  4. #64
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    vous pouvez poster la nouvelle version ?

  5. #65
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Bonsoir, voici la version avec les modifications suite à vos remarques.
    Comme dit précédemment , je suis un presque débutant et ne serais jamais un pro de l'arduino et du C . De ce fait, mes prgs ne serons jamais parfait .
    Malgré tout, grâce à vos aides, à vos remarques, à vos explications, j'apprends et j'ai pu écrire ce prg qui fonctionne sans bug depuis plus de 15 jours.


    Il reste toujours cette fonction qui résiste à toutes modifications (en réalité, les deux fonctions qui pointent sur des suites de caractères) et qui font que le pgr bug si on essaie de bien les écrire (voir post précédent).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String extraireMoisNom() 
                                                        //bug avec const char*  ou encadré par un  "if(compteurSeconde ==59) { }"
    {
      byte moisIndex = 0;
     
      for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
      {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
      }
     
      return mois[moisIndex];
      }

    Pour éventuellement vous faciliter la recherche du pb (qui n'est pas vraiment gênant ) et aussi pour ceux que cela intéresse, j'ai modifié le pgr pour que la lecture se fasse sur le moniteur série, et écrit un petit programme qui permet d'émuler et de visualiser sur un oscillo la sortie de mon récepteur de fréquence étalon ( France Inter sur 162khz).
    Il permet d'envoyer une date fixe vers le prg principal ( du coup, pas besoin de récepteur pour faire tourner le pgr principal).
    La date envoyée est " lundi 1 Aout 2020 - 4 hrs 8 mns"

    le programme de l'émulateur a été installé sur une nano et le prg principal sur une uno.
    Pin D12 de la nano connectée sur la pin D2 de la uno , ne pas oublier la gnd commun.

    Normalement tout doit fonctionner du premier coup, j'ai mis des tops synchro de 35 ms au lieu de 25 pour être quasi sur qu'il y aura bien lecture des données même si il y a une différence de timing entre les deux prg (du fait de la différence de fréquence des quartz).


    Il faut attendre deux tops synchro pour que la date s'affiche correctement. Sinon, modifier le nbr de micro-seconde dans le prg de l'émulateur et faire coïncider les fronts montants des dernières secondes de la minute entre l'émulateur (pin D12) et le prg principal (pin D13) ( les différences de micro secondes s'ajoutent pour faire de belles ms en avance ou en retard à la fin de la minute et qui peuvent éventuellement faire sortir la donnée de la fenêtre de lecture).
    Je pense que de ce côté là, on peut faire beaucoup mieux pour récupérer les données.


    Comme il y a deux prg à charger , ne pas oublier de revenir sur la carte qui supporte le prg principal pour pouvoir envoyer la visualisation sur le moniteur série.
    (J'écris cela car je me suis fait "avoir" )
    Bonne soirée
    Pat

    Programme principal:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
     
    //----- Adressage matériel -----
    LiquidCrystal_I2C lcd(0x27, 20, 4);
    //LiquidCrystal_I2C lcd(0x3F,20,4);
    //------------------------------
    #define interruptPin 2   
    #define led_bit 12      
    #define ledSeconde 13
     
    #define bitDonneesMinutesStart 21
    #define bitDonneesMinutesNbr 7
    byte bitDonneesMinutesCoeff[] = {1, 2, 4, 8, 10, 20, 40};
     
    #define bitDonneesHeuresStart 29
    #define bitDonneesHeuresNbr 6
    byte bitDonneesHeuresCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesJourSemaine 42
    #define bitDonneesJourSemaineNbr 3
    const char* jourSemaineNom[] = {"-", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
     
    #define bitDonneesJourStart 36
    #define bitDonneesJourNbr 6
    byte bitDonneesJourCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesMoisStart 45
    #define bitDonneesMoisNbr 5
    const char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"}; //byte bitDonneesMoisCoeff[] = {1, 2, 4, 8, 10};
     
    #define bitDonneesAnneesStart 50
    #define bitDonneesAnneesNbr 6
    byte bitDonneesAnneesCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define nombreDeSeconde 59
    byte infoDonnees[ nombreDeSeconde];
    byte donneeBit = 0;
     
    volatile boolean mesureEnCours = false;                    
    volatile boolean mesureNouvelle = false;
     
    volatile unsigned long tempoDepart = millis();
    volatile unsigned long topSyncMilliSec = millis();
    volatile unsigned long departMesure = micros();
    volatile unsigned long departbit_Importante = millis();
     
    const unsigned int topSyncMinimum = 800;
     
    int unsigned  compteurSeconde = 0; //compteur des secondes 
     
    boolean top = false;
    boolean top1 = false;
    boolean top2 = false;
    boolean top3 = false;
    int minute = 0;
     
    void setup()
    {
     
       for (byte s = 0; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
       {                                             // A faire avant chaque cycle de minute
         infoDonnees[s] = 0;          
       }
     
      lcd.init(); // initialisation de l'afficheur
     
      Serial.begin (115200);
      pinMode(interruptPin, INPUT_PULLUP);    // entrée interruption avec pull up
      pinMode(ledSeconde, OUTPUT);            // 
      digitalWrite(ledSeconde, LOW);
      pinMode(led_bit, OUTPUT);               //led_bit en sortie et low
      digitalWrite(led_bit, LOW);
      attachInterrupt(digitalPinToInterrupt(interruptPin), impulsion_Interruption, CHANGE); //interruption pour rechercher le top syncrho du debut de la pemière seconde
    }
    //-----------------------------------------------------------------------
    void loop()
    {
     
      if (mesureNouvelle == true)
      {
        mesureNouvelle = false;
        topSyncAction();
      }
     
      calibrage_Seconde();            // renvoie aux fonctions régulièrement
      lecture_Seconde_Et_Bits();   
      ecriture_Bit_Importante();
     
      affichage_I2c();
     
      //extraireMinute();
      //extraireHeure();
      //extraireJourSemaineNom();
      //extraireJour();
      extraireMoisNom();             //je ne peux pas supprimer  cette appelle , sinon bug
      //extraireAnnee();
    }
     
    //------------------------------------------------------------------------
    void impulsion_Interruption()
    {
      if (digitalRead(interruptPin) == LOW && !mesureEnCours)
      {
        tempoDepart = millis();                                 // machine à état pour récuperer le top synchro (début de la 1° seconde)
        mesureEnCours = true;
      }
     
      if (digitalRead(interruptPin) == HIGH && mesureEnCours)
      {
        topSyncMilliSec = millis() - tempoDepart;
        mesureEnCours = false;
        mesureNouvelle = true;
      }
    }
     
    //-------------------------------------------------------------------------
    void topSyncAction()
    {
     
      if (topSyncMilliSec >= topSyncMinimum)          //Dans cette routine ,on  teste si l'on a un temps sans donnée(sans interruption) de plus de 800ms
      {                                                                   // si c'est le cas on met au niveau haut la pin 13 des secondes  (la led s'allume)
        departMesure = micros(); 
        Serial.println("Syncro_seconde----->0");      // affiche la syncrho
        digitalWrite (ledSeconde, HIGH);             // puis on va dans la routine "calibrage_seconde" via la loop.
     
        lcd.clear();                                 // permet d'effacer les anciennes écitures sur l'afficheur (I2C)
        compteurSeconde = 0;                         // compteurSeconde à 0
     
        top3 = true;                                 //pour pouvoir rentrer dans la fonction affichage et afficher la seconde 0                    
     
      }
    }
    //-------------------------------------------------------------------------
     
    void calibrage_Seconde()
    {
     
        if (micros() - departMesure >= 140000 )              
      {     
        digitalWrite(ledSeconde, LOW);                        
     
     
        if (micros() - departMesure >=999370)       // 999420 ici le temps la 59° ne doit pas être inf. à une seconde sinon on n'affiche la seconde 60 puis seconde 0           
        {                                                           // donc il faut  régler les secondes quelques micros secondes en moins
          digitalWrite(ledSeconde, HIGH);           // pour que l'interrupt tombe av que le compteur ne s'incrémente (un peu tiré par les cheveux, on peut faire mieux)
          departMesure = micros();                            
          departbit_Importante = millis(); 
          compteurSeconde ++;
          top2 =true;
          top = true;
                                                    //top3 = true; en autorisant l'affichage ici, j'ai un retard du debut de la 1° seconde de 20ms par rapport a la syncro, 1 fois sur deux
                                                  //je ne sais pas encore pourquoi...je les ai mis dans lecture seconde et cela fonctionne.
        }
      }
    }
    //--------------------------------------------------------------------------
     
    void lecture_Seconde_Et_Bits()                      
    {
     
     
         if ( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == HIGH && top )
                                       //&&compteurSeconde >= 20 && compteurSeconde <= 59) //pour ne lire que les secondes importantes
        { 
          digitalWrite (led_bit, HIGH);                  //on met le bit de donnée à 1
                                                         //departbit_Importante = millis();                     
          donneeBit = 1;                                 //si les conditions sont ok , le bit est à  1                                           
          delay (25);                                    //delay de 25 ms pour visualiser à l'ecran le top plus facile à utiliser que milli()
          digitalWrite (led_bit,LOW);                    //après 25 ms ,on mais le bit de donnée à 0
          top =false;                                    //oblige à  rentrer dans le prg uniquement sur le front montant d'une nouvelle seconde
          top1 = true;                                   // autorisation d'utilisation de la fonction void ecriture_Bit-Importante ()
     
        }
           if( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == LOW && top )
                                       //&& compteurSeconde >= 20 && compteurSeconde <= 59)  //pour ne lire que les secondes importantes
          {
           donneeBit = 0;                                 // si les conditions sont ok, le bit est à 0
           top = false;                                   //idem que plus haut
           top1 = true;                                   //idem que plus haut
     
          } 
    }
     
    //-----------------------------------------------------------------------------
                                                      // une  partie de  "void ecriture_Bit_Importante" n'est nécessaire que pour la visualisation à l'écran       
    void ecriture_Bit_Importante()                    // des données    
    { 
      if( top1)
      {
       //Serial.print ("seconde----->");Serial.print (compteurSeconde );Serial.print("    ");   Serial.print("Donnée------>"); Serial.println(donneeBit);
                                                          // test pour affichage liaison serie
       infoDonnees[compteurSeconde] = donneeBit;          // mise en emoire des données pour chaque seconde 
     
       top1 = false;                                     // interdit de re-rentrer dans cette fonction par l'intermediaire de la loop , attente d'autorisation
       top3 = true;                                      // autorisation d'utiliser  la fonction afficheur i2c
     
      }                                              
    } 
     
    //------------------------------------------------------------------------------
     
    int extraireMinute()
    {
      if (compteurSeconde == 59)
      {
      int minute = 0;
     
      for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
      {
        minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
      }
     
      return minute;
      }
    }
    //----------------------------------------------------------------------------------------
     
    int extraireHeure()
    {
      if (compteurSeconde == 59)
      {
      int heure = 0;
     
      for (int mInd = 0; mInd < bitDonneesHeuresNbr; mInd ++)
      {
        heure += bitDonneesHeuresCoeff[mInd] * infoDonnees[bitDonneesHeuresStart + mInd];
      }
     
      return heure;
      }
    }
    //------------------------------------------------------------------------------------------
     
     
     const char* extraireJourSemaineNom()
     {  
       byte jourSemaineIndex = 0;
     
      for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
      {
        jourSemaineIndex += infoDonnees[bitDonneesJourSemaine + jsn] << jsn;
      }
     
      return jourSemaineNom[jourSemaineIndex];
    } 
     
    //------------------------------------------------------------------------------------------
     
    int extraireJour()
    {
      if (compteurSeconde == 59)
      {
      int jour = 0;
     
      for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
      {
        jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
      }
     
      return jour;
      }
    }
     
    //------------------------------------------------------------------------------
    String extraireMoisNom() 
                                                 //bug avec const char*  
    {
      byte moisIndex = 0;
     
      for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
      {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
      }
     
      return mois[moisIndex];
      } 
     
    //--------------------------------------------------------------------------------
    int extraireAnnee()
    {
      if (compteurSeconde == 59)
      {
      int annee = 0;
     
      for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
      {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
      }
     
      return annee;
      }
    }
    //-------------------------------------------------------------------------------
    void affichage_I2c()
    {
       if( top3 ) 
       {                                               //autorisation donnée par la fonction void ecriture_Bit_Importante()
          int nouvelleMin = extraireMinute();
          int nouvelleHeure = extraireHeure(); 
          String nouveauJourSemaineNom = extraireJourSemaineNom();                                            //Serial.println(nouvelleMin); 
          int nouveauJour = extraireJour();
          String nouveauMois = extraireMoisNom(); 
          int nouvelleAnnee = extraireAnnee();
     
     
     
          if (compteurSeconde == 0 && (nouvelleAnnee >= 20 && nouvelleAnnee <= 30)) // ect...
          {                                                                                                               
     
           Serial.print (nouveauJourSemaineNom);
           Serial.print (" ");
     
           Serial.print (nouveauJour);
           Serial.print (" ");
     
           Serial.print(nouveauMois);
           Serial.print("  ");
     
           Serial.print ("20");
           Serial.print (nouvelleAnnee);
           Serial.print ("  ");
     
           Serial.print (nouvelleHeure);
           Serial.print (" heure(s)");
           Serial.print(" ");
           Serial.print (nouvelleMin);
           Serial.print (" minute(s)");
           Serial.println("  ");
           }
            if (nouvelleAnnee !=20)
            {
             Serial.println("attente donnees");
            }
            Serial.print(compteurSeconde);
            Serial.println("seconde(s)");
     
           top3 = false;                          
        }                                          
    }

    Emulateur


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    #define ledSeconde 12
    volatile unsigned long departMesure = micros();
    int unsigned  compteurSeconde = 0;
    boolean top1 = false;
    boolean top2 = false;
    boolean top3 = false;
    void setup()
    {
      pinMode(ledSeconde, OUTPUT);
      digitalWrite (ledSeconde, LOW);
      Serial.begin (115200);
    }
     
    void loop()
    {
      calibrage_Seconde();
      compteur();
      donneeBitPasImportante();
     
      donneeBitImportanteMinute();      //24s
      donneeBitImportanteHeure();       //31s
      donneeBitImportanteJour();        //36s              //secondes supportant une donnée
      donneeBitImportanteJourSemaine(); //42s
      donneeBitImportanteMois();        //48s
      donneeBitImportanteAnnee();       //55s
    }
     
     
    void calibrage_Seconde()
    {
     
      if (micros() - departMesure >= 23000 )
      {
        digitalWrite(ledSeconde, LOW);
     
     
        if (micros() - departMesure >= 999595)
        {
          digitalWrite(ledSeconde, HIGH);
          departMesure = micros();
          top1 = true;
          top2 = true;
          top3 = true;
          compteurSeconde ++;
     
     
        }
      }
    }
     
    void compteur()
    {
      if (compteurSeconde == 60)
      {
        compteurSeconde = 0;
      }
     
      if (top1)
      {
        Serial.println (compteurSeconde);            // uniquement pour tests
        top1 = false;
      }
    }
     
     
    void donneeBitPasImportante()
    {
      if ((compteurSeconde >= 0 && compteurSeconde <= 58)/*|| (compteurSeconde >= 56 && compteurSeconde <= 58))
    */ && (micros() - departMesure >= 500000) && top2 )
      {
        digitalWrite (ledSeconde, HIGH);
        delay (5);
        if (micros() - departMesure >= 750000)
        {
          digitalWrite (ledSeconde, LOW);
        }
        top2 = false;
      }
    }
     
    void donneeBitImportanteMinute()
    {
      if ( compteurSeconde == 24 && (micros() - departMesure >= 90000) && top3  )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }
     
    void donneeBitImportanteHeure()
    {
      if ( compteurSeconde == 31 && (micros() - departMesure >= 90000) && top3  )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }
     
    void donneeBitImportanteJour()
    {
      if ( compteurSeconde == 36 && (micros() - departMesure >= 90000) && top3  )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }
     
    void donneeBitImportanteJourSemaine()
    {
      if ( compteurSeconde == 42 && (micros() - departMesure >= 90000) && top3  )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }
     
    void donneeBitImportanteMois()
    {
      if ( compteurSeconde == 48 && (micros() - departMesure >= 90000) && top3 )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }
     
    void donneeBitImportanteAnnee()
    {
      if ( compteurSeconde == 55 && (micros() - departMesure >= 90000) && top3 )
      {
        digitalWrite (ledSeconde, HIGH);
        delay(35);
        digitalWrite (ledSeconde, LOW);
        top3 = false;
      }
    }

  6. #66
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    il y a toujours le bug
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (byte s = 1; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
      { // A faire avant chaque cycle de minute
        infoDonnees[s] = 0;
      }
    qui va corrompre la mémoire et les fonctions d'extraction comme extraireMinute() qui doivent TOUJOURS retourner quelque chose, c'est la promesse que vous faites au compilateur mais que vous ne tenez pas;

    Vous avez essayé en corrigeant cela ?

  7. #67
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Le test avait bien été fait avec la correction (je viens de corriger sur le poste)... Mais cela ne change rien.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (byte s = 0; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
      { // A faire avant chaque cycle de minute
        infoDonnees[s] = 0;
      }
    Je n'ai pas vraiment compris ce que je dois rajouter dans la fonction:

    les fonctions d'extraction comme extraireMinute() etc doivent TOUJOURS retourner quelque chose, c'est la promesse que vous faites au compilateur en déclarant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int extraireMinute()
    {
      if (compteurSeconde == 59)
      {
      int minute = 0;
     
      for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
      {
        minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
      }
     
      return minute;
      }
    }
    . Dans votre cas vous ne retournez rien si compteurSeconde ne vaut pas 59. je vous suggère de retourner -1 pour dire que l'info n'est pas dispo.

  8. #68
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    OK vous avez de la chance alors que la corruption mémoire n'ait pas impacté le reste

    pour les fonctions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int extraireMinute()
    {
      if (compteurSeconde == 59) {
        int minute = 0;
        for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++) {
          minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
        }
        return minute;
      }
      return -1; // si le compteur de seconde n'était pas à 59 il faut retourner quelque chose. On dit -1 pour 'pas encore prêt'
    }
    //bug avec const char* ou encadré par un "if(compteurSeconde ==59) { }"
    Quel bug voyez vous si vous mettez un le if ? c'est peut-être parce que vous ne retourniez rien non plus. il faudrait retourner quand même un char* qui pointe sur une chaîne vide.

  9. #69
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Pat

    Une suggestion, pourquoi ne pas "encadrer" d'un if (compteurSeconde == 59) les appels aux fonctions extraire...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	if( top3 )
    	{                                               //autorisation donnée par la fonction void ecriture_Bit_Importante()
    		if (compteurSeconde == 59)
    		{
    			int nouvelleMin = extraireMinute();
    			int nouvelleHeure = extraireHeure();
    			String nouveauJourSemaineNom = extraireJourSemaineNom();                                            //Serial.println(nouvelleMin);
    			int nouveauJour = extraireJour();
    			String nouveauMois = extraireMoisNom();
    			int nouvelleAnnee = extraireAnnee();
    		}
     
    ....
    et les supprimer dans les fonctions extraire...

    Pourrais-tu résumer le problème de extraireMoisNom()?

    J'ai regardé cette "roue" des valeurs style DCF77, en fait toutes les valeurs sont codées de façon identiques, donc une seule fonction d'extraction de valeurs est utile.
    Ces valeurs sont codées en BCD (binaire codé décimal), au lieu de faire la progression "habituelle", 1 2 4 8 16 32 64... BCD fait 1 2 3 4 8 10 20 30 40...

    Je te fais un exemple comment traiter la chose.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  10. #70
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Une suggestion, pourquoi ne pas "encadrer" d'un if (compteurSeconde == 59) les appels aux fonctions extraire...et les supprimer dans les fonctions extraire...
    Ce serait une très bonne simplification !!

    (faut juste le savoir et ne pas appeler les fonctions sinon. à documenter)

  11. #71
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjout Pat

    Citation Envoyé par Pat42 Voir le message
    .... Sinon, modifier le nbr de micro-seconde dans le prg de l'émulateur et faire coïncider les fronts montants des dernières secondes de la minute entre l'émulateur (pin D12) et le prg principal (pin D13) ( les différences de micro secondes s'ajoutent pour faire de belles ms en avance ou en retard à la fin de la minute et qui peuvent éventuellement faire sortir la donnée de la fenêtre de lecture)....
    Ceci va à l'encontre du principe de ce genre de transmission, ton récepteur doit être entièrement "esclave" de l'émetteur au point de vue tempo, il doit se synchroniser sur chaque seconde, donc on ne devrait pas bidouiller des micro-secondes pour aligner les fenêtres.
    Au départ de ce projet, quand je proposait d'utiliser des interrupt pour mesurer les top, ce n'était pas pour détecter le début de la minute, mais pour mesurer chaque top seconde, on est, ainsi, synchrone avec l'émetteur.

    Citation Envoyé par Pat42 Voir le message
    Je pense que de ce côté là, on peut faire beaucoup mieux pour récupérer les données.
    Oui, baser tout le timing de ton programme sur le tempo de l'émetteur.

    Ci-dessous, la méthode "standard" pour extraire les données de la "roue des secondes", avec l'exemple pour la minute et le mois.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
     
    #define bitDonneesMinutesStart 21
    #define bitDonneesMinutesNbr 7
     
    #define bitDonneesMoisStart 45
    #define bitDonneesMoisNbr 5
    char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"}; //byte bitDonneesMoisCoeff[] = {1, 2, 4, 8, 10};
    ...
    	int nouvelleMin = donneesExtraire(bitDonneesMinutesStart, bitDonneesMinutesNbr);
    	String nouveauMoisNom = mois[donneesExtraire(bitDonneesMoisStart, bitDonneesMoisNbr)];
    ...
     
    /*------------------------------------------------------------------------------
    	Extraction de donnees dans le tableau infoDonnees
    	les donnees sont en decimal, si siBcd == true elles sont transformées en BCD
    '*------------------------------------------------------------------------------
    */
    int donneesExtraire(int bitStart, int bitNombre)
    {
    	int extrait = 0;
     
    	for (int bitIndex = 0; bitIndex < bitNombre; bitIndex ++)
    	{
    		extrait += infoDonnees[(bitStart+0) + bitIndex] << bitIndex;
    	}
     
    	extrait = convBcdToDec(extrait);                                 // Transformer du BCD en decimal
    	return extrait;
    }
     
    byte convBcdToDec(byte val) { return( (val/16*10) + (val%16) ); }        // Converti du BCD en code decimal
    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  12. #72
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Bonjour,

    Dans l'ordre ,

    //bug avec const char* ou encadré par un "if(compteurSeconde ==59) { }"
    Quel bug voyez vous si vous mettez un le if ? c'est peut-être parce que vous ne retourniez rien non plus. il faudrait retourner quand même un char* qui pointe sur une chaîne vide.

    j'ai bien fait le nécessaire sur les fonctions qui en avaient besoin ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    const char* extraireMoisNom() 
    {
     
         if(compteurSeconde == 59 )
        {
         byte moisIndex = 0;
     
          for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
          {
          moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
          }
     
        return mois[moisIndex];
        }
    return -1;
    }
    Mais rien à faire ! Les secondes s'égrainent sans plus aucune indication de l'heure, des mns ect...Il doit avoir un truc pas clair dans ces quelques lignes...



    Une suggestion, pourquoi ne pas "encadrer" d'un if (compteurSeconde == 59) les appels aux fonctions extraire...

    if( top3 )
    { //autorisation donnée par la fonction void ecriture_Bit_Importante()
    if (compteurSeconde == 59)
    {
    int nouvelleMin = extraireMinute();
    int nouvelleHeure = extraireHeure();
    String nouveauJourSemaineNom = extraireJourSemaineNom(); //Serial.println(nouvelleMin);
    int nouveauJour = extraireJour();
    String nouveauMois = extraireMoisNom();
    int nouvelleAnnee = extraireAnnee();
    }
    Donc j'ai fait les modifs,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if( top3 ) 
       {   
        if( compteurSeconde == 59)
        {                                                          
           nouvelleMin = extraireMinute();
           nouvelleHeure = extraireHeure(); 
           nouveauJourSemaineNom = extraireJourSemaineNom();                                            
           nouveauJour = extraireJour();
           nouveauMois = extraireMoisNom(); 
           nouvelleAnnee = extraireAnnee();
        } 
        ...
    ...supprimé toutes les conditions if(compteurSeconde == 59)
    et ça fonctionne impeccable, j'ai même pu supprimer dans la loop l'appel à la fonction" nouveauMois" .


    le prg épuré,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
     
    //----- Adressage matériel -----
    LiquidCrystal_I2C lcd(0x27, 20, 4);
    //LiquidCrystal_I2C lcd(0x3F,20,4);
    //------------------------------
    #define interruptPin 2   
    #define led_bit 12      
    #define ledSeconde 13
     
          int nouvelleMin;
          int nouvelleHeure; 
          String nouveauJourSemaineNom;                                            
          int nouveauJour;
          String nouveauMois; 
          int nouvelleAnnee; 
     
    #define bitDonneesMinutesStart 21
    #define bitDonneesMinutesNbr 7
    byte bitDonneesMinutesCoeff[] = {1, 2, 4, 8, 10, 20, 40};
     
    #define bitDonneesHeuresStart 29
    #define bitDonneesHeuresNbr 6
    byte bitDonneesHeuresCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesJourSemaine 42
    #define bitDonneesJourSemaineNbr 3
    const char* jourSemaineNom[] = {"-", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
     
    #define bitDonneesJourStart 36
    #define bitDonneesJourNbr 6
    byte bitDonneesJourCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define bitDonneesMoisStart 45
    #define bitDonneesMoisNbr 5
    const char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"}; //byte bitDonneesMoisCoeff[] = {1, 2, 4, 8, 10};
     
    #define bitDonneesAnneesStart 50
    #define bitDonneesAnneesNbr 6
    byte bitDonneesAnneesCoeff[] = {1, 2, 4, 8, 10, 20};
     
    #define nombreDeSeconde 59
    byte infoDonnees[ nombreDeSeconde];
    byte donneeBit = 0;
     
    volatile boolean mesureEnCours = false;                    
    volatile boolean mesureNouvelle = false;
     
    volatile unsigned long tempoDepart = millis();
    volatile unsigned long topSyncMilliSec = millis();
    volatile unsigned long departMesure = micros();
    volatile unsigned long departbit_Importante = millis();
     
    const unsigned int topSyncMinimum = 800;
     
    int unsigned  compteurSeconde = 0; //compteur des secondes 
     
    boolean top = false;
    boolean top1 = false;
    boolean top2 = false;
    boolean top3 = false;
    int minute = 0;
     
    void setup()
    {
     
       for (byte s = 0; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
       {                                             // A faire avant chaque cycle de minute
         infoDonnees[s] = 0;          
       }
     
      lcd.init(); // initialisation de l'afficheur
     
      Serial.begin (115200);
      pinMode(interruptPin, INPUT_PULLUP);    // entrée interruption avec pull up
      pinMode(ledSeconde, OUTPUT);            // 
      digitalWrite(ledSeconde, LOW);
      pinMode(led_bit, OUTPUT);               //led_bit en sortie et low
      digitalWrite(led_bit, LOW);
      attachInterrupt(digitalPinToInterrupt(interruptPin), impulsion_Interruption, CHANGE); //interruption pour rechercher le top syncrho du debut de la pemière seconde
    }
    //-----------------------------------------------------------------------
    void loop()
    {
     
      if (mesureNouvelle == true)
      {
        mesureNouvelle = false;
        topSyncAction();
      }
     
      calibrage_Seconde();            // renvoie aux fonctions régulièrement
      lecture_Seconde_Et_Bits();   
      ecriture_Bit_Importante();
     
      affichage_I2c();
    }
     
    //------------------------------------------------------------------------
    void impulsion_Interruption()
    {
      if (digitalRead(interruptPin) == LOW && !mesureEnCours)
      {
        tempoDepart = millis();                                 // machine à état pour récuperer le top synchro (début de la 1° seconde)
        mesureEnCours = true;
      }
     
      if (digitalRead(interruptPin) == HIGH && mesureEnCours)
      {
        topSyncMilliSec = millis() - tempoDepart;
        mesureEnCours = false;
        mesureNouvelle = true;
      }
    }
     
    //-------------------------------------------------------------------------
    void topSyncAction()
    {
     
      if (topSyncMilliSec >= topSyncMinimum)          //Dans cette routine ,on  teste si l'on a un temps sans donnée(sans interruption) de plus de 800ms
      {                                                                   // si c'est le cas on met au niveau haut la pin 13 des secondes  (la led s'allume)
        departMesure = micros(); 
        Serial.println("Syncro_seconde----->0");      // affiche la syncrho
        digitalWrite (ledSeconde, HIGH);             // puis on va dans la routine "calibrage_seconde" via la loop.
     
        lcd.clear();                                 // permet d'effacer les anciennes écitures sur l'afficheur (I2C)
        compteurSeconde = 0;                         // compteurSeconde à 0
     
        top3 = true;                                 //pour pouvoir rentrer dans la fonction affichage et afficher la seconde 0                    
     
      }
    }
    //-------------------------------------------------------------------------
     
    void calibrage_Seconde()
    {
     
        if (micros() - departMesure >= 140000 )              
      {     
        digitalWrite(ledSeconde, LOW);                        
     
     
        if (micros() - departMesure >=999370)       // 999420 ici le temps la 59° ne doit pas être inf. à une seconde sinon on n'affiche la seconde 60 puis seconde 0           
        {                                                           // donc il faut  régler les secondes quelques micros secondes en moins
          digitalWrite(ledSeconde, HIGH);           // pour que l'interrupt tombe av que le compteur ne s'incrémente (un peu tiré par les cheveux, on peut faire mieux)
          departMesure = micros();                            
          departbit_Importante = millis(); 
          compteurSeconde ++;
          top2 =true;
          top = true;
                                                    //top3 = true; en autorisant l'affichage ici, j'ai un retard du debut de la 1° seconde de 20ms par rapport a la syncro, 1 fois sur deux
                                                  //je ne sais pas encore pourquoi...je les ai mis dans lecture seconde et cela fonctionne.
        }
      }
    }
    //--------------------------------------------------------------------------
     
    void lecture_Seconde_Et_Bits()                      
    {
     
     
         if ( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == HIGH && top )
                                       //&&compteurSeconde >= 20 && compteurSeconde <= 59) //pour ne lire que les secondes importantes
        { 
          digitalWrite (led_bit, HIGH);                  //on met le bit de donnée à 1
                                                         //departbit_Importante = millis();                     
          donneeBit = 1;                                 //si les conditions sont ok , le bit est à  1                                           
          delay (25);                                    //delay de 25 ms pour visualiser à l'ecran le top plus facile à utiliser que milli()
          digitalWrite (led_bit,LOW);                    //après 25 ms ,on mais le bit de donnée à 0
          top =false;                                    //oblige à  rentrer dans le prg uniquement sur le front montant d'une nouvelle seconde
          top1 = true;                                   // autorisation d'utilisation de la fonction void ecriture_Bit-Importante ()
     
        }
           if( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == LOW && top )
                                       //&& compteurSeconde >= 20 && compteurSeconde <= 59)  //pour ne lire que les secondes importantes
          {
           donneeBit = 0;                                 // si les conditions sont ok, le bit est à 0
           top = false;                                   //idem que plus haut
           top1 = true;                                   //idem que plus haut
     
          } 
    }
     
    //-----------------------------------------------------------------------------
                                                      // une  partie de  "void ecriture_Bit_Importante" n'est nécessaire que pour la visualisation à l'écran       
    void ecriture_Bit_Importante()                    // des données    
    { 
      if( top1)
      {
       //Serial.print ("seconde----->");Serial.print (compteurSeconde );Serial.print("    ");   Serial.print("Donnée------>"); Serial.println(donneeBit);
                                                          // test pour affichage liaison serie
       infoDonnees[compteurSeconde] = donneeBit;          // mise en emoire des données pour chaque seconde 
     
       top1 = false;                                     // interdit de re-rentrer dans cette fonction par l'intermediaire de la loop , attente d'autorisation
       top3 = true;                                      // autorisation d'utiliser  la fonction afficheur i2c
     
      }                                              
    } 
     
    //------------------------------------------------------------------------------
     
    int extraireMinute()
    {
      //if (compteurSeconde == 59)
      //{
      int minute = 0;
     
      for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
      {
        minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
      }
     
      return minute;
      }
      //return -1;
    //}
    //----------------------------------------------------------------------------------------
     
    int extraireHeure()
    {
      int heure = 0;
     
        for (int mInd = 0; mInd < bitDonneesHeuresNbr; mInd ++)
        {
        heure += bitDonneesHeuresCoeff[mInd] * infoDonnees[bitDonneesHeuresStart + mInd];
        }
     
      return heure;
    }
    //------------------------------------------------------------------------------------------
     
     
    const char* extraireJourSemaineNom()
    {  
      byte jourSemaineIndex = 0;
     
       for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
        {
         jourSemaineIndex += infoDonnees[bitDonneesJourSemaine + jsn] << jsn;
        }
     
       return jourSemaineNom[jourSemaineIndex];
    }  
    //------------------------------------------------------------------------------------------
     
    int extraireJour()
    {
     int jour = 0;
     
        for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
        {
         jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
        }
     
     return jour;
    }
     
    //------------------------------------------------------------------------------
     
     
    const char* extraireMoisNom() 
    {
     byte moisIndex = 0;
     
        for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
        {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
        }
     
      return mois[moisIndex];
    }
    //--------------------------------------------------------------------------------
    int extraireAnnee()
    {
      int annee = 0;
     
        for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
        {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
        }
     
      return annee;
    }
    //-------------------------------------------------------------------------------
    void affichage_I2c()
    {
       if( top3 ) 
       {   
        if( compteurSeconde == 59)
        {                                                           //autorisation donnée par la fonction void ecriture_Bit_Importante()
           nouvelleMin = extraireMinute();
           nouvelleHeure = extraireHeure(); 
           nouveauJourSemaineNom = extraireJourSemaineNom();                                            //Serial.println(nouvelleMin); 
           nouveauJour = extraireJour();
           nouveauMois = extraireMoisNom(); 
           nouvelleAnnee = extraireAnnee();
        } 
     
     
          if (compteurSeconde == 0 && (nouvelleAnnee >= 20 && nouvelleAnnee <= 30)) // ect...
          {                                                                                                               
     
           Serial.print (nouveauJourSemaineNom);
           Serial.print (" ");
     
           Serial.print (nouveauJour);
           Serial.print (" ");
     
           Serial.print(nouveauMois);
           Serial.print("  ");
     
           Serial.print ("20");
           Serial.print (nouvelleAnnee);
           Serial.print ("  ");
     
           Serial.print (nouvelleHeure);
           Serial.print (" heure(s)");
           Serial.print(" ");
           Serial.print (nouvelleMin);
           Serial.print (" minute(s)");
           Serial.println("  ");
           }
            if ( nouvelleAnnee !=20)
            {
             Serial.println("attente donnees");
            }
            Serial.print(compteurSeconde);
            Serial.println("seconde(s)");
     
           top3 = false;                          
        }                                          
     
    }

    Ceci va à l'encontre du principe de ce genre de transmission, ton récepteur doit être entièrement "esclave" de l'émetteur au point de vue tempo, il doit se synchroniser sur chaque seconde, donc on ne devrait pas bidouiller des micro-secondes pour aligner les fenêtres.
    Au départ de ce projet, quand je proposait d'utiliser des interrupt pour mesurer les top, ce n'était pas pour détecter le début de la minute, mais pour mesurer chaque top seconde, on est, ainsi, synchrone avec l'émetteur.

    Au départ du projet, javais la ferme intention de synchroniser le prg au top de chaque seconde de l'heure étalon, pour qu'effectivement le pgr soit bien esclave de l'émetteur et n'être tributaire d'aucun réglage.

    Dans ce pgr, malgré tout, il faudrait vraiment que le quartz de l'arduino ne donne pas l'heure pour que les données sortent de la fenêtre de lecture et que l'on est besoin d'y retoucher.

    Mais je vais bien sur, car c'est comme cela que ça doit fonctionner tenter de faire une synchro sur chaque seconde et lire le bit de donné d'une façon un peu différente.
    Je vais me servir de ton exemple mais dur dur pour moi de tout comprendre...

    Il y a une "chose" pas très claire par mis tant d'autres qui m'échappent.

    Dans le pgr

    1) j'ai supprimé les appels dans la loop aux différentes fonctions
    2) les appels aux fonctions à extraire ont été encadrés par une condition if

    Alors! Est ce que les fonctions comme par ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int extraireAnnee()
    {
      int annee = 0;
     
        for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
        {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
        }
     
      return annee;
    }

    sont lues et actives s' il n'y a pas d'appel à ces fonctions (étant donné que le prg, lui évidemment, continu à tourner) j'ai un doute...

    Bonne journée à vous

    pat

  13. #73
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Salut Pat
    Citation Envoyé par Pat42 Voir le message
    ...Alors! Est ce que les fonctions comme par ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int extraireAnnee()
    {
      int annee = 0;
     
        for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
        {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
        }
     
      return annee;
    }

    sont lues et actives s' il n'y a pas d'appel à ces fonctions (étant donné que le prg, lui évidemment, continu à tourner) j'ai un doute...
    Oui, à chaque fois que la foonction affichage_I2c() est évoquée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void affichage_I2c()
    {
    	if( top3 )
    	{
    		if( compteurSeconde == 59)
    		{                                                           //autorisation donnée par la fonction void ecriture_Bit_Importante()
    			nouvelleMin = extraireMinute();
    			nouvelleHeure = extraireHeure();
    			nouveauJourSemaineNom = extraireJourSemaineNom();                                            //Serial.println(nouvelleMin);
    			nouveauJour = extraireJour();
    			nouveauMois = extraireMoisNom();
    			nouvelleAnnee = extraireAnnee();
    		}
    Et c'est le cas depuis loop() et sans conditions.

    J'ai essayé le couple Programme principal Emulateur du post #65, ça ne fonctionne pas, j'ai toujours 0 aux minutes, par exemple!
    Un truc que je n'ai toujours pas réussi à comprendre, c'est comment tu définis si c'est un 1 ou un 0 qui est reçu. Autre remarque, ton émulateur génère une impulsion toutes les 500 milliSecondes, pourquoi?

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  14. #74
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Pat42 Voir le message
    Bonjour,
    j'ai bien fait le nécessaire sur les fonctions qui en avaient besoin ex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const char* extraireMoisNom() 
    {
         if(compteurSeconde == 59 )  {
         byte moisIndex = 0;
          for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++) {
            moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
          }
          return mois[moisIndex];
        }
      return -1;
    }
    ==> -1 ce n'est pas un char*, ici il vaudrait mieux retourner NULL ou alors comme vous avez un 'faux' mois dans le tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"};
    vous pouvez retourner mois[0]

  15. #75
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Pat
    Citation Envoyé par jpbbricole Voir le message
    Bonjout Pat

    Ceci va à l'encontre du principe de ce genre de transmission, ton récepteur doit être entièrement "esclave" de l'émetteur au point de vue tempo, il doit se synchroniser sur chaque seconde, donc on ne devrait pas bidouiller des micro-secondes pour aligner les fenêtres.
    Au départ de ce projet, quand je proposait d'utiliser des interrupt pour mesurer les top, ce n'était pas pour détecter le début de la minute, mais pour mesurer chaque top seconde, on est, ainsi, synchrone avec l'émetteur.


    Oui, baser tout le timing de ton programme sur le tempo de l'émetteur.
    Je reviens sur ce que j'ai dit, en fait, je n'avais pas du tout compris le système de codage de France Inter, j'était axé sur DCF77 , donc mes remarques ne sont pas très pertinentes.
    C'est en lisant ce document que j'ai compris.

    Question: Le signal final à décoder est bien celui qui est dans le post #31 où il y a respectivement un 0 et un 1 ?

    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  16. #76
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Bonsoir,


    Question: Le signal final à décoder est bien celui qui est dans le post #31 où il y a respectivement un 0 et un 1 ?
    Ici, la lecture des données, donnée à 1 ou à 0
    Remarque: la valeur de 115 ms comme condition est là pour sauter le top seconde et ne pas le prendre en compte dans la lecture, mais on aurait très bien pu faire la lecture des données en incluant le top seconde.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    void lecture_Seconde_Et_Bits()                      
    {
     
     
         if ( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == HIGH && top )
     
        { 
          digitalWrite (led_bit, HIGH);                  //on met le bit de donnée à 1
                                                         //departbit_Importante = millis();                     
          donneeBit = 1;                                 //si les conditions sont ok , le bit est à  1                                           
          delay (25);                                    //delay de 25 ms pour visualiser à l'ecran le top plus facile à utiliser que milli()
          digitalWrite (led_bit,LOW);                    //après 25 ms ,on mais le bit de donnée à 0
          top =false;                                    //oblige à  rentrer dans le prg uniquement sur le front montant d'une nouvelle seconde
          top1 = true;                                   // autorisation d'utilisation de la fonction void ecriture_Bit-Importante ()
     
        }
           if( digitalRead (ledSeconde) == HIGH && millis()- departbit_Importante >= 115 && digitalRead (interruptPin) == LOW && top )
     
          {
           donneeBit = 0;                                 // si les conditions sont ok, le bit est à 0
           top = false;                                   //idem que plus haut
           top1 = true;                                   //idem que plus haut
     
          } 
    }
    On sort de la fonction ci-dessus pour rentrer dans celle ci et mettre les données en mémoire .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void ecriture_Bit_Importante()                    // des données    
    { 
      if( top1)
      {
     
       infoDonnees[compteurSeconde] = donneeBit;          // mise en emoire des données pour chaque seconde 
     
       top1 = false;                                     // interdit de re-rentrer dans cette fonction par l'intermediaire de la loop , attente d'autorisation
       top3 = true;                                      // autorisation d'utiliser  la fonction afficheur i2c
     
      }                                              
    }
    Concernant l' émulateur, je rajoute une photo de mon écran...


    ==> -1 ce n'est pas un char*, ici il vaudrait mieux retourner NULL ou alors comme vous avez un 'faux' mois dans le tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* mois[] = {"-", "Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"};
    vous pouvez retourner mois[0]

    Merci pour l'explication car je ne comprenais pas vraiment...
    Comme on a simplifié le prg, Il n'y en a plus besoin, mais je vais tester pour mon apprentissage et pour mes futures prg.

    Merci à vous.

    Pat
    Images attachées Images attachées  

  17. #77
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut Décodage code horaire 162kh
    Bonjour à tous,

    Je prends un peu de temps et je déterre mon post " mon horloge à moi" avant de le mettre « résolu » car j’aimerais vous faire partager les photos de mon récepteur horaire étalon terminé.

    1 ) vue d’ensemble de la face av.
    2) intérieur de coffret avec la carte arduino nano implantée

    Tout d’abord pour ceux qui on suivi, je ne suis pas un AS en programmation arduino, il m’a fallu pas mal de temps et beaucoup d’aide pour mette au point ce programme de décodage.

    Après les vacances d’Août je me suis remis au boulot pour modifier le prg.
    En effet la première version souffrait d’un défaut, le programme n’était pas esclave des tops synchro seconde reçues (remarque de JP).
    La synchronisation de début de minute était attendue par la machine à état que m’avait concocté JP, puis le programme créait lui-même ses propres top seconde (voir les anciens posts).
    Du coup, il fallait régler par programmation la minute pile poil, (avec l’oscillo num) pour faire que les bits de données tombent bien dans les créneaux de lecture.
    Si l’on programmait une autre carte arduino , il fallait prendre en compte la fréquence du quartz qui est obligatoirement différente d’une carte à l’autre et refaire un réglage précis .

    Dans cette nouvelle version simplifiée , la synchro principale (détection du silence puis début de la première seconde ) est toujours prise en compte par la machine à état, mais ce qui change c’est que le programme se re-synchronise toutes les secondes à chaque top seconde reçu.
    Seule la seconde 59 est créée puisqu’elle n’existe pas dans la réception du signal.

    J’ai échangé l’afficheur "2 lignes" contre un "4 lignes", ce qui m’a permis de rajouter une mesure du niveau du signal reçu par l’intermédiaire d’une entrée analogique .

    Et maintenant, la dernière petite difficulté que je vais vous exposer et que j’ai résolu d’une façon pas très élégante.

    JP m’a écrit un petit bout de prg me permettant d’afficher le nom des mois avec le coef des bits reçu.
    Je réexplique, le mois courant est donné par les secondes : 45, 46, 47, 48, 49.

    Les bits valent respectivement
    Pour la 45° seconde - 1
    Pour la 46° seconde – 2
    Pour la 47° seconde – 4
    Pour la 48° seconde – 8
    Pour la 49° seconde – 10 (le prg donne 16 comme valeur)

    Par ex : Si le mois courant est Septembre (9),les bits concernés dans les secondes 45 et 48 seront à 1 et les autre à 0
    Si le mois courant est juillet (7), seuls les bit des secondes 45, 46 ,47 seront à 1

    Et voici le pb… Quand le mois d’octobre est arrivé (c'est-à-dire le bit de la seconde 49 qui à pour coefficient 10 ) le mois ne s’affichait plus .
    Après avoir chercher le pourquoi du comment, j’ai eu l’idée d’allé voir ce que contenait
    mois, et… il contenait forcément la valeur 16 .
    En fait, on a pas dit au programme que le coef du bit de la seconde 49 valait 10 et non 16.

    Du coup, j’ai résolu le pb en mettant des espaces vides entre septembre et octobre pour qu’octobre soit placé à la seizième place, et là bien sur , tout est rentré dans l’ordre pour les mois à suivre.

    Tout ce laïus pour savoir s’il n’ y a pas une façon plus élégante ( je pense que oui) de gérer cela en donnant un coef de dix, à la place du coef naturel seize, au bit de la seconde 49.

    Merci à vous

    Ici j'ai mis le mois d'Octobre à la 16° place

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     #define bitDonneesMoisStart 45
      #define bitDonneesMoisNbr 5
      const char* moisNom[] = {"--", "Jan", "Fev", "Mars", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", " ", " ", " ", " "," ", " ", "Oct", "Nov", "Dec"};
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Reste du code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const char* extraireMoisNom() 
     {
        byte moisIndex = 0;
     
         for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
         {                                                                                                                       
            moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
         }
     
       return moisNom[moisIndex];

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------


    Il faut que j'écrive des commentaires clairs, car 2 mois après, il y avait déjà certaines parties du programme qui commençent à devenir flou dans mon esprit.
    Sans doute , y a t 'il encore beaucoup à redire sur le programme en lui même, mais...! c'est en forgeant que l'on devient forgeron...c'est ce que l'on m'a dit


    Le programme complet



    [CODE]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
     #include <Wire.h>
      #include <LiquidCrystal_I2C.h>
     
      //----- Adressage matériel -----
        LiquidCrystal_I2C lcd(0x27, 20, 4);
      //LiquidCrystal_I2C lcd(0x3F,20,4);
      //------------------------------
      #define interruptPin 2   
      #define led_bit 12      
      #define ledSeconde 13
     
      #define bitDonneesMinutesStart 21
      #define bitDonneesMinutesNbr 7
      byte bitDonneesMinutesCoeff[] = {1, 2, 4, 8, 10, 20, 40};
     
      #define bitDonneesHeuresStart 29
      #define bitDonneesHeuresNbr 6
      byte bitDonneesHeuresCoeff[] = {1, 2, 4, 8, 10, 20};
     
      #define bitDonneesJourSemaineStart 42
      #define bitDonneesJourSemaineNbr 3
      const char* jourSemaineNom[] = {"--", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
     
      #define bitDonneesJourStart 36
      #define bitDonneesJourNbr 6
      byte bitDonneesJourCoeff[] = {1, 2, 4, 8, 10, 20};
     
      #define bitDonneesMoisStart 45
      #define bitDonneesMoisNbr 5
      const char* moisNom[] = {"--", "Jan", "Fev", "Mars", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", " ", " ", " ", " "," ", " ", "Oct", "Nov", "Dec"};
     
      #define bitDonneesAnneesStart 50
      #define bitDonneesAnneesNbr 6
      byte bitDonneesAnneesCoeff[] = {1, 2, 4, 8, 10, 20};
     
      #define nombreDeSeconde 59
      byte infoDonnees[ nombreDeSeconde];
      byte donneeBit = 0;
     
      volatile boolean mesureEnCours = false;                    
      volatile boolean mesureNouvelle = false;
     
      volatile boolean mesureNouvelleSeconde = false;
      volatile unsigned long tempoDepart = millis();
      volatile unsigned long topSyncMilliSec = millis();
      volatile unsigned long departMesure = millis();
      const unsigned int topSyncMinimum = 800;
     
      int unsigned  compteurSeconde = 0;                       //compteur des secondes 
     
      int nouvelleMin;
      int nouvelleHeure; 
      String nouveauJourSemaineNom;                                            
      int nouveauJour;
      String nouveauMois; 
      int nouvelleAnnee;
      int testNouvelleAnnee; 
     
      boolean top = false;
      boolean top1 = false;
      boolean top2 = false;
      boolean top3 = true;  //pour indiquer "attente donnée"
      boolean top4 = true;
      boolean top5 = false;
      int minute = 0;
     
      float tension = 0;
      int valeur =0;
     
      void setup()
      {
       lcd.backlight();
     
       for (byte s = 0; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
       {                                             // A faire avant chaque cycle de minute
         infoDonnees[s] = 0;          
       }
     
      lcd.init(); // initialisation de l'afficheur
     
      Serial.begin (115200);
      pinMode(interruptPin, INPUT_PULLUP);    // entrée interruption avec pull up
      pinMode(ledSeconde, OUTPUT);            // 
      digitalWrite(ledSeconde, LOW);
      pinMode(led_bit, OUTPUT);               //led_bit en sortie et low
      digitalWrite(led_bit, LOW);
      attachInterrupt(digitalPinToInterrupt(interruptPin), impulsion_Interruption, CHANGE); //interruption pour rechercher 
     
     
      lcd.setCursor(0,0);
      lcd.print("attente synchro");
     
     
      }
     
      //-----------------------------------------------------------------------
      void loop()
      {
     
          if (mesureNouvelle == true)
          {                                                                    // appel de la fonction "topSyncAction" si le top synchro est détecté
            mesureNouvelle = false;
            topSyncAction();
          }
     
      topSeconde();
      ecriture_Bit_Importante();                                            //appelle des fonctions
      affichage_I2c();
     
      niveauSignal();
      }
     
      //------------------------------------------------------------------------
      void impulsion_Interruption()
      {
          if (digitalRead(interruptPin) == LOW && !mesureEnCours)
          {
            tempoDepart = millis();                                                           // machine à état pour récupérer le top synchro (début de la 1° seconde)
            mesureEnCours = true;
          }
     
            if (digitalRead(interruptPin) == HIGH && mesureEnCours)
            {
              topSyncMilliSec = millis() - tempoDepart;
              mesureEnCours = false;
              mesureNouvelle = true;
     
            }
     
      }
     
      //-------------------------------------------------------------------------
      void topSyncAction()
      {
     
          if (topSyncMilliSec >= topSyncMinimum )         
          {                                                                      
            digitalWrite (ledSeconde, HIGH);   
            compteurSeconde = 0;
            departMesure = millis();
            //Serial.println (millis());
            //Serial.print (compteurSeconde);
            //Serial.println ("Syncro_seconde----->0");                                           // top debut de la 1° seconde (synchro)
            delay (5);
            //Serial.println (millis());
            digitalWrite (ledSeconde, LOW);
            top1 = true;                            // permet de rentrer dans la fonction topSeconde qu'au top synchro, a un reset ou la mise en marche du pgr.
            top2 = true ;                          // permet d'attendre le top synchro, l'affichage des secondes demarre avec la seconde 0
            lcd.clear();                          //efface les donneeés sur l'ecran   au top synchro 
     
           }
           top5 = true;                          //on indique le niveau du signal à chaque interruption
      }
     
      //-------------------------------------------------------------------------
     
      void topSeconde()
      {
           if(millis()- departMesure >= 950 && digitalRead (interruptPin)== HIGH &&( compteurSeconde < 59) && top1 ) //<59 empeche le compteur d'indiquer 60 par un nouveau passage dans cette routine
           {                                                                                                                // avant le top Synchro ainsi que le top1 qui permet de renter dans le
            digitalWrite (ledSeconde, HIGH);                                                                                // topSeconde uniquement au top syncrho
            compteurSeconde++; 
            //Serial.println (compteurSeconde);
            departMesure = millis();
            delay (5);                                                                 //génère à partir des interrupts les tops seconde sauf la 59°s
            digitalWrite (ledSeconde, LOW);
                                                                                      //Serial.println (millis());
            delay (105);
                                                                                       //Serial.println (millis());
            lectureBit();
           }
     
     
             if(compteurSeconde == 58 && (millis() - departMesure >= 1000))
             {
               digitalWrite (ledSeconde, HIGH);
     
               compteurSeconde++; 
               departMesure = millis(); 
               delay (5);                                                                   //génère  le top 59°s manquant dans la réception
               digitalWrite (ledSeconde, LOW);
               //Serial.println (compteurSeconde);
               lectureBit();
     
             }
     
      }
      //---------------------------------------------------------------------------
     
      void lectureBit()
      {
           if( digitalRead (interruptPin) == HIGH)                                          
           {
            digitalWrite(ledSeconde, HIGH);
            delay (5);                                           //lit le bit 105 ms aprés le top seconde. Si le bit est à 1, il y a une donnée valide.
            digitalWrite (ledSeconde, LOW);
            donneeBit = 1;
            top = true;
           }
     
        else
        {
         donneeBit = 0;
         top = true;                                       // si pas de bit lue aprés 105 ms, le bit est égal à 0 .
        }
     
      }
      //---------------------------------------------------------------------------
     
      void ecriture_Bit_Importante()                        
      { 
      if(top)
      {
       //Serial.print ("seconde----->");Serial.print (compteurSeconde );Serial.print("    ");   Serial.print("Donnée------>"); Serial.println(donneeBit);
       infoDonnees[compteurSeconde] = donneeBit;    
       top = false;  
       top2 = true; 
       //top5 = true;   
      }                                             
      } 
     
      //------------------------------------------------------------------------------
     
      int extraireMinute()
     {
       int minute = 0;
     
          for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
          {
           minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
          }
     
       return minute;
     }
     
      //-------------------------------------------------------------------------------
     
      int extraireHeure()
     {
       int heure = 0;
     
          for (int mInd = 0; mInd < bitDonneesHeuresNbr; mInd ++)
         {
           heure += bitDonneesHeuresCoeff[mInd] * infoDonnees[bitDonneesHeuresStart + mInd];
         }
     
       return heure;
     }
     
      //---------------------------------------------------------------------------------
     
      const char* extraireJourSemaineNom()
     { 
        byte jourSemaineIndex = 0;
     
         for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
        {
           jourSemaineIndex += infoDonnees[bitDonneesJourSemaineStart + jsn] << jsn;
        }
     
        return jourSemaineNom[jourSemaineIndex];
     }
      //---------------------------------------------------------------------------------
     
      int extraireJour()
     {
       int jour = 0;
     
          for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
         {
            jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
         }
     
       return jour;
     }
      //----------------------------------------------------------------------------------
     
      const char* extraireMoisNom() 
     {
        byte moisIndex = 0;
     
         for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
         {                                                                                              // extraction des données à la seconde 59
            moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
         }
     
       return moisNom[moisIndex];         // obliger de soustraire 6 car le 4em bit vaut 16
     }
     
      //----------------------------------------------------------------------------------
     
      int extraireAnnee()
     {
        int annee = 0;
     
          for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
         {
           annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
         }
     
        return annee;
     
     }
      //----------------------------------------------------------------------------------
     
      void affichage_I2c()
     {
     
      if(compteurSeconde == 59)
      {
        nouvelleMin = extraireMinute();
        nouvelleHeure = extraireHeure();
        nouveauJourSemaineNom = extraireJourSemaineNom();  //Récupération  des données à la seconde 59
        nouveauJour = extraireJour();
        nouveauMois = extraireMoisNom(); 
        nouvelleAnnee = extraireAnnee();
        testNouvelleAnnee = nouvelleAnnee /10 % 10;   // permet d'avoir toujours  le "2"des dizaines d'années , fonctionne jusqu' à l'année 2030
        top4 = true;                                    // autorise l 'affichage des données une seule fois par minute pour éviter des multitudes d'affichages qui ne servent à rien et qui creer des pb de timing si l'affichage n'est pas 
      }                                                                       // terminé avant l'interruption pour le top synchro.
     
      if (top2)
      { 
     
        lcd.setCursor(14,1);
        lcd.print( compteurSeconde);  //affichage des secondes
        lcd.setCursor(16,1);
        lcd.print("sec");
     
          if( testNouvelleAnnee != 2) // si different de 2 , "affichage attente données"
          {
           lcd.setCursor(0,0);
           lcd.print("attente donnees");
          }
     
        top2 = false; 
      }                                        
     
     
      if (compteurSeconde == 0 && (testNouvelleAnnee == 2) &&( top4 == true)) //si 2, alors affichage les données une seule autorisation d'écriture est donné pa la fonction
      {                                                                       
     
           lcd.setCursor(7,1);                                                //void affichagei2c, si non on est sans arret dans l'ecriture des données sur l'afficheur et quand arrive l'interruption
           lcd.print(nouvelleMin);                                             // à la seconde 0 pour le top synchro, l'interruption laisse finir le travail. du coup, se sera la prochaine 
           lcd.setCursor(9,1);                                                // interruption qui sera prise en compte et toute les mesures sont décalées et l'affichage est incorrect.
           lcd.print("min");
     
           lcd.setCursor(0,1);                                  //affiche les données si les dizaines et unités de l'année sont 20 21 ou 22
           lcd.print(nouvelleHeure);
           lcd.setCursor(2,1);
           lcd.print("hr");
     
           lcd.setCursor(0,0);
           lcd.print(nouveauJourSemaineNom);
     
           lcd.setCursor(4,0);
           lcd.print(nouveauJour); 
     
           lcd.setCursor(7,0);
           lcd.print(nouveauMois);
     
           lcd.setCursor(12,0);
           lcd.print("20");
           lcd.setCursor(14,0);
           lcd.print(nouvelleAnnee);
     
           lcd.setCursor(0,2);
           lcd.print("--------------------");
     
           top4 = false;
       }
     
      }
     
     
    void niveauSignal()
     {
      if(top5)
      {
       valeur = analogRead(A7);
       tension = valeur * (5.0 / 1023.0);
       lcd.setCursor(0,3);
       lcd.print("Niv.Signal");
       lcd.setCursor(12,3);
       lcd.print(tension);
     
       top5 = false;
      }
     }
    Nom : Decodeur Horaire.jpg
Affichages : 128
Taille : 84,9 KoNom : intérieur coffret.jpg
Affichages : 125
Taille : 127,4 Ko

  18. #78
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Bonjour

    Magnifique !!

    La solution que vous avez retenue est maline même si non optimale en utilisation mémoire.

    C’est bizarre qu’avec 12 mois ils aient besoin de 5 bits. Avec 4 bits on a déjà 16 possibilités et le mois 10 pourrait être codé en 8+2... vive le BCD (comme dans le protocole DCF77), seul le dernier bit ne doit pas être mis à une puissance de 2 (effectué par le << mn dans le code) mais x10. On peut le faire "à la main".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     const char* extraireMoisNom()
    {
      byte moisIndex = 0;
    
      // calcul des unités 
      for (byte mn = 0; mn < bitDonneesMoisNbr-1; mn ++)  {
        moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
      }
      // calcul des dizaines 
      moisIndex += infoDonnees[bitDonneesMoisStart + bitDonneesMoisNbr-1] * 10; // x10 au lieu de x16
    
      return moisNom[moisIndex];
    }

  19. #79
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Pat

    Je plussoie Jay M, superbe travail!

    Citation Envoyé par Pat42 Voir le message
    Et voici le pb… Quand le mois d’octobre est arrivé (c'est-à-dire le bit de la seconde 49 qui à pour coefficient 10 ) le mois ne s’affichait plus ...
    Je pensais que je t'avais déjà passé une version corrigée de ce problème, sans doute un oubli de ma part .
    Comme toutes les données lues dans infoDonnees[] sont des données codées BCD, je t'ai fait une fonction (int donneesExtraire(int bitStart, int bitNombre)) qui extrait et converti les données lues. L'essentiel des modifications se trouvent dans void affichage_I2c(). Tu verras ça simplifie ton programme. J'ai laissé tes lignes devenues inutiles en remarques et les lignes transformées sont précédées d'un //*

    Citation Envoyé par Pat42 Voir le message
    Tout ce laïus pour savoir s’il n’ y a pas une façon plus élégante
    Je te donne ma vision de "l'élégance"!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
     #include <Wire.h>
     #include <LiquidCrystal_I2C.h>
     
     //----- Adressage matériel -----
     LiquidCrystal_I2C lcd(0x27, 20, 4);
     //LiquidCrystal_I2C lcd(0x3F,20,4);
     //------------------------------
     #define interruptPin 2
     #define led_bit 12
     #define ledSeconde 13
     
     #define bitDonneesMinutesStart 21
     #define bitDonneesMinutesNbr 7
     //byte bitDonneesMinutesCoeff[] = {1, 2, 4, 8, 10, 20, 40};
     
     #define bitDonneesHeuresStart 29
     #define bitDonneesHeuresNbr 6
     //byte bitDonneesHeuresCoeff[] = {1, 2, 4, 8, 10, 20};
     
     #define bitDonneesJourSemaineStart 42
     #define bitDonneesJourSemaineNbr 3
     const char* jourSemaineNom[] = {"--", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
     
     #define bitDonneesJourStart 36
     #define bitDonneesJourNbr 6
     //byte bitDonneesJourCoeff[] = {1, 2, 4, 8, 10, 20};
     
     #define bitDonneesMoisStart 45
     #define bitDonneesMoisNbr 5
     const char* moisNom[] = {"--", "Jan", "Fev", "Mars", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", "Oct", "Nov", "Dec"};
     
     #define bitDonneesAnneesStart 50
     #define bitDonneesAnneesNbr 6
     //byte bitDonneesAnneesCoeff[] = {1, 2, 4, 8, 10, 20};
     
     #define nombreDeSeconde 59
     byte infoDonnees[ nombreDeSeconde];
     byte donneeBit = 0;
     
     volatile boolean mesureEnCours = false;
     volatile boolean mesureNouvelle = false;
     
     volatile boolean mesureNouvelleSeconde = false;
     volatile unsigned long tempoDepart = millis();
     volatile unsigned long topSyncMilliSec = millis();
     volatile unsigned long departMesure = millis();
     const unsigned int topSyncMinimum = 800;
     
     int unsigned  compteurSeconde = 0;                       //compteur des secondes
     
     int nouvelleMin;
     int nouvelleHeure;
     String nouveauJourSemaineNom;
     int nouveauJour;
     String nouveauMois;
     int nouvelleAnnee;
     int testNouvelleAnnee;
     
     boolean top = false;
     boolean top1 = false;
     boolean top2 = false;
     boolean top3 = true;  //pour indiquer "attente donnée"
     boolean top4 = true;
     boolean top5 = false;
     int minute = 0;
     
     float tension = 0;
     int valeur =0;
     
     void setup()
     {
    	 lcd.backlight();
     
    	 for (byte s = 0; s <= nombreDeSeconde ; s++)   // Initialisation des bits de données
    	 {                                             // A faire avant chaque cycle de minute
    		 infoDonnees[s] = 0;
    	 }
     
    	 lcd.init(); // initialisation de l'afficheur
     
    	 Serial.begin (115200);
    	 pinMode(interruptPin, INPUT_PULLUP);    // entrée interruption avec pull up
    	 pinMode(ledSeconde, OUTPUT);            //
    	 digitalWrite(ledSeconde, LOW);
    	 pinMode(led_bit, OUTPUT);               //led_bit en sortie et low
    	 digitalWrite(led_bit, LOW);
    	 attachInterrupt(digitalPinToInterrupt(interruptPin), impulsion_Interruption, CHANGE); //interruption pour rechercher
     
     
    	 lcd.setCursor(0,0);
    	 lcd.print("attente synchro");
     }
     
     //-----------------------------------------------------------------------
     void loop()
     {
    	 if (mesureNouvelle == true)
    	 {                                                                    // appel de la fonction "topSyncAction" si le top synchro est détecté
    		 mesureNouvelle = false;
    		 topSyncAction();
    	 }
     
    	 topSeconde();
    	 ecriture_Bit_Importante();                                            //appelle des fonctions
    	 affichage_I2c();
     
    	 niveauSignal();
     }
     
     //------------------------------------------------------------------------
     void impulsion_Interruption()
     {
    	 if (digitalRead(interruptPin) == LOW && !mesureEnCours)
    	 {
    		 tempoDepart = millis();                                                           // machine à état pour récupérer le top synchro (début de la 1° seconde)
    		 mesureEnCours = true;
    	 }
     
    	 if (digitalRead(interruptPin) == HIGH && mesureEnCours)
    	 {
    		 topSyncMilliSec = millis() - tempoDepart;
    		 mesureEnCours = false;
    		 mesureNouvelle = true;
     
    	 }
     
     }
     
     //-------------------------------------------------------------------------
     void topSyncAction()
     {
     
    	 if (topSyncMilliSec >= topSyncMinimum )
    	 {
    		 digitalWrite (ledSeconde, HIGH);
    		 compteurSeconde = 0;
    		 departMesure = millis();
    		 //Serial.println (millis());
    		 //Serial.print (compteurSeconde);
    		 //Serial.println ("Syncro_seconde----->0");                                           // top debut de la 1° seconde (synchro)
    		 delay (5);
    		 //Serial.println (millis());
    		 digitalWrite (ledSeconde, LOW);
    		 top1 = true;                            // permet de rentrer dans la fonction topSeconde qu'au top synchro, a un reset ou la mise en marche du pgr.
    		 top2 = true ;                          // permet d'attendre le top synchro, l'affichage des secondes demarre avec la seconde 0
    		 lcd.clear();                          //efface les donneeés sur l'ecran   au top synchro
     
    	 }
    	 top5 = true;                          //on indique le niveau du signal à chaque interruption
     }
     
     //-------------------------------------------------------------------------
     
     void topSeconde()
     {
    	 if(millis()- departMesure >= 950 && digitalRead (interruptPin)== HIGH &&( compteurSeconde < 59) && top1 ) //<59 empeche le compteur d'indiquer 60 par un nouveau passage dans cette routine
    	 {                                                                                                                // avant le top Synchro ainsi que le top1 qui permet de renter dans le
    		 digitalWrite (ledSeconde, HIGH);                                                                                // topSeconde uniquement au top syncrho
    		 compteurSeconde++;
    		 //Serial.println (compteurSeconde);
    		 departMesure = millis();
    		 delay (5);                                                                 //génère à partir des interrupts les tops seconde sauf la 59°s
    		 digitalWrite (ledSeconde, LOW);
    		 //Serial.println (millis());
    		 delay (105);
    		 //Serial.println (millis());
    		 lectureBit();
    	 }
     
     
    	 if(compteurSeconde == 58 && (millis() - departMesure >= 1000))
    	 {
    		 digitalWrite (ledSeconde, HIGH);
     
    		 compteurSeconde++;
    		 departMesure = millis();
    		 delay (5);                                                                   //génère  le top 59°s manquant dans la réception
    		 digitalWrite (ledSeconde, LOW);
    		 //Serial.println (compteurSeconde);
    		 lectureBit();
     
    	 }
     
     }
     //---------------------------------------------------------------------------
     
     void lectureBit()
     {
    	 if( digitalRead (interruptPin) == HIGH)
    	 {
    		 digitalWrite(ledSeconde, HIGH);
    		 delay (5);                                           //lit le bit 105 ms aprés le top seconde. Si le bit est à 1, il y a une donnée valide.
    		 digitalWrite (ledSeconde, LOW);
    		 donneeBit = 1;
    		 top = true;
    	 }
     
    	 else
    	 {
    		 donneeBit = 0;
    		 top = true;                                       // si pas de bit lue aprés 105 ms, le bit est égal à 0 .
    	 }
     
     }
     //---------------------------------------------------------------------------
     
     void ecriture_Bit_Importante()
     {
    	 if(top)
    	 {
    		 //Serial.print ("seconde----->");Serial.print (compteurSeconde );Serial.print("    ");   Serial.print("Donnée------>"); Serial.println(donneeBit);
    		 infoDonnees[compteurSeconde] = donneeBit;
    		 top = false;
    		 top2 = true;
    		 //top5 = true;
    	 }
     }
     
     
    /*------------------------------------------------------------------------------
    	Extraction de donnees dans le tableau infoDonnees
    	les donnees en BCD sont converties en decimal
    '*------------------------------------------------------------------------------
    */
    int donneesExtraire(int bitStart, int bitNombre)
    {
    	int extrait = 0;
     
    	for (int bitIndex = 0; bitIndex < bitNombre; bitIndex ++)
    	{
    		extrait += infoDonnees[(bitStart+0) + bitIndex] << bitIndex;
    	}
     
    	extrait = (extrait/16*10) + (extrait%16);                         // Transformer du BCD en decimal
    	return extrait;
    }
     
     ////------------------------------------------------------------------------------
     //
     //int extraireMinute()
     //{
    	 //int minute = 0;
    	 //
    	 //for (int mInd = 0; mInd < bitDonneesMinutesNbr; mInd ++)
    	 //{
    		 //minute += bitDonneesMinutesCoeff[mInd] * infoDonnees[bitDonneesMinutesStart + mInd];
    	 //}
    	 //
    	 //return minute;
     //}
     
     ////-------------------------------------------------------------------------------
     //
     //int extraireHeure()
     //{
    	 //int heure = 0;
    	 //
    	 //for (int mInd = 0; mInd < bitDonneesHeuresNbr; mInd ++)
    	 //{
    		 //heure += bitDonneesHeuresCoeff[mInd] * infoDonnees[bitDonneesHeuresStart + mInd];
    	 //}
    	 //
    	 //return heure;
     //}
     
     ////---------------------------------------------------------------------------------
     //
     //const char* extraireJourSemaineNom()
     //{
    	 //byte jourSemaineIndex = 0;
    	 //
    	 //for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    	 //{
    		 //jourSemaineIndex += infoDonnees[bitDonneesJourSemaineStart + jsn] << jsn;
    	 //}
    	 //
    	 //return jourSemaineNom[jourSemaineIndex];
     //}
     ////---------------------------------------------------------------------------------
     //
     //int extraireJour()
     //{
    	 //int jour = 0;
    	 //
    	 //for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
    	 //{
    		 //jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
    	 //}
    	 //
    	 //return jour;
     //}
     ////----------------------------------------------------------------------------------
     //
     //const char* extraireMoisNom()
     //{
    	 //byte moisIndex = 0;
    	 //
    	 //for (byte mn = 0; mn < bitDonneesMoisNbr; mn ++)
    	 //{                                                                                              // extraction des données à la seconde 59
    		 //moisIndex += infoDonnees[bitDonneesMoisStart + mn] << mn;
    	 //}
    	 //
    	 //return moisNom[moisIndex];         // obliger de soustraire 6 car le 4em bit vaut 16
     //}
     
     ////----------------------------------------------------------------------------------
     //
     //int extraireAnnee()
     //{
    	 //int annee = 0;
    	 //
    	 //for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
    	 //{
    		 //annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
    	 //}
    	 //
    	 //return annee;
    	 //
     //}
     //----------------------------------------------------------------------------------
     
     void affichage_I2c()
     {
     
    	 if(compteurSeconde == 59)
    	 {
    		 //*nouvelleMin = extraireMinute();
    		 //*nouvelleHeure = extraireHeure();
    		 //*nouveauJourSemaineNom = extraireJourSemaineNom();  //Récupération  des données à la seconde 59
    		 //*nouveauJour = extraireJour();
    		 //*nouveauMois = extraireMoisNom();
    		 //*nouvelleAnnee = extraireAnnee();
    		 //*testNouvelleAnnee = nouvelleAnnee /10 % 10;   // permet d'avoir toujours  le "2"des dizaines d'années , fonctionne jusqu' à l'année 2030
     
    		 nouvelleMin = donneesExtraire(bitDonneesMinutesStart, bitDonneesMinutesNbr);
    		 nouvelleHeure = donneesExtraire(bitDonneesHeuresStart, bitDonneesHeuresNbr);
    		 nouveauJour = donneesExtraire(bitDonneesJourStart, bitDonneesJourNbr);
    		 nouveauJourSemaineNom = jourSemaineNom[donneesExtraire(bitDonneesJourSemaineStart, bitDonneesJourSemaineNbr)];
    		 nouveauMois = moisNom[donneesExtraire(bitDonneesMoisStart, bitDonneesMoisNbr)];
    		 nouvelleAnnee = donneesExtraire(bitDonneesAnneesStart, bitDonneesAnneesNbr);
    		 testNouvelleAnnee = nouvelleAnnee /10 % 10;   // permet d'avoir toujours  le "2"des dizaines d'années , fonctionne jusqu' à l'année 2030
    		 top4 = true;                                    // autorise l 'affichage des données une seule fois par minute pour éviter des multitudes d'affichages qui ne servent à rien et qui creer des pb de timing si l'affichage n'est pas
    	 }                                                                       // terminé avant l'interruption pour le top synchro.
     
    	 if (top2)
    	 {
     
    		 lcd.setCursor(14,1);
    		 lcd.print( compteurSeconde);  //affichage des secondes
    		 lcd.setCursor(16,1);
    		 lcd.print("sec");
     
    		 if( testNouvelleAnnee != 2) // si different de 2 , "affichage attente données"
    		 {
    			 lcd.setCursor(0,0);
    			 lcd.print("attente donnees");
    		 }
     
    		 top2 = false;
    	 }
     
     
    	 if (compteurSeconde == 0 && (testNouvelleAnnee == 2) &&( top4 == true)) //si 2, alors affichage les données une seule autorisation d'écriture est donné pa la fonction
    	 {
     
    		 lcd.setCursor(7,1);                                                //void affichagei2c, si non on est sans arret dans l'ecriture des données sur l'afficheur et quand arrive l'interruption
    		 lcd.print(nouvelleMin);                                             // à la seconde 0 pour le top synchro, l'interruption laisse finir le travail. du coup, se sera la prochaine
    		 lcd.setCursor(9,1);                                                // interruption qui sera prise en compte et toute les mesures sont décalées et l'affichage est incorrect.
    		 lcd.print("min");
     
    		 lcd.setCursor(0,1);                                  //affiche les données si les dizaines et unités de l'année sont 20 21 ou 22
    		 lcd.print(nouvelleHeure);
    		 lcd.setCursor(2,1);
    		 lcd.print("hr");
     
    		 lcd.setCursor(0,0);
    		 lcd.print(nouveauJourSemaineNom);
     
    		 lcd.setCursor(4,0);
    		 lcd.print(nouveauJour);
     
    		 lcd.setCursor(7,0);
    		 lcd.print(nouveauMois);
     
    		 lcd.setCursor(12,0);
    		 lcd.print("20");
    		 lcd.setCursor(14,0);
    		 lcd.print(nouvelleAnnee);
     
    		 lcd.setCursor(0,2);
    		 lcd.print("--------------------");
     
    		 top4 = false;
    	 }
     
     }
     
     
     void niveauSignal()
     {
    	 if(top5)
    	 {
    		 valeur = analogRead(A7);
    		 tension = valeur * (5.0 / 1023.0);
    		 lcd.setCursor(0,3);
    		 lcd.print("Niv.Signal");
    		 lcd.setCursor(12,3);
    		 lcd.print(tension);
     
    		 top5 = false;
    	 }
     }
    ça n'est pas testé à 200%, je n'ai plus de montage pour ce faire, mais ça doit fonctionner.

    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  20. #80
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2019
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2019
    Messages : 64
    Points : 23
    Points
    23
    Par défaut
    Bonjour, en premier lieux, je tiens à vous souhaiter une belle et heureuse année 2021...

    J'ai d'abord testé la solution de J May et bien sur, cela fonctionne à merveille. J'ai donc pu supprimer les espaces "spéciaux" qui ne contenaient pas de nom de mois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* moisNom[] = {"--", "Jan", "Fev", "Mars", "Avr", "Mai", "Juin", "Juil", "Aout", "Sept", " ", " ", " ", " "," ", " ", "Oct", "Nov", "Dec"};
    Puis j'ai testé la solution de JP qui a fait "une pierre deux coups" en me simplifiant et optimisant le programme... même constat...c'est le top.

    Je n'ai malheureusement pas encore toutes les compétences en programmation pour comprendre vos modifs (je les comprends en surface, mais pas en détail)

    Auriez vous connaissance de littérature(d'un cours ou d'un bouquin) expliquant l' indexation en détail (telle que vous l'avez utilisé dans le prg ),pour en faire ma lecture à la lueur de ma lampe de chevet...(peut être suis je passé à coté. dans mes recherches).

    Vos compétences me seront sans doute encore d'un grand secours ... mon nouveau petit projet est d' intégrer une horloge en temps réel dans le montage, car, tous les mardis matin, l'émetteur de l 'ex-France Inter est en maintenance.

    Du coup, je n'ai plus l'heure exacte et ça me stress

    Cordialement

    Pat

Discussions similaires

  1. TOP 10 sur WeBI
    Par aemag dans le forum Webi
    Réponses: 9
    Dernier message: 21/05/2008, 20h41
  2. Detecter si l'on a toujours la synchro sur son modem
    Par yoghisan dans le forum API, COM et SDKs
    Réponses: 25
    Dernier message: 21/10/2005, 18h09
  3. Top 10 sur plusieurs items
    Par hussard dans le forum Langage SQL
    Réponses: 1
    Dernier message: 03/10/2005, 09h33
  4. Réponses: 3
    Dernier message: 23/08/2005, 09h43
  5. Détection d'un front sur la broche RI d'un port série
    Par G3G3 dans le forum Ordinateurs
    Réponses: 2
    Dernier message: 19/08/2005, 17h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo