Autor Tema: Como crear un menú en un display LCD  (Leído 5489 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado zagoaristides

  • PIC12
  • **
  • Mensajes: 99
    • deportes de contacto y fitness
Como crear un menú en un display LCD
« en: 26 de Marzo de 2009, 00:03:13 »
Bueno, hace unos días estoy queriendo hacer un menú en un display. Mi idea original la pude hacer. Pero para lograr hacer un tipo librería que pueda servir a muchos estaría bueno compartir la mejor forma de hacerlo.

Algo que no puedo lograr hasta ahora es por ejemplo definir

char menu_prueba[3][16] = {"  Automatico","  Mecanico","  Manual"}; //sería lo que quiero escribir

Como el LCD puede ser de 2 Líneas con un par de botones arriba abajo los iría moviendo pasando la última línea a primera si bajo o visceversa si subo.

Luego para llamar a la función como habría que hacer?

Esto no me funciona:

presenta_menu (&menu_prueba[3][16], 16);

con la funcion definida como: void presenta_menu (char, int);

y comenzada como:

void presenta_menu (int *dir_menu[][16], int cant_palabras)


Agradezco ayudas.
Nadie nació sabiendo...Que genio ese Nadie!!!

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Como crear un menú en un display LCD
« Respuesta #1 en: 26 de Marzo de 2009, 18:16:25 »
mira yo utilizo la sentencia switch

while(200){
      if(!input(PIN_C5)|| !input(PIN_C5)){
         if(!input(PIN_C5)){ --menu; antirebote();}
         if(!input(PIN_C6)){ ++menu; antirebote();}
         if(menu>3) menu = 1;
         if(menu>1) menu = 0;
      }
      switch(menu){
               case 0: antirebote();
                     disable_interrupts(global);
                      lectura();
                     enable_interrupts(global);
                     printf(lcd_putc,"\f%2x-%2x-20%2x\n",dia,mes,anio);
                     printf(lcd_putc,"%2x:%2x:%2x",horas,minutos,segundos);
                     break;
               case 1: printf(lcd_putc, "\fajustar la hora?\n NO->+   SI->-");
                     delay_ms(50);
                     if(!input(PIN_C5)){
                        menu = 0;
                        ajuste_hora();
                     }
                     if(!input(PIN_C6)) menu = 0;
                     break;
               case 2: printf(lcd_putc, "\f tiempo seguridad\n %u segundos" contador2);
                     if(!input(PIN_C5)){ --contador2; antirebote();}
                     if(!input(PIN_C6)){ ++contador2; antirebote();}
                     if(contador2>24) contador2 = 24;
                     if(contador<1) contador2 = 1;   
                     tempo_relleno = contador2*50;
                     break;
      }

   }

depenediendo del valor de ""valor"" hara un caso u otro, facil y rapido
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Como crear un menú en un display LCD
« Respuesta #2 en: 26 de Marzo de 2009, 19:32:48 »
Yo hice un menu para el lcd de mi insoladora y para un probador de servos
Mira el codigo, tal vez te sirva... aunque no utilizo ninguna libreria
Salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Como crear un menú en un display LCD
« Respuesta #3 en: 26 de Marzo de 2009, 19:40:18 »
grandes proyectos si señor.... me han gustado mucho... felicidades...
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado zagoaristides

  • PIC12
  • **
  • Mensajes: 99
    • deportes de contacto y fitness
Re: Como crear un menú en un display LCD
« Respuesta #4 en: 27 de Marzo de 2009, 14:32:31 »
No me sirve ese tipo de menú. Cuando la cosa se complica son hojas y hojas de código solo para ocupar espacio. Te muestro algo que funciona y es aprox como tiene que quedar solo que la mayor parte quiero sustituirla por una función que tome un array que yo le diga y haga aprox. esto.

void menu_control(void)
{
char opc1, i, j, sumar;
signed char pulsa1 = -1;
char Arriba1, Abajo1, Enter1, Escape1;
const char num_pal1 = 3, num_let1 = 13, LCD_lines = 2;
char menu1[num_pal1][num_let1] = {"  Automatico","  Mecanico","  Manual"};

   lcd_putc("\f  Menu Control");
   delay_ms(200);

   
   for (;;)
   {
      Arriba1 = input (PIN_C1);
      Abajo1 = input (PIN_C2);
      Escape1 = input (PIN_C3);
      Enter1 = input (PIN_C0);
     
      if (!Arriba1 || !Abajo1 || pulsa1 == -1 || volver == 1)
      {
         if (pulsa1 == -1) pulsa1 = 0;
         if (!Arriba1)
            pulsa1 --;
         if (!Abajo1)
            pulsa1 ++;
         if (pulsa1 >= num_pal1)
            pulsa1 = num_pal1;
         if (pulsa1 < 0)
            pulsa1 = 0;
     
         lcd_putc("\f");
       
         sumar = 0;
         for (i = 0; i < LCD_lines; i++)
         {
            if (!Abajo1 && pulsa1 >= LCD_lines)   //si se va a escribir fuera del LCD
               sumar = 1;
               
            if (!Arriba1 && pulsa1 == 2)
               sumar = 1;             
               
               for (j=0; j<=num_let1; j++)   
                  printf (lcd_putc, "%c",menu1[i + sumar][j]);         
               
               opc1 = pulsa1;
                 
                  lcd_gotoxy(1,  pulsa1%2 + 1);
                  lcd_putc(">");

               if (i == 1) continue;
                  lcd_putc("\n");
         }
         
         delay_ms(400);
         volver = off;

      }
      if (!Enter1)
         
      if (!Escape1)
         volver = 2;
         
      if (volver == 2)
         break;
   }
   
} //// --------------------------- fin de la funcion menu_control() --------------------------- \\\\
Nadie nació sabiendo...Que genio ese Nadie!!!

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Como crear un menú en un display LCD
« Respuesta #5 en: 27 de Marzo de 2009, 20:05:35 »
No me sirve ese tipo de menú. Cuando la cosa se complica son hojas y hojas de código solo para ocupar espacio. Te muestro algo que funciona y es aprox como tiene que quedar solo que la mayor parte quiero sustituirla por una función que tome un array que yo le diga y haga aprox. esto.


que te refieres a las lineas de codigo que te he puesto yo?
creo que con tanto if y tantos anidamientos ese tipo de codigo es ilegible, segun mi punto de vista.... yo lo que utilizo son funciones, lo que pasa es que en el ejemplo no estan muy representadas por que no hera necesario, pero hay casos... como el de apagar las 10 bombas de agua ,separadas en el menu, para una mejor comprension del aparatejo.... en este ejemplo va  muy bien este tipo de codigo...

void bomba(num_bomba[ i ])
           if(!input(PIN_B0)){
                num_bomba[ i ] = ~num_bomba[ i ];
                delay_ms(130);
            }
            lcd_gotoxy(1,1);
            printf(lcd_putc, "numero bomba %u \n" i);
            printf(lcd_putc, "estado -> %u" num_bomba);
.
.
.

el resto de menu.....

case 4: bomba(i=1);
            break;
case 5: bomba(i= 2);
            break;
case 6: bomba(i = 3);
            break;
y asi sucesibamente....

creo que no te complicas mas de lo normal, y ya te digo.... son dependiendo de programas recomendables este tipo....
« Última modificación: 27 de Marzo de 2009, 20:10:22 por ppyote »
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado zagoaristides

  • PIC12
  • **
  • Mensajes: 99
    • deportes de contacto y fitness
Re: Como crear un menú en un display LCD
« Respuesta #6 en: 29 de Marzo de 2009, 22:53:01 »
Bueno dejo lo que logré que me sirve por cierto.

Tengo 4 botones (con pull up resistor o sea que cuando se presionan ponen la línea a masa) en el puerto C con los que comandaré los menúes. A saber:  Enter, Escape, Arriba y Abajo


----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
Primero definí las siguientes variables

char Vmenu_AB         = 0;
char Vmenu_A_A1_A2    = 1;
char Vmenu_A_A1_abc   = 2;
char Vmenu_A_A1_c     = 3;
char Vmenu_A_A2_abcd  = 4;
char Vmenu_A_A2_b     = 5;
char Vmenu_A_A2_c     = 6;
char Vmenu_A_A2_d     = 7;

char Vmenu_B_B1_B2_B3_B4_B5    = 8;
char Vmenu_B4_ab               = 9;
char Vmenu_B5_ab              = 10;

Luego los arrays que contienen lo que yo quiero mostrar en cada menú:

const char menu_AB[2][13]        = {"  Menu Ppal.","  Ajustes"};

const char menu_A_A1_A2[2][10]   = {"  Control","  Datos"};
const char menu_A_A1_abc[3][13]  = {"  Manual","  Mecanico","  Automatico"};
const char menu_A_A1_c[2][14]    = {"  Normal","  Inteligente"};

const char menu_A_A2_abcd[4][14] = {"  Turbiedad","  Temperatura","  Consumo","  Niv Tanque"};
const char menu_A_A2_b[3][10]    = {"  Externa","  Interna", "  Agua"};
const char menu_A_A2_c[3][10]    = {"  3 Meses","  Mensual", "  Semanal"};
const char menu_A_A2_d[2][13]    = {"  Porcentaje","  Litros"};

const char menu_B_B1_B2_B3_B4_B5[5][16]   = {"  Fecha y Hora","  Lim Turbiedad","  Limites Carga","  Volum. Tanque","  Control Ozono"};
const char menu_B4_ab[2][15]              = {"  Distribucion","  Cisterna"};
const char menu_B5_ab[2][13]              = {"  Activacion","  Tiempos"};


----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
Luego la funcion que me manejará todos los menúes (no la que los muestra)


void menu_principal (void)
{

char Enter1, Escape1;
char eleccion;
const char A=1, B=2, A1=1, A2=2, B1=1, B2=2, B3=3, B4=4, B5=5;
const char a=1, b=2, c=3, d=4;

   Escape1 = input (PIN_C3);
   Enter1 = input (PIN_C0);

   do
   {
      eleccion = elije_menu(Vmenu_AB);
      if (eleccion == A)   //Menu Principal
      {   
         eleccion = elije_menu(Vmenu_A_A1_A2);
         if (eleccion == A1)  //Control
         {
            eleccion = elije_menu(Vmenu_A_A1_abc);
            switch (eleccion)
               {
                  case a:  //lcd_putc("\fAct Ctrl. Manual");//activar control manual
                     break;
                  case b:  //lcd_putc("\fAct Ctrl. Mecan");//activar control mecánico
                     break;
                  case c:  //lcd_putc("\fAct Ctrl. Autom");//activar control automático
                     break;
               }
         }
         if (eleccion == A2) //Datos
         { 
            eleccion = elije_menu(Vmenu_A_A2_abcd);
            switch (eleccion)
            {
               case a: lcd_putc("\fMostrar Turb.");//mostrar Turbiedad
                  break;
               case b: lcd_putc("\fMostrar Temp.");//mostrar Temperaturas
                  break;
               case c: lcd_putc("\fMostrar Consum.");//mostrar Consumos
                  break;
               case d: lcd_putc("\fMostrar Niv. Tq.");//mostrar Niveles de Tanque
                  break;
            }
         }
      }       
      if (eleccion == B)   //Menu Ajustes
      {   
         eleccion = elije_menu(Vmenu_B_B1_B2_B3_B4_B5);
         switch (eleccion)
            {
               case B1: lcd_putc("\fAjust Fecha");//Ajustar Fecha y Hora
                  break;
               case B2: lcd_putc("\fAjust Lim Turb");//Ajustar Límite de turbiedad máximo
                  break;
               case B3: lcd_putc("\fAjust Lim Carg");//Ajustar Límites de carga de tanque
                  break;
               case B4: //Cilindico o Rectangular
                  eleccion = elije_menu(Vmenu_B4_ab);
                  if (eleccion == a) lcd_putc("\fCalc Vol Cil");//Calcular volumen de tanque cilíndrico
                  if (eleccion == b) lcd_putc("\fCalc Vol Rect");//Calcular volumen de tanque rectangular
                  break;
               case B5: //Control Ozono
                  eleccion = elije_menu(Vmenu_B5_ab);
                  if (eleccion == a) lcd_putc("\fAct Ozono");//Activar o desactivar Ozonizador
                  if (eleccion == b) lcd_putc("\fAjust Tiempos");//Ajustar Tiempos de Ozonizado
                  break;
            }
      }
     
   }while (!Escape1);
     
   delay_ms(500);

} //// -------------------------- fin de la funcion menu_principal() -------------------------- \\\\*/


----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
Ahora la función que muestra cada array de caracteres y devuelve la opción que se selecciona
en este caso de 1 a 5 pero podría hacer sido con más opciones con alguna pequeña modificación

char elije_menu (int menu)
{
char opc, i, sumar, num_pal, pulsa;
char Arriba, Abajo, Enter, Escape;
const char LCD_lines = 2;

   if (menu == Vmenu_AB || menu == Vmenu_A_A1_A2 || menu == Vmenu_A_A1_c ||
    menu == Vmenu_A_A2_d || menu == Vmenu_B4_ab || menu == Vmenu_B5_ab)
      num_pal = 2;
   if (menu == Vmenu_A_A1_abc || menu == Vmenu_A_A2_b || menu == Vmenu_A_A2_c )
      num_pal = 3;
   if (menu == Vmenu_A_A2_abcd )
      num_pal = 4;
   if (menu == Vmenu_B_B1_B2_B3_B4_B5 )
      num_pal = 5;
     
   pulsa = 0;
   for (;;)
   {
      Arriba = input (PIN_C1);
      Abajo = input (PIN_C2);
      Escape = input (PIN_C3);
      Enter = input (PIN_C0);
     
      if (!Arriba || !Abajo || pulsa == 0)
      {
         if (pulsa == 0) pulsa = 1; //solo para entrar la primera vez
         if (!Arriba)
            pulsa --;
         if (!Abajo)
            pulsa ++;
         if (pulsa > num_pal)
            pulsa = num_pal;
         if (pulsa < 1)
            pulsa = 1;
         
         lcd_putc("\f");
       
         sumar = 0;
         
         for (i = 0; i < LCD_lines; i++)
         {
            if (!Abajo && pulsa > 2 || !Arriba && pulsa == 2)   //si se va a escribir fuera del LCD
               sumar = 1;
            if (!Abajo && pulsa > 3 || !Arriba && pulsa == 3)   //si se va a escribir fuera del LCD
               sumar = 2;               
            if (!Abajo && pulsa > 4 || !Arriba && pulsa == 4)
               sumar = 3;             
               
            switch (menu)
            {
               case 0:
                  printf (lcd_putc, "%s",menu_AB[i + sumar]);
                  break;
               case 1:
                  printf (lcd_putc, "%s",menu_A_A1_A2[i + sumar]);
                  break;
               case 2:
                  printf (lcd_putc, "%s",menu_A_A1_abc[i + sumar]);
                  break;
               case 3:
                  printf (lcd_putc, "%s",menu_A_A1_c[i + sumar]);
                  break;
               case 4:
                  printf (lcd_putc, "%s",menu_A_A2_abcd[i + sumar]);
                  break;
               case 5:
                  printf (lcd_putc, "%s",menu_A_A2_b[i + sumar]);
                  break;
               case 6:
                  printf (lcd_putc, "%s",menu_A_A2_c[i + sumar]);
                  break;
               case 7:
                  printf (lcd_putc, "%s",menu_A_A2_d[i + sumar]);
                  break;
               case 8:
                  printf (lcd_putc, "%s",menu_B_B1_B2_B3_B4_B5[i + sumar]);
                  break;
               case 9:
                  printf (lcd_putc, "%s",menu_B4_ab [i + sumar]);
                  break;
               case 10:
                  printf (lcd_putc, "%s",menu_B5_ab[i + sumar]);
                  break;
            }

               opc = pulsa;

               if (i == 0)         
                  lcd_putc("\n");
         }
         
         //Pos de flecha con pulsa bajando  2:2(A >B), 3:2(B >C), 4:2(C >D), 5:2(D >E)
         //Pos de flecha con pulsa subiendo 1:1(>A B), 2:1(>B C), 3:1(>C D), 4:1(>D E)
         
         lcd_gotoxy(1,1);
         if (!Abajo)
            lcd_gotoxy(1,2);
         if (!Arriba)
            lcd_gotoxy(1,1);
                   
         lcd_putc(">");         
         
         delay_ms(delay_txt);
         //volver = off;

      }
         
      if (!Enter)
      {
         Enter = input (PIN_C0);
         //while (!Enter)
            delay_ms(anti_reb);
         
         return opc;
         break;
      }
      if (!Escape)
         break;
   }
} //// ---------------------------- fin de la funcion elije_menu() ---------------------------- \\\\*/


Con esto ya se pueden manejar muchísimos menúes que era lo que me interesaba para mi aplicación
que es un control de agua domiciliaria con varias funciones.

Luego algo más sencillo que puede ser útil es una función que elige entre si y no mostrando el menú
y devolviendo la opción seleccionada (1: Si   0:No)


char menu_si_no(void)
{
char Enter, Escape, Arriba, Abajo;
char opcion = 2;
      do
      {
         Arriba = input (PIN_C1);
         Abajo = input (PIN_C2);
         Escape = input (PIN_C3);
         Enter = input (PIN_C0);
         
         if (!Arriba)
         {
            lcd_putc("\n > Si       No");
            opcion = 1;
         }
         if (!Abajo || opcion == 2)
         {
            lcd_putc("\n   Si     > No");
            opcion = 0;
         }
         if (!Escape)
            break;
      }while (Enter);
     
   return opcion;
}


Ahora sigo con el proyecto, cuando lo termine lo posteo.
Nadie nació sabiendo...Que genio ese Nadie!!!


 

anything