TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: zagoaristides 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.
-
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
-
Yo hice un menu para el lcd de mi insoladora (http://www.todopic.com.ar/foros/index.php?topic=24813.0) y para un probador de servos (http://www.todopic.com.ar/foros/index.php?topic=24937.0)
Mira el codigo, tal vez te sirva... aunque no utilizo ninguna libreria
Salu2
-
grandes proyectos si señor.... me han gustado mucho... felicidades...
-
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() --------------------------- \\\\
-
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....
-
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.