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. #41
    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
    C'est plus clair pour cette instruction , je me penche sur le reste.
    Merci et Bonne soirée.

    Pat

  2. #42
    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 à tous et en particulier à Jp.

    l'exemple de code que tu m'as écrit m'a permis de bien avancer et j'ai pu afficher mes données sur l'afficheur (voir photo).
    J' ai utilisé ton code en tatonnant car si j'ai bien compris le principe, je n'en ai pas compris toute la subtilité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    minute += bitDonneesMinutesCoeff[mInd] * bitDonnees[bitDonneesMinutesStart + mInd];
    Pourrais tu me l'expliquer ...

    Un autre "petit soucis" sur lequel je bute est le suivant:

    Il est indiqué sur l'afficheur le chiffre 7, ce chiffre correspond à Dimanche.

    En fait sur le même principe que les minutes les bits des secondes 47, 48 ,49 peuvent être à 1 ou 0.

    47 à 1= 1, 48 à 1= 2, 49 à 1= 4.

    si le bit des secondes 47 48 49 sont à 1 , on a la somme qui fait 7

    1 correspond à lundi
    2 correspond à mardi
    3 correspond à mercredi
    .....
    7 correspond à dimanche

    Je n'ai pas trouvé la réponse à ma question.
    Comment faire pour que je puisse transcrire le chiffre sept en une chaîne de caractère que je pourrais envoyer sur mon afficheur (ici, dimanche).

    c'est idem pour les mois.

    Une question sur l'utilisation du site; il y a 10 Mo pour mettre des photos, je suis pratiquement arrivé au bout et j'aimerais savoir comment éliminer des photos ou remplacer des photos par des moins gourmandes pour gagner de la place. J'ai fait une demande directement, mais je n'ai pas eu de réponse...

    voici mon bout de programme ( il est sans doute très loin de ce qu'un bon programmeur pourrait faire, mais j'essaierai de l'améliorer...plus tard... quand j'aurai progressé )

    Cordialement
    pat



    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
    #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
    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
    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();
      extraireJourSemaine();
      extraireJour();
      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 >=999550)       // ici le temps la 59° ne doit pas etre 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;
     
        }
      }
    }
    //--------------------------------------------------------------------------
     
    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 
          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];
      }
                                          Serial.println ("Test");
      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;
      }
    }
    //------------------------------------------------------------------------------------------
    int extraireJourSemaine()
    {
      if (compteurSeconde == 59)
      {
      int jourSemaine = 0;
     
      for (int mInd = 0; mInd < bitDonneesJourSemaineNbr; mInd ++)
      {
        jourSemaine += bitDonneesJourSemaineCoeff[mInd] * infoDonnees[bitDonneesJourSemaine + mInd];
      }
                                          //Serial.println ("Test");
      return jourSemaine;
      }
    }
      //------------------------------------------------------------------------------------------
    int extraireJour()
    {
      if (compteurSeconde == 59)
      {
      int jour = 0;
     
      for (int mInd = 0; mInd < bitDonneesJourNbr; mInd ++)
      {
        jour += bitDonneesJourCoeff[mInd] * infoDonnees[bitDonneesJourStart + mInd];
      }
                                          //Serial.println ("Test");
      return jour;
      }
    }
     
    //------------------------------------------------------------------------------
    int extraireMois()
    {
      if (compteurSeconde == 59)
      {
      int mois = 0;
     
      for (int mInd = 0; mInd < bitDonneesMoisNbr; mInd ++)
      {
        mois += bitDonneesMoisCoeff[mInd] * infoDonnees[bitDonneesMoisStart + mInd];
      }
                                          //Serial.println ("Test");
      return mois;
      }
    }
    //--------------------------------------------------------------------------------
    int extraireAnnee()
    {
      if (compteurSeconde == 59)
      {
      int annee = 0;
     
      for (int mInd = 0; mInd < bitDonneesAnneesNbr; mInd ++)
      {
        annee += bitDonneesAnneesCoeff[mInd] * infoDonnees[bitDonneesAnneesStart + mInd];
      }
                                          //Serial.println ("Test");
      return annee;
      }
    }
    //-------------------------------------------------------------------------------
    void affichage_I2c()
    {
     
     
       if( top3 == true) 
       {                                               //autorisation donnée par la fonction void ecriture_Bit_Importante()
          int nouvelleMin = extraireMinute();
          int nouvelleHeure = extraireHeure(); 
          int nouveauJourSemaine = extraireJourSemaine();                                            //Serial.println(nouvelleMin); 
          int nouveauJour = extraireJour();
          int nouveauMois = extraireMois();
          int nouvelleAnnee = extraireAnnee();
     
          lcd.backlight();
     
          if (compteurSeconde == 0)
          {
           lcd.setCursor(0,1);
           lcd.print(nouvelleHeure);
           lcd.setCursor(2,1);
           lcd.print("hrs");
     
     
           lcd.setCursor(7,1);
           lcd.print(nouvelleMin);           
           lcd.setCursor(9,1);
           lcd.print("min");
     
     
           lcd.setCursor(0,0);
           lcd.print(nouveauJourSemaine);
     
           lcd.setCursor(7,0);
           lcd.print(nouveauJour);  
     
           lcd.setCursor(9,0);
           lcd.print("/");
     
           lcd.setCursor(10,0);
           lcd.print(nouveauMois); 
     
           lcd.setCursor(11,0);
           lcd.print("/");
     
           lcd.setCursor(12,0);
           lcd.print("20");
           lcd.setCursor(14,0);
           lcd.print(nouvelleAnnee);           
           }
     
        lcd.setCursor(13,1);
        lcd.print( compteurSeconde); 
        lcd.setCursor(15,1);
        lcd.print("s");
     
        top3 = false;
    Nom : Afficheur1.JPG
Affichages : 215
Taille : 49,1 Ko

  3. #43
    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
    Ça avance Super!

    Le problème est de réunir ces 3 bits (bitDonneesJourSemaineNbr) en une valeur, en fonction de leur état (1 ou 0) et, aussi, en fonction de leur "poids" (1, 2, 4, ...), du fait de leur index. C'est réalisé avec les opérateurs de décalage << ou >>.
    Et ça donne ceci:
    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
    byte bitDonnees[60];                 // Déclaration du tableau
     
     
    #define bitDonneesJourSemaine 42
    #define bitDonneesJourSemaineNbr 3
    //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};     // Plus utile
    char* jourSemaineNom[] = {"-", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"};
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(500);
     
    	bitDonnees[bitDonneesJourSemaine] = 1;                         
    	bitDonnees[bitDonneesJourSemaine +1] = 1;
    	bitDonnees[bitDonneesJourSemaine +2] = 0;
     
    	String jourSemaine = extraireJourSemaineNom();
    	Serial.println(jourSemaine);
    }
     
    void loop()
    {
     
     
    }
    //------------------------------------- Extraction des minutes du tableau bitDonnees
    String extraireJourSemaineNom()
    {
    	byte jourSemaineIndex = 0;
     
    	// Version detaillée
    	//jourSemaineIndex += bitDonnees[bitDonneesJourSemaine];           // 2^0  (*1)
    	//jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + 1] << 1;  // 2^1  (*2)
    	//jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + 2] << 2;  // 2^1  (*4)
     
    	// Version courte
    	for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    	{
    		jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + jsn] << jsn;
    	}
     
    	return jourSemaineNom[jourSemaineIndex];
    }
    Dans le tableau jourSemaineNom[], j'ai laissé l'indice [0] à "-", comme ceci, si le tableau bitDonnees est vide, cela évite que extraireJourSemaineNom() donne lundi, ainsi, si le tableau est vide, cela donnera -.

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

  4. #44
    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
    Pourquoi ne pas construire les valeurs au fur et à mesure de la réception au lieu de tout stocker dans un tableau et faire le traitement plus tard ?

    au lieu d'utiliser un index pour écrire le bit au bon endroit dans le tableau, testez la valeur de cet index et faites l'opération mathématique qui va bien

    par exemple au moment où index == 0 --> on met toutes les variables à calculer à 0 - par exempleQuand index vaut 47, on sait qu'on reçoit un élément sur le jour de semaine et que c'est le bit de poids faible. on fait doncQuand index vaut 48, on sait qu'on reçoit un élément sur le jour de semaine et que c'est le second bit. on fait donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     jourSemaine += bitRecu<<1; // idem que 2* bitRecu
    Quand index vaut 49, on sait qu'on reçoit un élément sur le jour de semaine et que c'est le dernier bit. on fait donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     jourSemaine += bitRecu<<2; // idem que 4* bitRecu
    idem pour les autres indices. ça se code dans un grand switch ou des if imbriqués.


    Vous gagnez ainsi la place du tableau et les maths sont faits au fur et à mesure, vous pouvez même mettre l'affichage à jour pour le jour de la semaine dès l'index 49 reçu par exemple si vous voulez.

  5. #45
    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 Jay M
    Citation Envoyé par Jay M Voir le message
    ...ça se code dans un grand switch ou des if imbriqués....
    Donc un switch de 60 éléments ou 60 if !!!, je ne vois pas du tout l'avantage de cette méthode et surtout à écrire et entretenir...

    Citation Envoyé par Jay M Voir le message
    Vous gagnez ainsi la place du tableau et les maths sont faits au fur et à mesure...
    Est-ce vraiment nécessaire d'économiser ce tableau?


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

  6. #46
    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 jpbbricole Voir le message
    Donc un switch de 60 éléments ou 60 if !!!
    Salut JP

    J'avais cru comprendre qu'il n'y avait que quelques plages pertinentes et comme GCC supporte des switch/case avec un 'range' et que les maths sont relativement simple, ça ne serait pas si lourd que cela.

    Pour l'exemple ci dessous ça ressemblerait à cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      switch (indexSeconde) {
        case 0: jourSemaine = 0; break;
     
        case 47 ... 49: // réception du jour semaine
          jourSemaine += bitRecu << (indexSeconde - 47);
          break;
     
        default: break; // on ignore
      }
    ça ne me choque donc pas au niveau complexité et la lecture reste aisée, on ne fait qu'intégrer au fil de l'eau les maths que vous avez décrits.

    Est-ce vraiment nécessaire d'économiser ce tableau?
    Je ne sais pas

    Si le programme ne fait rien d'autre ce n'est pas une nécessité si le reste tient en mémoire.

    Souvent on veut juste une fonction de mise à jour régulière de l'heure pour synchro et le reste du programme fait autre chose de plus ou moins compliqué. Dans ce cadre, éviter d'affecter de la mémoire à cette tâche pour en conserver pour le coeur du programme peut-être utile.

    ça ne reste qu'une suggestion bien entendu.

  7. #47
    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 hoaraire 162kh
    Bonjour,

    Eh bien voici le résultat, j'ai mis en oeuvre ton dernier exemple de programme pour l'affichage des jours de la semaine et des mois...et ça fonctionne.

    j'ai appris pas mal de choses:

    Les machines à état
    les tableaux array
    les tableaux d'indices
    utiliser un afficheur I2c etc...


    Pourrais tu m'expliquer en détail ce bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    	{
    		jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + jsn] << jsn;   
    	}

    Concernant ta discussion avec Jay M sur la bonne façon d'écrire et de lire les données , je n'ai pas tout compris, du coup je vais relire attentivement vos post.


    il y en a sans doute qui vont s'arracher les cheveux en lisant le programme, mais bon! au mieux s'il bug, j'ai encore ma montre

    Maintenant je vais continuer à travailler sur ce programme pour:

    1) comprendre certain morceaux de code que j'ai placé et utilisé sans vraiment en comprendre tous les rouages.
    2) rendre ce prg plus lisible et l'optimiser si cela est possible.
    3) rajouter un 0 quand on a qu' un chiffre pour la date ex: Ven 5 ----> Ven 05.
    4) remplacer l'afficheur par un couleur plus important pour rajouter des données.

    j'aurais sans doute besoin, et comme d'habitude d'un petit coup de main...

    Cordialement
    Pat

    Nom : Afficheur I2C 1.jpg
