Gestions des menus avec pic - Page 2
Répondre à la discussion
Page 2 sur 2 PremièrePremière 2
Affichage des résultats 31 à 57 sur 57

Gestions des menus avec pic



  1. #31
    eSb`

    Re : Gestions des menus avec pic


    ------

    Encore moi, vu que tu voulais aussi ajouter des accents, je m'y suis penché (ça m'entraine aussi).
    L'idée est d'ajouter le caractère dans le contrôleur du LCD, ensuite d'envoyer la chaîne et si on rencontre un 'é' on affiche ce qui se trouve dans le contrôleur.
    Il y a des Warning dans mikroC avec les 'é' mais je ne sais pas pourquoi.

    A ajouter :

    Code:
    const char character[] = {2,4,14,17,31,16,14,0}; // Ligne par ligne : caractère 'é'
    
    void AddEacute()
    {
        char i;
        LCD_Cmd(0x40); // On positionne CGRAM à l'adresse 0x00
        
        for (i=0; i<=7; i++)
           LCD_Chr_Cp(character[i]); // On envoie ligne par ligne
    }

    Dans ton main(), afin d'ajouter le caractère dans le contrôleur du LCD, tu ajoutes :

    Code:
    AddEacute();

    Et tu modifies la routine Lcd_Cmd_Out :

    Code:
    void Lcd_Const_Out(unsigned char row, unsigned char col, const char *pString)
    {
      Lcd_Out(row, col, ""); // ou LCD_Cmd(LCD_CLEAR);
      while(*pString)
      {
        if(*pString == 'é') // Si on rencontre 'é' on l'affiche
           Lcd_Chr_Cp(0x00);
        else
           Lcd_Chr_Cp(*pString);
        pString++;
      }
    }

    -----

  2. #32
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Ce qui a l'avantage de ne pas nécessiter de variable temporaire et donc gain en RAM.
    Gain en RAM, probablement, mais surtout grosse conso CPU ! ... chaque appel de fonction coute un empilement/depilement de contexte ... c'est cher sur ces petits PIC ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  3. #33
    DavidDB

    Re : Gestions des menus avec pic

    Salut Seb.26,

    Faut voir le code assembleur généré...

    La consommation en temps CPU est négligeable, c'est une douzaine d'instructions (à comparer avec une solution de buffer en RAM, la différence devient ridicule).
    De plus, comme c'est pour de l'affichage sur un LCD, il faut tenir compte du temps de traitement LCD qui demande 40µSec, et ce n'est pas quelques instructions supplémentaires qui vont mettre à genoux le µC. Le µC va quand même devoir attendre entre l'écriture de deux caractères sur le LCD.

    Si le programme est correctement réalisé, ce n'est pas l'utilisation d'un espace dans la pile qui va générer un overflow.
    Perso, dans mes routines ASM, suivant le contexte la gestion du LCD arrive à demander deux espaces de la pile, mais qui sont libéré après l'affichage complet du texte.

    Dans tous les cas, pour du texte LCD, il est impératif de le stocker en Flash, car ce type de données n'est pas sujet à modification et ce n'est pas à proprement parler des variables.

    David.

  4. #34
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par DavidDB Voir le message
    Dans tous les cas, pour du texte LCD, il est impératif de le stocker en Flash, car ce type de données n'est pas sujet à modification et ce n'est pas à proprement parler des variables.
    Complètement d'accord ! ...

    Pour le reste, je dirais que c'est surtout des habitudes propres à chacun, car dans le fond, je suis de ton avis : c'est tirebou-stroumph et stroumph-bouchon ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  5. #35
    eSb`

    Re : Gestions des menus avec pic

    Bonjour à vous deux,

    En fait, j'ai du mal à percevoir où est l'utilisation de la pile dans "ma" solution et qui n'apparait pas avec un buffer ?

    Merci à vous : ).

  6. #36
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Bonjour à vous deux,
    En fait, j'ai du mal à percevoir où est l'utilisation de la pile dans "ma" solution et qui n'apparait pas avec un buffer ?
    Merci à vous : ).
    Tu fais un appel de fonction par caractère, donc à chaque fois, c'est empillage/dépillage du contexte ... donc selon ce que tu cherche ( RAM ou % CPU ), il est bon de faire attention ...

    Par exemple, dans mes IT, je n'appèle jamais de fonction, j'inclu directement le code via un #include "toto.c" (oui : c'est moche) ... Et bien, le gain est spectaculaire ... Je vous invite à essayer un jour ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  7. #37
    eSb`

    Re : Gestions des menus avec pic

    Merci, c'est vrai que je n'avais pas pensé à ça ; ).

    Sinon, je tente moi aussi de faire l'application qui est voulue (enfin, comme je la suppose). Ca ne me sert à rien, à part à m'entrainer : ).

    Cependant, j'ai du mal à trouver un moyen de sélectionner les différents menus (si j'en sélectionne un, pas de souci, mais passer de l'un à l'autre m'est problématique, enfin comme cela a été présenté au départ, un tableau à deux dimensions serait plus facile à mettre en oeuvre mais entrainerait une perte de mémoire car tous les menus n'ont pas le même nombre de choix).

    Voilà mon code qui vaut ce qu'il vaut mais qui fonctionne pour le moment. (si vous avez des améliorations, je suis preneur)

    Ici, j'utilise clairement cMenu1, mon problème serait de trouver un moyen de passer facilement à cMenuX (choisi par boutons-poussoirs).

    J'ai voulu faire avec un pointeur char* comme tenté au début mais j'ai du mal avec le passage ROM / RAM.

    Auriez-vous des idées ? : )

    Merci

    Ps: Dans le programme actuel, il y a des boutons-poussoirs en RA0->RA3.
    J'affiche le premier élément des menus sur la première ligne (donc dans cMenu1 : Climat) et le reste du menu peut-être sélectionné par RA0 et RA1.
    Code:
          //*************************************************************
          //                     Variables globales                     *
          //*******************************************************************
      const char *cMenu1[] = {"Climat", " Température", " Humidité sol", " Luminosité"};
      const char *cMenu2[] = {"Electrovannes", "Voie 1", "Voie 2", "Voie 3", "Voie 4", "Voie 5"};
      const char *cMenu3[] = {"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumi"};
      const char *cMenu4[] = {"Choix méthode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"};
    
      const char cEacute[] = {2,4,14,17,31,16,14,0};
    
          //*************************************************************
          //                      Prototypes                            *
          //*************************************************************
      void AddEacute();
      void Lcd_Const_Out(unsigned char row, unsigned char col, const char *pString);
      char strlen_const(const char *pString);
      char SizeOfArray(const char *pArray[]);
      
    void main()
    {
          //*************************************************************
          //                     Variables locales                      *
          //*************************************************************
      char  i,
            cSizeArray;
      short nOldState,
            nSelMenuOld, nSelMenu = 0,
            nSelInMenuOld, nSelInMenu = 1;
    
      struct strButton
      {
         unsigned A0 : 1;
         unsigned A1 : 1;
         unsigned A2 : 1;
         unsigned A3 : 1;
      } strStateButton;
    
          //*************************************************************
          //                  Configuration du PIC                      *
          //*************************************************************
      ANSEL  = 0;                              // Configure AN pins as digital I/O
      ANSELH = 0;
      TRISA  = 0xFF;                           // PORTA en entrée
      
      Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // Lcd_Init_EP5, see Autocomplete
      Lcd_Cmd(LCD_CURSOR_OFF);
    
          //*************************************************************
          //                    Initialisation                          *
          //*************************************************************
      AddEacute();
      Lcd_Const_Out(1,1, cMenu1[0]);
      Lcd_Const_Out(2,1, cMenu1[1]);
      cSizeArray = sizeof(cMenu1) / 2;
    
          //*************************************************************
          //                        Programme                           *
          //*************************************************************
      do
      {
        // On monte dans le menu sur un flanc montant
        if(PORTA.F0)
           strStateButton.A0 = 1;
        if(!PORTA.F0 && strStateButton.A0)
          if(strStateButton.A0 = 0, ++nSelInMenu == cSizeArray)
               nSelInMenu = 1;
    
        // On descend dans le menu sur un flanc montant
        if(PORTA.F1)
           strStateButton.A1 = 1;
        if(!PORTA.F1 && strStateButton.A1)
          if(strStateButton.A1 = 0, --nSelInMenu == 0)
               nSelInMenu = cSizeArray-1;
    
        if (nSelInMenu != nSelInMenuOld)
        {
           //Lcd_Const_Out(1,1, cMenu1[0]);
           Lcd_Const_Out(2,1, cMenu1[nSelInMenu]);
           cSizeArray = sizeof(cMenu1) / 2;
        }
    
        nSelInMenuOld = nSelInMenu;
      }
      while(1);
    }
          //*************************************************************
          //                        Fonctions                           *
          //*************************************************************
    
    // Ajout de l'accent en CGRAM
     void AddEacute()
    {
        char i;
        LCD_Cmd(0x40); // On positionne CGRAM à l'adresse 0x00
    
        for (i=0; i<=7; i++)
           LCD_Chr_Cp(cEacute[i]); // On envoie ligne par ligne
    }
    
    // Affichage d'un caractère de ROM
    void Lcd_Const_Out(unsigned char row, unsigned char col, const char *pString)
    {
      Lcd_Out(row, col, "                ");
      
      if (row == 1)
      {
         Lcd_Cmd(LCD_FIRST_ROW);
         Lcd_Chr_Cp(0xA5);
      }
      else
      {
         Lcd_Cmd(LCD_SECOND_ROW);
         Lcd_Chr_Cp(0x7E);
      }
      
      while(*pString)
      {
        if(*pString == 'é')
           Lcd_Chr_Cp(0x00);
        else
           Lcd_Chr_Cp(*pString);
        pString++;
      }
    
      Delay_ms(200);
    }

  8. #38
    alainav1

    Re : Gestions des menus avec pic

    bonjour,

    juste une idée pour choisir un menu sur un LCD .
    mesurer la tension au borne du curseur d'un potentiometre
    utiliser un poussoir pour le valider
    suivant la valeur afficher le texte sur le LCD
    algorithme
    exemple :
    mesure de la tension
    m= partie entière de (tension*10)/5 (ce qui donne choix entre 10 valeurs )
    affichage du menu correspondant
    validation par le poussoir --> execution du sous programme affiché

    cordialement
    Alain
    Décider de faire, c'est bien . Décider quand, c'est mieux !

  9. #39
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Ici, j'utilise clairement cMenu1, mon problème serait de trouver un moyen de passer facilement à cMenuX (choisi par boutons-poussoirs).
    Plutôt que d'utiliser cMenu1, pourquoi pas un pointeur de tableaux de chaines, de cette façon tu pourras pointer sur le cMenuX de ton choix

    NB: j'ajoute un pointeur NULL en tant que dernier élément du tableau pour pouvoir détecter la fin du menu, et avoir des menu avec un nombre différents d'éléments ... on peut aussi utiliser un #define pour le nombre d'éléments, on gagne en taille en ROM, mais ça oblige à compter les éléments...

    Dans ce genre là par exemple :

    Code:
      const char *cMenu1[] = {"Climat", " Température", " Humidité sol", " Luminosité", 0};
      const char *cMenu2[] = {"Electrovannes", "Voie 1", "Voie 2", "Voie 3", "Voie 4", "Voie 5", 0};
      const char *cMenu3[] = {"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumi", 0};
      const char *cMenu4[] = {"Choix méthode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3", 0};
    
      const char **allMenu[] = { cMenu1, cMenu2, cMenu3, cMenu4, 0 };
    
      char ** actualMenu;
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  10. #40
    Seb.26

    Re : Gestions des menus avec pic

    PS: il est plus judicieux AMA de stocker l'indice actuel dans allMenu :

    Code:
    //char ** actualMenu;
    unsigned char actualMenu_pos;


    PS: pourquoi une pause de 200ms dans ton affichage ???
    ( attention aux mauvaises raisons ... )
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  11. #41
    eSb`

    Re : Gestions des menus avec pic

    Merci pour tes réponses : ), je vais tester tout ça. (c'est quand même tordu ces pointeurs de pointeurs :d)

    Eh bien, c'est sûrement pas la meilleure façon de procéder mais en tout cas une solution simple, ça me sert "d'anti-rebond", empêchant à l'utilisateur de "mitrailler" mon pauvre bouton pour faire défiler les choix dans les menus et donc de ne pas avoir un affichage un peu étrange (défilement rapide).

  12. #42
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Eh bien, c'est sûrement pas la meilleure façon de procéder mais en tout cas une solution simple, ça me sert "d'anti-rebond", empêchant à l'utilisateur de "mitrailler" mon pauvre bouton pour faire défiler les choix dans les menus et donc de ne pas avoir un affichage un peu étrange (défilement rapide).
    C'est bien ce que je présentais ...
    ( Et ce n'est effectivement pas une très bonne façon de procéder ... mais ça marche à peu près, et chaque chose en son temps ... )
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  13. #43
    Seb.26

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Merci pour tes réponses : ), je vais tester tout ça. (c'est quand même tordu ces pointeurs de pointeurs :d)
    cMenu1 est un pointeur de pointeurs ( un tableau est en fait un pointeur et réciproquement ) ... allMenu est un pointeur de pointeurs de pointeurs ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  14. #44
    eSb`

    Re : Gestions des menus avec pic

    Voilà le résultat final :

    C'est certainement perfectible mais je suis arrivé où je le voulais. (vu que ça me sert quand même à rien, je vais pas aller trop loin dans l'optimisation ;d)

    Le principal "souci" est effectivement ma pause de 100ms qui induit un affichage non simultané du nom du menu et sa composante, mais je n'ai pas envie de faire un système anti-rebond. (je pourrais en plus le faire facilement grâce à une routine mikroC)

    S'il y a des trucs vraiment trop mauvais, je veux bien qu'on me le dise pour que je puisse changer de système par la suite.

    PS: ce code est pour un PIC16F887, Quartz 8MHz. (mais je ne pense pas que beaucoup de choses seraient à changer pour un autre)

    Code:
          //*************************************************************
          //                       Définitions                          *
          //*************************************************************
      #define NULL 0
    
          //*************************************************************
          //                     Variables globales                     *
          //*************************************************************
      const char *cMenu1[]    = {"Climat", " Température", " Humidité sol", " Luminosité", NULL};
      const char *cMenu2[]    = {"Electrovannes", " Voie 1", " Voie 2", " Voie 3", " Voie 4", " Voie 5", NULL};
      const char *cMenu3[]    = {"Seuils", " Seuil Temp", " Seuil Humi", " Seuil Lumi", NULL};
      const char *cMenu4[]    = {"Choix méthode", " Automatique", " Cycle 1", " Cycle 2", " Cycle 3", NULL};
      const char **cAllMenu[] = {cMenu1, cMenu2, cMenu3, cMenu4, NULL};
    
      const char cEacute[] = {2,4,14,17,31,16,14,0};
    
          //*************************************************************
          //                      Prototypes                            *
          //*************************************************************
      void AddEacute();
      void Lcd_Const_Out(unsigned char row, unsigned char col, const char *pString);
      char SizeOfArray(const char **pArray[], short nSelMenu);
      
    void main()
    {
          //*************************************************************
          //                     Variables locales                      *
          //*************************************************************
      char   i,
             cSizeArray;
      short  nOldState,
             nSelMenuOld   = 0,
             nSelMenu      = 0,
             nSelInMenuOld = 1,
             nSelInMenu    = 1;
    
      struct strButton
      {
         unsigned A0 : 1;
         unsigned A1 : 1;
         unsigned A2 : 1;
         unsigned A3 : 1;
      } strStateButton;
    
          //*************************************************************
          //                  Configuration du PIC                      *
          //*************************************************************
      ANSEL  = 0;                              // AN pins en I/O
      ANSELH = 0;
      TRISA  = 0xFF;                           // PORTA en entrée
      
      Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // Lcd_Init_EP5
      Lcd_Cmd(LCD_CURSOR_OFF);
    
          //*************************************************************
          //                    Initialisation                          *
          //*************************************************************
      AddEacute();
      Lcd_Const_Out(1,1, *cAllMenu[nSelMenu]);  // Menu 1
      Lcd_Const_Out(2,1, *(cAllMenu[nSelMenu] + nSelInMenu)); // Menu 1 -> Sous-section 1
      cSizeArray = SizeOfArray(cAllMenu, nSelMenu); // Nombre d'éléments du Menu1
    
          //*************************************************************
          //                        Programme                           *
          //*************************************************************
      do
      {
        // On monte dans le menu sur un flanc montant
        if(PORTA.F0)
           strStateButton.A0 = 1;
        if(!PORTA.F0 && strStateButton.A0)
          if(strStateButton.A0 = 0, ++nSelInMenu == cSizeArray)
               nSelInMenu = 1;
    
        // On descend dans le menu sur un flanc montant
        if(PORTA.F1)
           strStateButton.A1 = 1;
        if(!PORTA.F1 && strStateButton.A1)
          if(strStateButton.A1 = 0, --nSelInMenu == 0)
               nSelInMenu = cSizeArray-1;
               
        // On monte de menu sur un flanc montant
        if(PORTA.F2)
           strStateButton.A2 = 1;
        if(!PORTA.F0 && strStateButton.A2)
          if(strStateButton.A2 = 0, ++nSelMenu == sizeof(cAllMenu)-1)
               nSelMenu = 0;
    
        // On descend de menu sur un flanc montant
        if(PORTA.F3)
           strStateButton.A3 = 1;
        if(!PORTA.F1 && strStateButton.A3)
          if(strStateButton.A3 = 0, --nSelMenu < 0)
               nSelMenu = sizeof(cAllMenu)-2;
    
        if (nSelMenu != nSelMenuOld)
        {
           nSelInMenu = 1; // On re-sélectionne la première sous-section
           Lcd_Const_Out(1,1, *(cAllMenu[nSelMenu]));
           Lcd_Const_Out(2,1, *(cAllMenu[nSelMenu] + nSelInMenu));
        }
           
        if (nSelInMenu != nSelInMenuOld)
        {
           Lcd_Const_Out(2,1, *(cAllMenu[nSelMenu] + nSelInMenu));
           cSizeArray = SizeOfArray(cAllMenu, nSelMenu);
        }
    
        nSelInMenuOld = nSelInMenu;
        nSelMenuOld = nSelMenu;
      }
      while(1);
    }
          //*************************************************************
          //                        Fonctions                           *
          //*************************************************************
    
    // Ajout de l'accent en CGRAM
     void AddEacute()
    {
        char i;
        LCD_Cmd(0x40); // On positionne CGRAM à l'adresse 0x00
    
        for (i=0; i<=7; i++)
           LCD_Chr_Cp(cEacute[i]); // On envoie ligne par ligne
    }
    
    // Affichage d'un caractère de ROM
    void Lcd_Const_Out(unsigned char row, unsigned char col, const char *pString)
    {
      Lcd_Out(row, col, "                ");
      
      if (row == 1)
      {
         Lcd_Cmd(LCD_FIRST_ROW);
         Lcd_Chr_Cp(0xA5); // Point
      }
      else
      {
         Lcd_Cmd(LCD_SECOND_ROW);
         Lcd_Chr_Cp(0x7E); // Flèche
      }
      
      while(*pString)
      {
        if(*pString == 'é')
           Lcd_Chr_Cp(0x00);
        else
           Lcd_Chr_Cp(*pString);
        pString++;
      }
    
      Delay_ms(100);
    }
    
    // Calcul du nombre d'éléments dans chaque menu
    char SizeOfArray(const char **pArray[], short nSelMenu)
    {
        char cCount = 0;
        char *pArrayOld = pArray[nSelMenu];
    
        while(*pArray[nSelMenu]++ != NULL)
            cCount++;
    
        pArray[nSelMenu] = pArrayOld;
        return cCount;
    }

  15. #45
    Seb.26

    Re : Gestions des menus avec pic

    Franchement :

    Ton code est très propre, tu peux être fier de toi ... Mais je pense que tu n'es pas un débutant en dev ... ou alors continue !!!

    Pour ton antirebond, effectivement c'est pas terrible ... alors comme t'as déjà fini ton TP et qu'il te reste du temps, voilà ce que je te propose :

    1) Tu virre ton delay_ms(200)

    2) Tu ajoute un delay_ms(10) dans ton While(1)

    -> De cette façon, ta boucle s'exécute en (très) gros toutes les 10ms, suffisant pour filtrer une entrée ...

    3) Tu réalise un "vrai" pooling d'entrée avec détection/validation de front (montant) ...

    On arrive donc à la question : qu'est-ce qu'un front montant valide ?

    Et bien, on pourrait dire que c'est quand une entrée est à l'état 0 et qu'elle passe à 1.
    Il faut alors ajouter que pour changer d'état, une entrée doit présenter un nouvel état de façon stable et maintenue dans le temps.



    Avec ces quelques débuts de piste et un peu de réflexion, tu devrais pouvoir réaliser ça tout seul ...

    Et ensuite, tu te demandera s'il n'est pas dommage d'attendre "bêtement" dans un delay_ms(10) ?
    ... et comme : OUI, c'est dommage ( ne serait-ce car ce n'est pas précis )

    -> comment remplacer ce delay_ms(10) par autre chose de plus précis ?

    Et voilà, à toi de jouer !
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  16. #46
    eSb`

    Re : Gestions des menus avec pic

    Merci, eh bien, bien qu'ayant des notions dans divers langages (C, C++, C#, Delphi, OpenGL, Matlab), on ne peut pas dire que j'aie beaucoup pratiqué; donc je profite de mes vacances pour m'y mettre et tenter de faire ça proprement ; ).

    Pour mon code, je n'avais pas vu mais il y a deux petites erreurs au niveau du changement de menu (je vérifie PORTA.F2 puis PORTA.F0 et idem en PORTA.F3 -> copié/collé non modifié ;d).
    Et bien qu'ayant mis "flanc montant", pour le moment j'évalue le tout sur flanc descendant. (ce qui paraissait mieux réagir aux rebonds mais ce qui, après test, ne se vérifie évidemment pas ; ))

    Je vais me pencher sur un vrai anti-rebond : ).

    Je suppose que la meilleure manière de faire est de lire, relire un moment après (reste à trouver le temps idéal) et si on a la même chose, on peut supposer que l'état est stable ?

  17. #47
    Jack
    Modérateur

    Re : Gestions des menus avec pic

    Un peu de littérature sur les anti rebonds (hard et soft).

    A+

  18. #48
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Bonsoir,

    Tout d'abord je suis désolé pour cette longue absence.

    Infiniment merci pour tous ceux qui ont participé à la discussion surtout eSb` pour le listing qu'il a développé.

    J'ai pas dit que je suis nul en c(j'ai fait du basic mais ça parait un peu différent).

    Donc j'ai besoin de votre aide pour comprendre des détails.. j'aime pas recopier de des scripts bêtement.

    Pour la déclaration des chaines de caractères
    • Quelle est la différence entre:
    Code:
    const char *menu1[] = {"Climat", "Temperature", "Humidite sol", "Lumlinosite"};
    const char menu1[] = {"Climat", "Temperature", "Humidite sol", "Lumlinosite"};
    • Que signifient les 2 accolades vides
    : la longueur des chaines est indéfinie ou la dimension du tableau qui est indéfinie? et quels sont les limites éventuelles?).
    • Comment déclarer une matrice de chaines de caractères(const)?
    J'ai essayé
    Code:
    const char *menu[][] = {{"Climat", "Tempèrature", "Humidité sol", "Lumlinosite"},"Electrovannes", "Voie 1", "Voie 2", "Voie 3", "Voie 4","Voie 5"},{"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumli"},{"Chodix methode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"}};
    mais le compilateur renvoi des erreurs.
    • Que signifie: ++nom_variable (je connais le syntaxe nom_variable++)
    • Que signifie: #define NULL 0
    • Que signifie: *pArray[nSelMenu]++ != NULL

    Merci d'avance

  19. #49
    Jack
    Modérateur

    Re : Gestions des menus avec pic

    Que signifient les 2 accolades vides
    La dimension et l'initialisation du tableau avec les chaines est automatique

    Comment déclarer une matrice de chaines de caractères(const)?
    C'est ce que tu as fait au-dessus

    Que signifie: ++nom_variable (je connais le syntaxe nom_variable++)
    C'est de la préincrémentation: l'incrémentation est effectuée avant une opération quelconque avec la variable en question.

    Que signifie: #define NULL 0
    Toute occurrence de NULL dans le programme sera remplacée par 0 par le préprocesseur, donc juste avant la compilation.

    Que signifie: *pArray[nSelMenu]++ != NULL
    Il faudrait voir la partie déclaration.

    A+

  20. #50
    eSb`

    Re : Gestions des menus avec pic

    Pour :
    Que signifie: *pArray[nSelMenu]++ != NULL
    Si tu as bien vu dans mon dernier programme, j'ai dans chaque menu ajouté un "0" (NULL) en dernier élément. (comme conseillé par Seb.26)

    Donc ici l'idée est de compter le nombre de sous-menus dans chaque menus. (je ne pense pas que ce soit faisable par sizeof() ou autre)
    Donc on prend la même idée que pour une chaîne de caractère :
    *pArray[nSelMenu]++ permet de "regarder s'il y a quelque chose à l'adresse pointée par pArray[nSelMenu] différent de NULL"
    Si oui, on compte (nCount++) car on a rencontré un sous-menu et on reteste (l'adresse a changé par le "++").
    Si non, on sort parce qu'on a rencontré le NULL.
    Au final, on a compté le nombre d'éléments.

    L'idée était identique avec une chaîne de caractère où on attend de rencontrer '\0' pour arrêter la boucle.

    Pour ton erreur de *menu[][], il me semble que tu ne peux pas donner tant d'inconnues au compilateur. Si tu fixes la deuxième valeur, ça devrait passer. (mais du coup, on atteint ton tableau à deux dimensions que tu voulais éviter au début ; ))

    Ps: Merci Jack pour le document, j'essayerai tout ça dès je retrouverai du courage ;d.
    Dernière modification par eSb` ; 10/08/2008 à 22h19.

  21. #51
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Merci pour la réponse rapide Jack
    Citation Envoyé par Jack Voir le message
    C'est ce que tu as fait au-dessus
    const char *menu[][] = {{"Climat", "Tempèrature", "Humidité sol", "Lumlinosite"},"Electrovannes" , "Voie 1", "Voie 2", "Voie 3", "Voie 4","Voie 5"},{"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumli"},{"Chodix methode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"}};

    ca renvoie "internal errror" et "multi dimension array missing subscript" et "too many initializers" et "invalid declarator" et "identifier redifined"

    @+

  22. #52
    Jack
    Modérateur

    Re : Gestions des menus avec pic

    const char *menu[][] = {{"Climat", "Tempèrature", etc.
    Il est impossible d'effectuer une initialisation automatique avec [][], le compilateur a au moins besoin de connaitre une des 2 dimensions.

  23. #53
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Pour :

    Si tu as bien vu dans mon dernier programme, j'ai dans chaque menu ajouté un "0" (NULL) en dernier élément. (comme conseillé par Seb.26)

    Donc ici l'idée est de compter le nombre de sous-menus dans chaque menus. (je ne pense pas que ce soit faisable par sizeof() ou autre)
    Donc on prend la même idée que pour une chaîne de caractère :
    *pArray[nSelMenu]++ permet de "regarder s'il y a quelque chose à l'adresse pointée par pArray[nSelMenu] différent de NULL"
    Si oui, on compte (nCount++) car on a rencontré un sous-menu et on reteste (l'adresse a changé par le "++").
    Si non, on sort parce qu'on a rencontré le NULL.
    Au final, on a compté le nombre d'éléments.

    L'idée était identique avec une chaîne de caractère où on attend de rencontrer '\0' pour arrêter la boucle.
    Oui j'ai compris ca merci pour les commentaires.
    ce que j'ai pas compris au début c'est xxxxx++=yyyy
    maintenant c'est bien clair.

    Citation Envoyé par eSb` Voir le message
    Pour ton erreur de *menu[][], il me semble que tu ne peux pas donner tant d'inconnues au compilateur. Si tu fixes la deuxième valeur, ça devrait passer.
    j'ai essayé de le faire (mikroC) les mêmes messages d'erreur.

    Citation Envoyé par eSb` Voir le message
    (mais du coup, on atteint ton tableau à deux dimensions que tu voulais éviter au début ; ))
    oui je sais mais puis qu'on a trouvé une façon de stocker tout sur le Rom ca devrait bien simplifier le programme ey j'aurai bien d'espace libre. donc pas la peine d'optimiser
    merci

  24. #54
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Citation Envoyé par Jack Voir le message
    Il est impossible d'effectuer une initialisation automatique avec [][], le compilateur a au moins besoin de connaitre une des 2 dimensions.
    J'ai essayé de préciser les deux dimensions mais c toujours le même problème.

  25. #55
    eSb`

    Re : Gestions des menus avec pic

    Pour moi, il manque simplement une accolade avant "Electrovannes" (sans corriger les fautes de frappe ; )) :
    Code:
      const char *menu[][6] = {
    {"Climat", "Tempèrature", "Humidité sol", "Lumlinosite"},
    {"Electrovannes" , "Voie 1", "Voie 2", "Voie 3", "Voie 4","Voie 5"},
    {"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumli"},
    {"Chodix methode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"}
    };
    Mais si tu veux, mon code est fonctionnel et te permet de mettre des menus de taille quelconque. (mais j'admets qu'il est plus tordu et moins évident à comprendre qu'un tableau à 2 dimensions).

    Et pour les ++x et x++ et compagnie, c'est juste une question d'habitude, ça devient plus clair et plus concis que x = x + 1 par ex.

  26. #56
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Citation Envoyé par eSb` Voir le message
    Pour moi, il manque simplement une accolade avant "Electrovannes" (sans corriger les fautes de frappe ; )) :
    Code:
      const char *menu[][6] = {
    {"Climat", "Tempèrature", "Humidité sol", "Lumlinosite"},
    {"Electrovannes" , "Voie 1", "Voie 2", "Voie 3", "Voie 4","Voie 5"},
    {"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumli"},
    {"Chodix methode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"}
    };
    Mais si tu veux, mon code est fonctionnel et te permet de mettre des menus de taille quelconque. (mais j'admets qu'il est plus tordu et moins évident à comprendre qu'un tableau à 2 dimensions).

    Et pour les ++x et x++ et compagnie, c'est juste une question d'habitude, ça devient plus clair et plus concis que x = x + 1 par ex.
    infiniment merci
    je posterai demain mon essai.
    merci encore une fois eSB

  27. #57
    invite2d9e7c03

    Re : Gestions des menus avec pic

    Bonjour,

    Enfin j'arrive à terminer une bonne partie de mon programme.

    Je pense qu'un tel listing sera utile dans l'archive du forum ( c'est vérifié et c'est bien fonctionnel ).

    J'ai besoin d'un petit coup de pouce pour la gestion du rétro éclairage(je comprend pas trop les astuces des timers)

    Arbre du menu:
    les dimensions sont à réviser..

    Code:
    const char *menu[6][6] = {
    {"Climat", "Temperature", "Humidite sol", "Luminosite"},
    {"Electrovannes" , "Voie 1", "Voie 2", "Voie 3", "Voie 4","Voie 5"},
    {"Seuils", "Seuil Temp", "Seuil Humi", "Seuil Lumi"},
    {"Choix methode", "Automatique", "Cycle 1", "Cycle 2", "Cycle 3"}
    };
    Valeurs donnés pour essais,ils seront lu à partir de l'eeprom

    Code:
    unsigned short temp = 11;//
    unsigned short hum = 22;//
    unsigned short lum = 33;//
    
    unsigned short seuil_temp = 10;//
    unsigned short seuil_hum = 20;//
    unsigned short seuil_lum = 30;//
    Code:
    char valeur_str[4];//valeur convertie en string de temp ou humi ou lumi
    
    unsigned short nbr_colonnes[]={3,5,3,4};//Pour chaque ligne
    action:
    0: rien
    1: activer/désactiver/accès au sous menus

    électrovannes: définit les états des sorties voie(i) correspond à electrovannes.Fi

    methode:
    0: automatique
    1: manuel
    2: cycle 1
    3: cycle 2
    3: cycle 3

    Code:
    unsigned short action,electrovannes,methode,k,j,i;
    Boutons de navigation

    Code:
    #define bp_in PORTB.F3
    #define bp_out PORTB.F4
    #define bp_up PORTB.F2
    #define bp_down PORTB.F1
    Fonction qui renvoie la longueur d'une chaine stockée en rom

    Code:
    char strlen_const(const char *pString)
    {
       char cCount = 0;
       while(*pString++)
       cCount++;
       return cCount;
    }
    Procédure qui reçoit une chaine de 16caracters aux maximum et la répartit sur 2 lignes (lcd 1*16) (le contrôleur de l'afficheur traite chaque 8 caractères comme ligne)

    Code:
    void    Lcd_2_lignes(const char *ecran)
    {
    LCD_CMD(LCD_FIRST_ROW);
     for ( k = 0; (k < 8) && (k < strlen_const(ecran)) ; k++ ) Lcd_CHR_CP(ecran[k])   ;
    LCD_CMD(LCD_SECOND_ROW);
     for ( k = 8; k < strlen_const(ecran) ; k++ ) Lcd_CHR_CP(ecran[k])    ;
    }
    Programme principal

    Initialisation

    Code:
    void    main()
            {
    //Initialisation:
    Lcd_Config(&PORTD, 7, 5, 6, 3, 2, 1, 0);
    Lcd_Cmd(Lcd_CLEAR) ;
    Lcd_Cmd(Lcd_CURSOR_OFF) ;
    i=0;
    j=0;
    action=0;
    electrovannes=0; //electrovannes initialement au repos
    methode=0; //mode automatique par défaut
    
    goto affichage;// pour le premier affichage menu(0,0)
    Attente d'un événement
    Code:
    attente:
    if (bp_down |bp_up|bp_in|bp_out) goto routine;
    goto attente;
    Routine de traitement renvoie la valeur de i , j et action

    Code:
        routine:
    
        if (bp_in) {
           if ((i==1 |i==3)&j>0){  //la ou il y'a des ON/OFF
              action=1;// activer / désactiver
           }else{
              j=1;
           }
        }
        
        if (bp_out) {
           if ((i==1 |i==3)&j>0){  //la ou il y'a des ON/OFF
              j=0;//menu parent
           }else{
              j=0;
           }
        }
    
        if (bp_down) {
           if (j==0) {//niveau 0
              i++; //menu suivant
              if (i>3){ // test de débordement
                  i=0;
              }
           }else{// sous menus
           j++;    //sous menu suivant
              if (j>nbr_colonnes[i]){ // test de débordement
              j=1;//premier sous menu
              }
           }
        }
        
        if (bp_up) {
           if (j==0) {//niveau 0
              if (i==0){ // test de débordement
                  i=3;
              }else{
                    i--; //menu précedant
              }
           }else{// sous menus
              if (j==1){ // test de débordement
                  j=nbr_colonnes[i];//dernier sous menu
              }else{
                  j--; //sous menu précedant
              }
           }
              
        }
    Mise à jour de l'affichage de menu

    Code:
    affichage:
            Lcd_Cmd(Lcd_CLEAR) ;
            Lcd_2_lignes(menu[i][j])  ;
    mise à jour de :
    -l'affichage des valeurs ou état
    -choix méthodes
    -états électrovannes

    Code:
    switch (i) {    //selon menu principal faire
        case 0:   //menu climat
          switch (j) {
            case 1:
                 ByteToStr(temp, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
            case 2:
                 ByteToStr(hum, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
            case 3:
                 ByteToStr(lum, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
          }
        break;
        case 1:   //menu elctrovannes
          switch (j) {
            case 1:
                 if (action==1& electrovannes.F1==0 & methode==1){//activation
                   electrovannes.F1=1;
                 }else if(action==1& electrovannes.F1==1& methode==1){// désactivation
                   electrovannes.F1=0;
                 }
                 if(electrovannes.F1==1){
                 lcd_out(2,7,"On");
                 }else{
                 lcd_out(2,6,"Off");
                 }
            break;
            case 2:// le changement d'état des electrovannes n'est permis qu'en mode manuel cad methode==1
                 if (action==1& electrovannes.F2==0 & methode==1){//activation
                   electrovannes.F2=1;
                 }else if(action==1& electrovannes.F2==1  & methode==1){// désactivation
                   electrovannes.F2=0;
                 }
                 if(electrovannes.F2==1){
                 lcd_out(2,7,"On");
                 }else{
                 lcd_out(2,6,"Off");
                 }
            break;
            case 3:
                 if (action==1& electrovannes.F3==0& methode==1){//activation
                   electrovannes.F2=1;
                 }else if(action==1& electrovannes.F3==1& methode==1){// désactivation
                   electrovannes.F3=0;
                 }
                 if(electrovannes.F3==1){
                 lcd_out(2,7,"On");
                 }else{
                 lcd_out(2,6,"Off");
                 }
            break;
            case 4:
                 if (action==1& electrovannes.F4==0& methode==1){//activation
                   electrovannes.F4=1;
                 }else if(action==1& electrovannes.F4==1& methode==1){// désactivation
                   electrovannes.F4=0;
                 }
                 if(electrovannes.F4==1){
                 lcd_out(2,7,"On");
                 }else{
                 lcd_out(2,6,"Off");
                 }
            break;
            case 5:
                 if (action==1& electrovannes.F5==0& methode==1){//activation
                   electrovannes.F5=1;
                 }else if(action==1& electrovannes.F5==1& methode==1){// désactivation
                   electrovannes.F5=0;
                 }
                 if(electrovannes.F5==1){
                 lcd_out(2,7,"On");
                 }else{
                 lcd_out(2,6,"Off");
                 }
            break;
          }
        break;
        case 2:   //menu seuil
          switch (j) {
            case 1:
                 ByteToStr(seuil_temp, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
            case 2:
                 ByteToStr(seuil_hum, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
            case 3:
                 ByteToStr(seuil_lum, valeur_str);
                 lcd_out(2,6,valeur_str);
            break;
          }
        break;
        
        case 3:   //menu methode : pour ce menu un seul choix est possible
          switch (j) {
            case 1:
                 if (action==1){//activation
                   methode=0;
                 }
                 if(methode==0){
                 lcd_out(2,7,"On");
                 }
            break;
            case 2:
                 if (action==1){//activation
                   methode=1;
                 }
                 if(methode==1){
                 lcd_out(2,7,"On");
                 }        break;
            case 3:
                 if (action==1){//activation
                   methode=2;
                 }
                 if(methode==2){
                 lcd_out(2,7,"On");
                 }        break;
            case 4:
                 if (action==1){//activation
                   methode=3;
                 }
                 if(methode==3){
                 lcd_out(2,7,"On");
                 }        break;
         }
        ; break;
      }
    Retour

    Code:
    action=0;// remettre l'ordre ;)
    // prévoir le déclenchement du rétro-éclairage
    // je vais prévoir une tempo ici pour anti rebond.
    goto attente;
    }
    @+

Page 2 sur 2 PremièrePremière 2

Discussions similaires

  1. deux barre d'outil avec deux menus démarrer : c'est possible ?
    Par invite30fe8374 dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 31/07/2008, 07h50
  2. PIC 16F8xx Aide....Menus LCD
    Par CED_TV_JVC dans le forum Électronique
    Réponses: 3
    Dernier message: 06/07/2008, 10h58
  3. Application à mettre en place pour la gestions des dechets
    Par invite0e72e517 dans le forum Environnement, développement durable et écologie
    Réponses: 6
    Dernier message: 16/04/2008, 14h21
  4. programmer des PIC avec un psion
    Par invite39462866 dans le forum Électronique
    Réponses: 15
    Dernier message: 18/10/2006, 06h37
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...