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 :

Programmation de fonctions


Sujet :

Arduino

  1. #1
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut Programmation de fonctions
    Bonjour � tous,

    D�sireux, de rendre plus pratique et pr�sentable mon programme en cours , j'essaie de cr�er des onglets particuliers qui contiennent mes fonctions

    par exemple : un onglet "affichage.h" regroupant toutes mes fonctions utilis�es dans mon programme etc ...
    j'ajoute que mes fonctions que je place dans le corps de mon programme ( apr�s le LOOP ) se compilent sans erreur

    mais par contre plus rien ne fonctionne et je me heurte � de nombreuses erreurs de type "...was not declared in this scope"

    qu'elle en est la raison principale svp ?
    Images attach�es Images attach�es    

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 591
    D�tails du profil
    Informations personnelles :
    �ge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 591
    Par d�faut
    tes fichiers sont bien dans le m�me r�pertoire?
    ton fichier .h est bien enregistr�? (bon ici, on oublie, �a s'enregistre automatiquement normalement)

  3. #3
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    Salut umfred

    Oui, les fichiers sont bien dans le m�me r�pertoire

    mais au-d�l� de ��, c'est surtout le principe que je souhaiterai comprendre
    la fonction lorsqu'elle est sous "LOOP" fonctionne normalement
    mais lorsque je la d�place avec "#include affiche.h" l� �� ne marche plus (?)

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 591
    D�tails du profil
    Informations personnelles :
    �ge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 591
    Par d�faut
    Je ne saurais dire, je ne rencontre pas le soucis en copiant ton code.
    Quelle version d'arduino IDE ? (j'ai test� sous la v2.3.6)

  5. #5
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    m�me version Arduino


    En fait il ne s'agit que d'un exemple d'illustration , mon code est un peu plus volumineux mais je ne savais pas comment le mettre � disposition
    autrement que sous la forme d'un fichier zip
    puisqu'il comporte des sous-programmes .h

    En fait ma question serait plut�t orient�e pour savoir comment utiliser efficacement les fichiers .h et .cpp

  6. #6
    Responsable Arduino et Syst�mes Embarqu�s


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 268
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 268
    Billets dans le blog
    48
    Par d�faut
    Bonjour,

    Ce serait plut�t comme ci-dessous.

    sketch_oct15a.ino
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "affichage.h"
     
    void setup() {
      // put your setup code here, to run once:
      ma_fonction(10, 10);
    }
     
    void loop() {
      // put your main code here, to run repeatedly:
    }

    affichage.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    #ifndef AFFICHAGE_H
    #define AFFICHAGE_H
     
    void ma_fonction(int x, int y); // prototype de la fonction
     
    #endif
    affichage.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    void ma_fonction(int x, int y) {
      // code de la fonction ici
    }

  7. #7
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    merci f-leb

    c'est exact, j'ai fini par trouver une vid�o sur le net qui explique la manip
    mais que fait-on de fa�on globale pour les variables contenues dans la fonction "d�port�e" ?

    par exemple, j'utilise cette fonction l� que j'ai mise dans un sous-programme de type .cpp :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //#########################################################################################
    void afficherDate(int jour, int mois, int annee)
    {
      char texte[20];
      static String(affichdate);  // <===================
      sprintf(texte, "%02d/%02d/%04d", jour, mois, annee);
      afficherTexte(texte);
      affichdate = " Date : ";
      affichdate += texte;
    }
    pour �viter le plantage � la compilation , j'ai du red�clarer la variable dans la fonction avec le terme "static"
    pour quelle raison ? puisque je l'avais d�clar�e initialement dans le programme principale
    est-ce que je confonds encore (!) , d�finition et d�claration ?

  8. #8
    Responsable Arduino et Syst�mes Embarqu�s


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 268
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 268
    Billets dans le blog
    48
    Par d�faut
    par exemple avec une variable d�clar�e extern :

    sketch_oct15a.ino
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "affichage.h"
     
    void setup() {
      // put your setup code here, to run once:
      ma_fonction(10, 10);
    }
     
    void loop() {
      // put your main code here, to run repeatedly:
    }
    affichage.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    #ifndef AFFICHAGE_H
    #define AFFICHAGE_H
     
    #include <Arduino.h> // Nécessaire pour le type String
     
    void ma_fonction(int x, int y); // prototype de la fonction
    extern String ma_variable; // Déclaration externe
    #endif
    affichage.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <Arduino.h>
    #include "affichage.h"
     
    String ma_variable = "toto"; // Définition, attention de ne pas mettre ça dans le .h !
     
    void ma_fonction(int x, int y) {
      // code de la fonction ici
      ma_variable = ma_variable + "titi";
    }

  9. #9
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    pardon pour la question stupide
    mais sommes-nous oblig�s de r�p�ter 2 fois la m�me variable
    une fois en d�claration puis en d�finition

    un sous-programme "variable.h" par exemple regroupant l'ensemble des variables du prg
    m'�viterait de r��crire "extern" ...

    un autre exemple de sous-programme ici affichage.cpp qui plante :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "affichage.h"
    #include <Arduino.h>
     
    //#########################################################################################
    void DisplayAstronomySection(int x, int y) {
      display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK); 
      u8g2Fonts.setFont(u8g2_font_helvB08_tf);
      drawString(x+5,y+95, affichalarme, LEFT);
      display.display(false); // Full screen update mode
    }
    le r�sultat n'est pas r�jouissant :

    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
     
    ....\affichage.cpp: In function 'void DisplayAstronomySection(int, int)':
    ...\affichage.cpp:7:3: error: 'display' was not declared in this scope; did you mean 'delay'?
        7 |   display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK);
          |   ^~~~~~~
          |   delay
    ...\affichage.cpp:7:39: error: 'GxEPD_BLACK' was not declared in this scope
        7 |   display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK);
          |                                       ^~~~~~~~~~~
    ...\affichage.cpp:8:3: error: 'u8g2Fonts' was not declared in this scope
        8 |   u8g2Fonts.setFont(u8g2_font_helvB08_tf);
          |   ^~~~~~~~~
    ...\affichage.cpp:8:21: error: 'u8g2_font_helvB08_tf' was not declared in this scope
        8 |   u8g2Fonts.setFont(u8g2_font_helvB08_tf);
          |                     ^~~~~~~~~~~~~~~~~~~~
    ....\affichage.cpp:9:24: error: 'affichalarme' was not declared in this scope
        9 |   drawString(x+5,y+95, affichalarme, LEFT);
          |                        ^~~~~~~~~~~~
    ...\affichage.cpp:9:38: error: 'LEFT' was not declared in this scope
        9 |   drawString(x+5,y+95, affichalarme, LEFT);
          |                                      ^~~~
    ..\affichage.cpp:9:3: error: 'drawString' was not declared in this scope; did you mean 'String'?
        9 |   drawString(x+5,y+95, affichalarme, LEFT);
          |   ^~~~~~~~~~
          |   String
    exit status 1
     
    Compilation error: 'display' was not declared in this scope; did you mean 'delay'?
    qu'ai-je oubli� par exemple de d�clarer ? j'ajoute que si je laisse la fonction dans le prog principal , le compilateur ne trouve aucune erreur

  10. #10
    Responsable Arduino et Syst�mes Embarqu�s


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 268
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 268
    Billets dans le blog
    48
    Par d�faut
    dans le .ino tu rajoutes le #include <Adafruit_trucbidule.h> et tu initialises Adafruit_trucbidule display(...les paramètres).

    dans le .h, tu rajoutes le #include <Adafruit_trucbidule.h>, et
    extern Adafruit_trucbidule display; // Déclaration externe.


    tu adapteras les trucbidule bien entendu

  11. #11
    Expert confirm�

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 932
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activit� : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 932
    Par d�faut
    mais sommes-nous oblig�s de r�p�ter 2 fois la m�me variable
    une fois en d�claration puis en d�finition
    En C++, il est essentiel de bien distinguer la d�claration, qui informe le compilateur de l�existence d�une variable (en pr�cisant son nom et son type) ou d�une fonction (en indiquant son nom, le type de ses param�tres et le type de retour), de la d�finition, qui correspond � l�allocation effective de la m�moire pour cette variable ou � la fourniture du corps de la fonction.

    Dans l�IDE Arduino, lorsqu�on cr�e plusieurs onglets avec l'extension .ino, l�IDE les fusionne automatiquement en un seul gros fichier .ino avant la compilation puis il parcourt ce fichier et g�n�re automatiquement en d�but de code toutes les d�clarations de fonctions n�cessaires, en indiquant leur nom, leurs param�tres et leur type de retour.

    => Cela permet au compilateur de conna�tre toutes les fonctions, m�me si elles sont d�finies plus bas dans le code, et explique pourquoi on peut appeler une fonction avant sa d�finition sans probl�me. Gr�ce � ce m�canisme, il n�est souvent pas n�cessaire d�utiliser des fichiers `.h`, `extern` ou d�autres s�parations classiques.

    En revanche, dans le cadre d'une compilation s�par�e standard avec des fichiers `.h` et `.cpp, chaque fichier est compil� ind�pendamment.

    Il faut se souvenir que le pr�processeur, lorsqu�il rencontre un `#include`, ne fait rien d�autre que copier textuellement le contenu du fichier `.h` � l�endroit o� le `#include` appara�t. Cela signifie que tout ce qui se trouve dans le `.h` � qu�il s�agisse de d�clarations ou de d�finitions � est litt�ralement ins�r� dans chaque fichier qui inclut ce `.h`.

    Si ce fichier `.h` contient des d�finitions, c�est-�-dire des allocations m�moire pour des variables ou le corps complet de fonctions, et qu�il est inclus plusieurs fois dans un m�me projet ou dans plusieurs fichiers `.cpp`, le compilateur va g�n�rer plusieurs d�finitions identiques pour chaque fichier compil�.

    Puis, lors de l��dition de lien (qui consiste � assembler tous les fichiers compil�s en un ex�cutable unique), le linker va se retrouver avec ces multiples d�finitions et produira une erreur, car il ne peut pas g�rer plusieurs allocations pour la m�me variable ou plusieurs corps identiques pour la m�me fonction.

    Pour �viter ce probl�me, la r�gle d'or consiste � mettre uniquement les d�clarations dans le fichier `.h`. Ces d�clarations indiquent simplement au compilateur que telle fonction ou telle variable existe, avec son type et son nom, mais sans r�server de m�moire ni fournir le corps de la fonction et que le linker les retrouvera plus tard.

    Les d�finitions, qui correspondent � l�allocation r�elle de la m�moire ou � la mise en place du code de la fonction, sont plac�es dans un fichier `.cpp` qui sera compil� une seule fois. De cette fa�on, on peut inclure le m�me fichier `.h` dans tous les fichiers n�cessaires � qu�il s�agisse d�autres `.cpp` ou m�me d�un `.ino` dans l�IDE Arduino � et le compilateur saura de quoi il s�agit gr�ce aux d�clarations, tout en �vitant de cr�er plusieurs allocations m�moire pour la m�me entit�.

    Donc pour votre question, OUI, on r�pt�te deux fois, mais une fois c'est la DECLARATION et l'autre fois c'est la DEFINITION.

    pour une variable, quand on ne veut pas allouer la m�moire (ie on fait la d�claration) on utilise extern
    pour une fonction, quand on ne veut pas allouer la m�moire (sans le code donc) pas besoin de extern, on met juste le prototype de la fonction suivi d'un ; au lieu du corps de la fonction.





    C'est plus clair?

  12. #12
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    Merci encore � tous les deux pour votre patience....

    Pour savoir si c'est clair je propose un exemple concret

    Dans mon fichier .ino , j'ai ceci :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display(GxEPD2_213_BN(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); 
    U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; 
    --/--
    #include "affichage.h"
    dans mon fichier affichage.h , j'ai ceci :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef AFFICHAGE_H
    #define AFFICHAGE_H
     
    void DisplayAstronomySection(int x, int y);
     
    #endif // AFFICHAGE_H
    et enfin dans mon fichier affichage.cpp j'ai la fonction suivante :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "affichage.h"
    #include <Arduino.h>
     
    //#########################################################################################
    void DisplayAstronomySection(int x, int y) {   <======
      display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK);
      u8g2Fonts.setFont(u8g2_font_helvB08_tf);
      drawString(x+5,y+95, affichalarme, LEFT);
      display.display(false); // Full screen update mode
    }
    si je veux compiler par ex
    display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK);


    je dois donc "d�couper" la dite fonction dans affichage.h en :

    void display(bool partial_update_mode = false) ;
    void drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
    uint16_t color);
    etc ...

    c'est �� ?

  13. #13
    Expert confirm�

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 932
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activit� : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 932
    Par d�faut
    Non ce serait dommage d'avoir � reprendre chaque fonction de la biblioth�que d'affichage comme drawRect() et d'en faire une fonction dans votre .cpp




    la question � vous poser est plut�t de savoir quelle est la logique des diff�rents fichiers pour savoir quoi d�clarer et o�

    Dans votre exemple, vous voulez avoir des onglets qui g�rent les affichages (affichage.h et affichage.cpp) donc il me semblerait logique de mettre la d�finition de display et de u8g2Fonts dans affichage.cpp et vous conservez toutes le fonctions li�es � l'affichage et qui utilisent display dans affichage.cpp. Les autres modules (si la logique est respect�e) n'utilisant que les fonctions n'ont pas � conna�tre l'existence de ces variables. il faudra sans doute avoir dans affichage.cpp une fonction begin() qui se chargera de l'initialisation de l'�cran et que vous appelez depuis le setup().

    C'est pour moi ce qui serait coh�rent.




    Sinon si vous voulez rester avec votre structure actuelle, il faut que affichage.cpp connaisse l'existence de display et de u8g2Fonts.
    Il faudra donc rajouter dans affichage.h leur d�claration pour que affichage.cpp puisse l'utiliser. On mettrait donc

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef AFFICHAGE_H
    #define AFFICHAGE_H
     
    extern GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display;
    extern U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;
     
    void DisplayAstronomySection(int x, int y);
     
    #endif // AFFICHAGE_H
    et le linker retrouvera ces 2 variables qui sont d�finies dans le .ino au moment de l'�dition de lien.



    Sinon il est d'usage de mettre tous les include au d�but du fichier, donc pas apr�s la d�claration de la variable
    ==>

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // les includes
    #include "affichage.h"
     
    // les variables globales 
    GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display(GxEPD2_213_BN(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); 
    U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; 
     
    ...

  14. #14
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    Salut Jay M

    la question � vous poser est plut�t de savoir quelle est la logique des diff�rents fichiers pour savoir quoi d�clarer et o�

    Dans votre exemple, vous voulez avoir des onglets qui g�rent les affichages (affichage.h et affichage.cpp) donc il me semblerait logique de mettre la d�finition de display et de u8g2Fonts dans affichage.cpp et vous conservez toutes le fonctions li�es � l'affichage et qui utilisent display dans affichage.cpp. Les autres modules (si la logique est respect�e) n'utilisant que les fonctions n'ont pas � conna�tre l'existence de ces variables. il faudra sans doute avoir dans affichage.cpp une fonction begin() qui se chargera de l'initialisation de l'�cran et que vous appelez depuis le setup().

    C'est pour moi ce qui serait coh�rent.
    Oui, vous avez bien saisi ma demande, en fait je cherche effectivement � faire des onglets regroupant les entit�s comme ici l'affichage

    ce que je ne comprends pas , c'est l'appel de la fonction begin()
    dans non cas : display.init(115200, true, 2, false);
    je pensais qu'elle ne pouvait se faire que dans le setup()

    j'ai donc repris le contenu de affichage.h comme suit :
    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
     
    #ifndef AFFICHAGE_H
    #define AFFICHAGE_H
     
    enum alignmentType {LEFT, RIGHT, CENTER};
     
    extern bool P1;
    extern bool P2;
    extern const float voltage; 
    extern float AHT_Temp ;
    extern float AHT_Humidite;
    extern uint8_t percentage;
    extern String(affichalarme);
     
    void InitialiseDisplay() ;
    void drawString(int x, int y, String text, alignmentType alignment);
    void DisplayAstronomySection(int x, int y);
    void Draw_Heading_Section();
    void DrawBattery(int x, int y) ;
    void DrawPanneaux(int x, int y);
    void Draw_Temp_Hum_Section(int x, int y);
    void full_sreeen();
    void powerOff();
     
    #endif // AFFICHAGE_H
    puis affichage.cpp

    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
     
    #include <Arduino.h>
    #include <GxEPD2_BW.h>
    #include <U8g2_for_Adafruit_GFX.h>
     
    #include "affichage.h"
     
    #define ENABLE_GxEPD2_display 0
    #define SCREEN_WIDTH   212
    #define SCREEN_HEIGHT  104
    #define Large 7    // For best results use odd numbers
    #define Small 3    // For best results use odd numbers
    GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display(GxEPD2_213_BN(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); 
    U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; 
     
    #define pinVb                35                  //* mesure BATT  
     
     
    String(affichdate);
    String(affichHeure);
     
     
    //#########################################################################################
    void InitialiseDisplay() {
      display.init(115200, true, 2, false);
      display.setRotation(1);                    // Use 1 or 3 for landscape modes
      u8g2Fonts.begin(display);                  // connect u8g2 procedures to Adafruit GFX
      u8g2Fonts.setFontMode(1);                  // use u8g2 transparent mode (this is default)
      u8g2Fonts.setFontDirection(0);             // left to right (this is default)
      u8g2Fonts.setForegroundColor(GxEPD_BLACK); // apply Adafruit GFX color
      u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
      u8g2Fonts.setFont(u8g2_font_helvB10_tf);   // Explore u8g2 fonts from here: https://github.com/olikraus/u8g2/wiki/fntlistall
      display.fillScreen(GxEPD_WHITE);
      display.setFullWindow();
    }
     
    //#########################################################################################
    void drawString(int x, int y, String text, alignmentType alignment) {
      int16_t  x1, y1; //the bounds of x,y and w and h of the variable 'text' in pixels.
      uint16_t w, h;
      display.setTextWrap(false);
      display.getTextBounds(text, x, y, &x1, &y1, &w, &h);
      if (alignment == RIGHT)  x = x - w;
      if (alignment == CENTER) x = x - w / 2;
      //if (alignment == LEFT) x = x + w ;
      u8g2Fonts.setCursor(x, y + h);
      u8g2Fonts.print(text);
    }
     
    //#########################################################################################
    void DisplayAstronomySection(int x, int y) {
      //display.drawRect(x+5, y+85 , 220, 25, GxEPD_BLACK);
      display.drawRect(x, y+85 , 240, 25, GxEPD_BLACK);
      u8g2Fonts.setFont(u8g2_font_helvB08_tf);
      drawString(x+5,y+95, affichalarme, LEFT);
      display.display(false); // Full screen update mode
    }
     
    //#########################################################################################
    void Draw_Heading_Section() {
      u8g2Fonts.setFont(u8g2_font_helvB08_tf);
      drawString(2, 1, affichdate+" "+affichHeure, LEFT);
      //display.drawLine(0, 11, 200, 11, GxEPD_BLACK);
    }
     
    //#########################################################################################
    void DrawBattery(int x, int y) {
     
      if (voltage > 1 ) { // Only display if there is a valid reading
        display.drawRect(x + 15, y - 12, 19, 10, GxEPD_BLACK);
        display.fillRect(x + 34, y - 10, 2, 5, GxEPD_BLACK);
        display.fillRect(x + 17, y - 10, 15 * percentage / 100.0, 6, GxEPD_BLACK);
        drawString(x + 60, y - 11, String(percentage) + "%", RIGHT);
      }
    }
     
    //#########################################################################################
    void DrawPanneaux(int x, int y){
      display.drawRect(x, y, x+184,y+60, GxEPD_BLACK);
      //Panneau droit
      display.drawRect(x+2, y+2, x+40,y+56, GxEPD_BLACK);  // P11
      display.drawRect(x+47, y+2, x+40,y+56, GxEPD_BLACK); // P12
      drawString(x + 23, y+27, "P1", CENTER);
      display.fillRect(x + 93, y, 3, 75, GxEPD_BLACK);
      //Panneau gauche
      display.drawRect(x+98, y+2, x+40,y+56, GxEPD_BLACK);  // P22
      display.drawRect(x+142, y+2, x+40,y+56, GxEPD_BLACK); // P21
      drawString(x + 164, y+27, "P2", CENTER);
      if (!P1) {
          display.fillRoundRect(x+49, y+4, x+36, y+52 ,4, GxEPD_BLACK);
      }else{
          display.fillRoundRect(x+4, y+4, x+36, y+52 ,4, GxEPD_BLACK);
      }
      if (!P2) {
          display.fillRoundRect(x+100, y+4, x+36, y+52,4, GxEPD_BLACK);   
      }else{
          display.fillRoundRect(x+144, y+4, x+36, y+52,4, GxEPD_BLACK);
      }
     
    }
     
    //#########################################################################################
    void Draw_Temp_Hum_Section(int x, int y){
      //sensors_event_t humidity, temp;
      //aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
      //Serial.print("Temperature: "); Serial.print(temp.temperature,1); Serial.println(" degrees C");
      //Serial.print("Humidity: "); Serial.print(humidity.relative_humidity,0); Serial.println("% rH");
      display.drawRect(x, y,x+10,y+60, GxEPD_BLACK); 
      display.drawLine(x, y+36, x+60, y+36, GxEPD_BLACK);
      u8g2Fonts.setFont(u8g2_font_helvB18_tf);
      //drawString(210,35, String(temp.temperature,0)+"c", CENTER);
      drawString(210,35, String(AHT_Temp,0)+"c", CENTER);
      //drawString(210,70, String(humidity.relative_humidity,0)+"%", CENTER);
      drawString(210,70, String(AHT_Humidite,0)+"%", CENTER);
      delay(500);
    }
     
    void full_sreeen(){
      display.display(false); // Full screen update mode 
    }
     
    void powerOff(){
     display.powerOff();  
    }
    j'ai du cr�er 2 fonctions suppl�mentaires car appel�es par mon .ino
    - void full_sreeen()
    - void powerOff()

    apr�s de nombreuse gal�res , le programme se compile
    apr�s la partie affichage , je continue avec la partie RTC ......

  15. #15
    Expert confirm�

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 932
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activit� : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 932
    Par d�faut
    L�appel a begin se fait dans le set up mais rien ne vous emp�che de mettre cela au fin fond d�un appel de fonctions imbriqu�es. L�important c�est que ce soit fait avant que vous ne commenciez � utiliser votre �cran�.

    setup() est juste une fonction comme une autre, appel�e une seule fois par la fonction main() qui est g�n�r�e automatiquement par l�IDE. Pas de magie.

    Vous avez main() qui appelle setup() qui peut appeler preparerEcran() qui appelle begin() par exemple

    ___

    Sinon, oui toutes les fonctions qui doivent �tre connues en dehors de votre .cpp doivent �tre d�clar�es dans le .h et ce .h inclus dans le fichier o� vous voulez utiliser la fonction.

  16. #16
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    Salut Jay M

    Je commence � comprendre ( du moins j'esp�re) le principe de base
    � savoir dans un fichier .h et .cpp

    mettre "extern" dans le fichier .h lorsqu'une variable est cr��e ailleurs dans un autre sous-programme
    mettre aussi la fonction "void trucmuche (..) ;"

    mais comment fait-on lorsque dans un fichier .cpp , j'utilise une fonction d'autre .cpp ?

  17. #17
    Expert confirm�

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 932
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activit� : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 932
    Par d�faut
    Salut,

    Imaginez que vous ayez a.h, a.cpp et b.h et b.cpp

    Si dans b.cpp vous voulez utiliser une fonction fonctionA() d�finie dans a.cpp, l�approche traditionnelle est de d�clarer le prototype de fonctionA() dans a.h et dans b.cpp vous faites un include de a.h

    De m�me, si dans a.cpp vous voulez utiliser une fonction fonctionB() d�finie dans b.cpp, vous d�clarez le prototype de fonctionB() dans b.h et dans a.cpp vous faites un include de b.h

    En resum� le fichier header .h permet de d�clarer tout ce qu�on veut faire conna�tre � l�ext�rieur de son .cpp. Tout autre fichier .cpp voulant utiliser un de ces �l�ments n�aura qu�� inclure ce .h

  18. #18
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    ok merci bien Jay M
    je vais..tenter

    a-t-on le droit de d�cliner les m�mes << #includes >> de fa�on infinie
    dans chaque sous-programmes comme par ex
    #include <SPI.h>
    #include <Wire.h>

  19. #19
    Expert confirm�

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 932
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activit� : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 932
    Par d�faut
    Vous pouvez avoir autant d�include que vous voulez, �a ne fait que ins�rer le texte du .h � cet endroit du fichier avant de compiler.

    L�usage de � gardes � en d�but de fichier .h qui disent � si ce fichier a d�j� �t� import� pas la peine de le rajouter � permettra d��viter des boucles dans les include (si a.h inclut b.h et inversement et que vous mettez les deux dans le m�me fichier tiers les inclusions de texte seraient infinie on rajoute a.h et b.h puis le compilateur relit et voit que a.h a aussi des include dont b.h donc injecte � nouveau b.h et qui contient l�inclusion de a.h etc et donc �a planterait.

    Donc c�est pour �a que Toto.h par exemple est toujours encadr� par un #ifndef
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef TOTO_H
    #define TOTO_H
     
    …
     
    #endif
    Comme �a si le define a d�j� eu lieu lors de la prochaine tentative d�inclusion le code ne sera pas inject� et donc la boucle sans fin sera �vit�e.



    Sinon pour votre question, oui il faut inclure les D�CLARATIONS de tout ce dont vous avez besoin. Comme expliqu� une d�claration n�alloue pas de m�moire c�est juste une information que vous donnez au compilateur sur le nom et type d�une variable ou prototype de fonction. C�est OK de lui expliquer 10 fois la m�me chose - du moment que c�est bien la m�me chose. (Vous ne pouvez pas lui dire que vous avez une variable externe qui s�appelle toto et une fois c�est un entier et une autre fois c�est un float - il faut rester coh�rent). C�est aussi pour cela que l�on ne met pas de DEFINITION dans un .h sinon on se retrouve avec la variable allou�e plusieurs fois et �a n�est pas possible bien s�r .

    (Il y a quelques exceptions � tout cela mais c�est pour des concepts et besoins plus avanc� donc appliquez d�j� ces r�gles et vous verrez �a va tout seul).

    -> un module (.h et .cpp) doit avoir un sens et �tre coh�rent (tout ce qui concerne l�affichage par exemple)
    -> le .h ne contient aucune d�finition, que des d�clarations et a son #ifndef
    -> le .cpp reprend bien exactement le meme type o� signature pour la d�finition des variables et fonctions.
    -> Chaque fichier .cpp doit inclure son propre .h en premier pour v�rifier la coh�rence des d�clarations et �viter les d�pendances cach�es.
    -> si vous voulez utiliser un module ailleurs vous incluez son .h dans votre .cpp ou .ino (�ventuellement on peut l�inclure dans le .h si des fonctions de ce nouveau module utilisent un type par exemple d�crit dans l�autre .h)

  20. #20
    Membre �prouv�
    Inscrit en
    Juillet 2004
    Messages
    1 051
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 051
    Par d�faut
    merci Jay M

    je souhaiterai vous soumettre mon croquis si vous �tes d'accord car je gal�re sur une partie
    � savoir l'affichage de la date du jour et de l'heure ( pourtant affich�es sur la console mais que je n'arrive maintenant plus � afficher du le E-paper )
    mais comment faire s'il comporte plusieurs fichier.h et il me semble que pour la compr�hension , il faut l'ensemble de tous les fichiers
    un zip peut-�tre ?

Discussions similaires

  1. Mettre a jour un programme en fonction de l'utilisateur
    Par morgan47 dans le forum VB 6 et ant�rieur
    R�ponses: 6
    Dernier message: 02/05/2007, 10h33
  2. R�ponses: 1
    Dernier message: 28/03/2007, 15h33
  3. R�ponses: 10
    Dernier message: 11/01/2007, 21h45
  4. Programmer une fonction joindre_fichier
    Par leCcsympas dans le forum R�seau
    R�ponses: 5
    Dernier message: 03/12/2006, 19h51
  5. R�ponses: 2
    Dernier message: 31/05/2005, 09h50

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