Affichages : 216
Taille : 123,0 Ko


    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
    #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
    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
    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();
      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 >=999550)       // ici le temps la 59° ne doit pas etre 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];
      }
                                          Serial.println ("Test");
      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;
      }
    }
    //------------------------------------------------------------------------------------------
     
     String 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];
      }
                                          //Serial.println ("Test");
      return jour;
      }
    }
     
    //------------------------------------------------------------------------------
    String extraireMoisNom()
    {
      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];
      }
                                          //Serial.println ("Test");
      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)
          {
           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);           
           }
     
        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
      }
    }

  8. #48
    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 Pat42 Voir le message
    Eh bien voici le résultat, j'ai mis en oeuvre ton dernier exemple de programme pour l'affichage des jours de la semaine et des mois...et ça fonctionne
    C'est super!!

    Citation Envoyé par Pat42 Voir le message
    Pourrais tu m'expliquer en détail ce bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    	{
    		jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + jsn] << jsn;   
    	}
    Je vais essayer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    {
    	jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + jsn] << jsn;   
    }
    //en "français" ça donne:
    for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    {
    	jourSemaineIndex += bitDonnees[bitDonneesJourSemaine + jsn] x 2^jsn;   
    }
    Si les bits 47, 48, 49 (jsn 0, 1, 2) valent 101, on aditionne:
    jsn = 0 bit = 1 x 2^0 = 1 (<<0)
    jsn = 1 bit = 0 x 2^1 = 0 (<<1)
    jsn = 2 bit = 1 x 2^2 = 4 (<<2)
    total 5 donc Vendredi

    Citation Envoyé par Pat42 Voir le message
    il y en a sans doute qui vont s'arracher les cheveux en lisant le programme, mais bon! au mieux s'il bug, j'ai encore ma montre
    Dès que j'ai du temps, je vais regarder ton programme, je suis entrain de réécrire le générateur qui m'a permis de t'aider.
    Citation Envoyé par Pat42 Voir le message
    Concernant ta discussion avec Jay M sur la bonne façon d'écrire et de lire les données , je n'ai pas tout compris, du coup je vais relire attentivement vos post.
    C'est juste 2 façons de voire les choses, Jay M est une "bête" en C (entre autre), moi je n'avais jamais fait de C avant de découvrir le monde de l'Arduino, le "concept" Arduino a été fait pour rendre le C d'une approche plus "populaire", accessible à plus grand nombre, plus simple sans être simpliste. Donc, je "je fais de l'Arduino" et Jay M du C.

    Encore Bravo pour le résultat!

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

  9. #49
    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 jpbbricole Voir le message
    C'est juste 2 façons de voire les choses, Jay M est une "bête" en C (entre autre), moi je n'avais jamais fait de C avant de découvrir le monde de l'Arduino, le "concept" Arduino a été fait pour rendre le C d'une approche plus "populaire", accessible à plus grand nombre, plus simple sans être simpliste. Donc, je "je fais de l'Arduino" et Jay M du C.
    J'ai peut-être un peu plus d'experience en C et C++ mais vous faites aussi de C, @JP !!

    Ce que j'ai proposé c'est une approche fonctionnelle différente de ce que vous aviez commencé:

    Vous avez 59 petits bouts de données qui arrivent "au fil de l'eau" et qu'il faut rassembler pour obtenir l'information souhaitée.

    --> Une première approche, qui est celle que vous avez prise et que JP a rendu fonctionnelle, est de collecter dans un tableau ces données et quand on les a toutes, effectuer un traitement qui fabrique l'information.

    --> Une autre approche, qui est celle que je proposais, est de construire l'information au fur et à mesure que les petits bouts de données arrivent.

    Donc pour prendre une métaphore, mon approche fonctionne un peu comme si vous lisiez un texte qui s'affiche petit à petit, caractère par caractère, sur l'écran. Votre cerveau fonctionne en permanence et n'attend pas d'avoir reçu la phrase complète pour la lire et former sa compréhension. A chaque fois que assez de caractères sont arrivés pour faire un mot vous le déchiffrez et avancez dans la fabrication de la compréhension de la phrase (information). Votre approche consiste à ne pas se soucier des lettres reçues pour former des mots tant que vous n'avez pas reçu la phrase complète.

    Les deux approches sont correctes, elles délivrent au final l'information souhaitée.

    La raison pour laquelle je proposais mon approche comme alternative c'est qu'elle est plus frugale: il n'y a pas le "gros tableau" de 59 octets à conserver pour mémoriser en SRAM les 59 bits reçus et le processeur ne reste pas à ne rien faire pendant 59 secondes en se tournant les pouces pour ensuite passer "plein de temps" (à l'échelle du microprocesseur) pour faire un "gros calcul" pour fabriquer l'information.

    D'un point de vue lecture du code (@JP le mentionnait) la construction du tableau et son traitement ultérieur sont conceptuellement plus simples à comprendre, expliquer et visualiser. ça simplifie la maintenance du code.

    Dans mon approche on profite du temps mort entre 2 bouts de données pour commencer à fabriquer l'information. Cette approche économise donc des resources qui sont limitées (temps CPU, mémoire) qui pourraient être critiques sur un petit processeur comme Arduino.

    Mais ça ne fait du sens de les économiser que si on en a besoin pour autre chose (et c'est ce que demandait fort justement @JP). Si votre programme ne fait "que" maintenir l'heure à jour sur un LCD, alors ça n'est pas un souci que d'allouer de la mémoire, elle est disponible autant l'utiliser. D'un autre côté, si un jour vous souhaitez intégrer ce même bout de code dans une application plus gourmande en mémoire, où ces ressources limitées vous feront défaut, vous serez content d'avoir optimisé l'usage des resources.

    Voilà, donc il y a des plus et des moins dans les deux approches, comme souvent en informatique il n'y a pas qu'une seule bonne solution.

  10. #50
    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 hoaraire 162kh
    Bonsoir, et merci d'avoir pris du temps pour m'expliquer les deux approches pour construire l'information, et le morceaux de code que j'ai du mal a décrypter.

    En fait, j'avais pensé à la 1° solution qui est celle de construire l'information au fur et à mesure du décodage des infos...
    Mais je m'étais dit que cela prendrait un certain temps qui influerait sur la routine "seconde", de plus, les nouvelles informations doivent être visualisées sur l'afficheur au top synchro, d'ou il me paraissait plus judicieux de faire les calculs dans le temps imparti à la 59° seconde qui de plus ne supporte aucune information à traiter ( je pense que c'est la raison pour laquelle en plus de générer le top synchro, que celle-ci est sans info).

    j'ai un autre pb auquel je n'est pas trouvé la solution ( j'ai l'impression que plus j'apprends,moins j'en sais )

    J'aimerai rajouter sur mon afficheur tant que l'info n'est pas décodée une phrase du genre " lecture donnée".
    Et pour cela j'utilise un if else dans lequel je pourrais lire la dite information et une logique "and" du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void affichage_I2c()
    {
     
     
        lcd.backlight();
     
          if (compteurSeconde == 0 && nouvelleAnnee == 2020 ) // je rajouterai 2021 2022 ... plus tard
          {
           lcd.setCursor(0,1);
           lcd.print(nouvelleHeure);
           lcd.setCursor(2,1);
           lcd.print("hr");
    Info:Tant que l'information n'est pas décodée , l'année affichée ne correspond à rien , mais dès que l'information est décodée, 2020 s'inscrit sur l'afficheur.

    Du coup il me faudrait utiliser l'égalité "nouvelleAnnee == 2020" pour renter dans le if que si la condition est vrai. et aller dans le else si la contition est fausse.
    Je pensais que "nouvelleAnnee" contiendrait la valeur "2020" (une fois que l'information est décodée) puisque je la lie sur l'afficheur, mais cela ne fonctionne pas (je ne rentre jamais dans le if).

    j'aurais besoin d'une explication ... que contient "nouvelleAnnee" et comment l'écrire pour que je puisse avoir cette égalité.
    J'espère que ce n'est pas trop confus car je ne maîtrise pas encore le langage du programmeur qui permet de faire des raccourcis tout en étant précis...

    J'ai constaté en testant une fonction string une chose bizarre...que je ne m'explique pas (une de plus) ... c'est pour plus tard...

    Cordialement

    Pat

  11. #51
    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
    J'aimerai rajouter sur mon afficheur tant que l'info n'est pas décodée une phrase du genre " lecture donnée".
    Et pour cela j'utilise un if else dans lequel je pourrais lire la dite information et une logique "and" du genre
    vous voulez dire pendant la première minute ?

  12. #52
    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
    Oui c'est cela,

    au mieux avec beaucoup de chance 1 mn et une seconde
    Au pire 1 mn et 59 secondes

    Il faut un top synchro puis une lecture complète des données

    Donc deux minutes à partir du moment ou le système est fonctionnel.

    Je voulais faire une tempo de deux minutes et quelques secondes avant de passer à l'affichage des données mais je trouve plus sympa et plus didactique d'afficher les données par comparaison comme je l'ai écrit dans mon poste précédent.


    Bonne soiréee

    Pat

  13. #53
    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 avez un état initial sans information, puis des mises à jour.

    Vous pourriez avoir des variables globales booléennes pour chaque champ qui sont au début à false par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool anneeEnAttente = true;
    bool anneeMiseAJour = false;
    int annee = -1; // on initialise avec une valeur improbable
    Quand vous avez reçu l'année, vous passez anneeEnAttente à false. Ensuite vous comparez l'année reçue avec celle en mémoire et si elles sont différentes alors vous mettez anneeMiseAJour à true, ce qui aura pour effet de mettre à jour le champs quand vous passez dans l'affichage.

    Par exemple
    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
     
    /* TRAITEMENT DES DONNEES */
     
    // LES ANNEES
    int nouvelleAnnee = extraireAnnee();
    anneeEnAttente = false; // ça y'est on a reçu au moins une première valeur
    anneeMiseAJour =  (annee != nouvelleAnnee); // vrai si la valeur reçue est différente de celle qui est affichée.
     
    /*   Affichage années */
    lcd.setCursor(12,0);
    if (anneeEnAttente) {
      lcd.print(F("20??"));
    } else {
      if (anneeMiseAJour) { // on ne fait l'affichage que quand c'est nécessaire
        annee = nouvelleAnnee; // on mémorise la nouvelle année
        lcd.print(F("20"));
        lcd.print(annee);
        anneeMiseAJour = false;
      }*
     
    // LES MOIS
    ....
     
    }
    Tout ces booléens ce n'est pas ce qui a de plus efficace pour la gestion mémoire mais ça fait le job

  14. #54
    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,

    Je me suis sans doute mal expliqué dans mon dernier post (il était tard)...ou je ne comprend pas , ce qui n'est pas impossible

    En fait, je voudrais comparer une valeur, ici 2020 (année courante) à la valeur qui a été décodée et contenue dans "nouvelleAnnee" (forcément 2020).
    Si l'égalité "nouvelleAnnéé == 2020" est vraie, alors on suit les instructions dans le if et toutes les données s'afficheront.

    Si l'égalité n'est pas vraie alors on sera dans le else et on affichera une phrase genre "données en attente".

    Comme cela une seule égalité suffira à faire que l'on affiche les données ou la petite phrase d'attente.

    Et le pb est, que je ne sais pas comment faire pour que l'égalité "nouvelleAnnee == 2020" fonctionne (je l'ai testé et et ça ne fonctionne pas).

    Voici en gros le code que j'aimerais écrire

    Cordialement

    pat

    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
    void affichage_I2c()
    {
     
     
       if( top3 == true) 
       {                                               
          int nouvelleMin = extraireMinute();
          int nouvelleHeure = extraireHeure(); 
          String nouveauJourSemaineNom = extraireJourSemaineNom();                                            
          int nouveauJour = extraireJour();
          String nouveauMois = extraireMoisNom();
          int nouvelleAnnee = extraireAnnee();
     
          lcd.backlight();
     
          if (compteurSeconde == 0 && nouvelleAnnee == 2020)   //on rentre dans le if et on affiche toutes les données
          {
           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);           
           }
      
        lcd.setCursor(13,1);
        lcd.print( compteurSeconde); 
        lcd.setCursor(15,1);
        lcd.print("s");
     
        top3 = false;  
                    
            else
    
           { 
             lcd.setcursor
             lcd print
    
                      " données en attente"                    //si l'égalité "nouvelleAnnée" == 2020 est inexacte alors on est dans le else et on affiche le message d'attente
    
           }
                                         
      }

  15. #55
    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

    Si j'ai bien compris, tu as, actuellement, affiché l'année 2020, tu reçoit un nouveau cycle de données qui contiennent l'année 2021, à ce moment tu aimerai indiquer que les données affichées, actuellement, ne concernent plus les données reçues?
    Si oui, avec mon "principe" de décodage, c'est à dire, tout d'un coups, pendant la seconde 59, on ne verra pas de changements que à cette 59ème seconde, donc il n'y aura pas de donnée "décalées" d'affichées.

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

  16. #56
    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
    Salut JP

    Ne devrirez vous pas extraire les données AVANT de faire l'affichage ? de plus vous ne mémorisez pas les valeurs lues ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (top3 == true && compteurSeconde == 59)
    	{
    		affichage_I2c();  
                    // EST-CE UTILE DE FAIRE CES APPELS??
     		extraireMinute();
    		extraireHeure();
    		extraireJourSemaineNom();
    		extraireJour();
    		extraireMoisNom();
    		extraireAnnee();
    		top3 = false;                          // on ne rentre qu'une fois par seconde dans cette fonction , sinon gros souci de timing car on vient la lire
    	}
    et ça fait redondance car affichage_I2c() demande aussi l'extraction
    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 == 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();
     ...

    Sinon en guide d'optimisation des performance, vous pouvez éviter de créer des string à chaque fois que vous retournez nouveauJourSemaineNom et simplement retourner un pointeur vers la bonne chaîne du tableau. Pour cela vous pouvez déclarer le tableau en constantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* jourSemaineNom[] = {"-", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
    et la fonction retournerait un const char* aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const char* extraireJourSemaineNom()
    {
    	byte jourSemaineIndex = 0;
     
    	for (byte jsn = 0; jsn < bitDonneesJourSemaineNbr; jsn ++)
    	{
    		jourSemaineIndex += infoDonnees[bitDonneesJourSemaine + jsn] << jsn;
    	}
     
    	return jourSemaineNom[jourSemaineIndex];
    }

  17. #57
    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 Jay M
    Citation Envoyé par Jay M Voir le message
    Ne devrirez vous pas extraire les données AVANT de faire l'affichage ? de plus vous ne mémorisez pas les valeurs lues ?
    Oupsss!!! J'ai pêché par excès de précipitation , je vais revoir ma copie et, surtout, essayer.

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

  18. #58
    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 avez déjà fait un gros boulot ! à mon avis faut juste virer ces appels puisqu'ils sont faits dans affichage_I2c() (qu'il suffit d'appeler quand le tableau des bits reçus est plein)

  19. #59
    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,

    En modifiant ma fonction "void affichage _I2c()" j'ai pu afficher mon petit message "attente donnees".
    En fait ,je n'arrivais pas à faire fonctionner la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (compteurSeconde == 0 && nouvelleAnnee == 20 || nouvelleAnnee == 21)
    parce que je m'évertuais à comparer" nouvelleAnnee" à 2020...


    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
    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) //on affiche au début de la 1° seconde à condition que les dizaines et unité de l'année courante soient décodées.
          {                                               
           //lcd.clear();                                 // A modifier si les jours et mois ont des tailles différentes   .                                        
           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
      }
     
    }

    Le système fonctionne à merveille même s'il n'est pas écrit d'une manière rigoureuse...
    A ce propos, j'ai supprimé les appels comme le préconisait J May, mais un appel résiste "extraireMoisNom"
    Si je le supprime le programme part en live...


    //extraireMinute();
    //extraireHeure();
    //extraireJourSemaineNom();
    //extraireJour();
    extraireMoisNom();
    //extraireAnnee();

    j'ai aussi remplacé les string comme le préconisait J May.


    Sinon en guide d'optimisation des performance, vous pouvez éviter de créer des string à chaque fois que vous retournez nouveauJourSemaineNom et simplement retourner un pointeur vers la bonne chaîne du tableau. Pour cela vous pouvez déclarer le tableau en constantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* jourSemaineNom[] = {"-", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"};   //byte bitDonneesJourSemaineCoeff[] = {1, 2, 4,};
    et la fonction retournerait un const char* aussi
    Ça fonctionne avec const char* jourSemaineNom[],
    Mais idem que plus haut, si j'applique cela sur la fonction "extraireMoisNom" le prg part en live.
    À part cela le prg fait son job.
    Maintenant, je vais faire quelques modifs sur la carte réception, changer l'afficheur, faire un circuit imprimé (si j'en ai le temps) et trouver une jolie boîte 😁
    Bonne journée.

    Pat
    Images attachées Images attachées  

  20. #60
    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 reposter tout le code?

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