Autor Tema: Menu 3 opciones con lcd 20x4  (Leído 8123 veces)

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

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #15 en: 06 de Junio de 2023, 04:11:01 »
 Hola Eduardo2 ,

Bueno he vuelto a compilar y crearlos de nuevo subo 2 ejemplos de RTC DS3231 ,en los 2 ejemplos me pasa lo mismo error I2C START(); y Temporizacion demasiado larga saliendo de el tiempo marcado iluminación lcd.
He añadido las librerías que utilizo DS3231.c e I2C.c . Creo que es lo que me comentabas para debuggear errores. 
* prueba I2C DS3231_LCDilumina_b.zip
(41.42 kB - descargado 122 veces)
 
* prueba I2C DS3231_LCDilumina_b.zip
(41.42 kB - descargado 122 veces)
« Última modificación: 06 de Junio de 2023, 04:15:46 por genti »

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #16 en: 06 de Junio de 2023, 13:17:38 »
... Bueno antes que una opción es una función que es la de pulsar un botón y que se ilumine el LCD durante unos segundos o minutos y luego este apagado en reposo esto debería funcionar independientemente de en que parte del Menú este ,he realizo una funcion(void) y llamo a esta "funcion" desde el menú principal o desde cualquier opción , solo pulsando un botón en este caso a nivel hardware lo tengo asignado en puerto" B7 " (input) y puerto "A5" (Output) hacia pines LCD. La duración del tiempo que permanece encendido el lcd la he puesto en 20 segundos y luego se apague pero por alguna razón no me realiza bien el bucle de temporización ya que me mantiene el lcd encendido
En el código que subiste en funcion_ilumina_lcd() tenés un while(true)  --> no sale jamás de ahí.

Pero funciones que deben ejecutarse independientes del resto es preferible que entren por interrupción.

Por ejemplo:  Programando el Timer 2 para que genere una interrupción cada 10ms
Código: [Seleccionar]
// en main()
   setup_timer_2(T2_DIV_BY_16,125,5); //2.0 ms overflow, 10.0 ms interrupt
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);

y usando una interrupción de este estilo:
Código: [Seleccionar]
#INT_TIMER2
void  TIMER2_isr(void) {       
static int16 Tilum = 0 ;        // Tiempo maximo 11minutos
                                // si hace falta mas se usa int32
    if(Tilum){
        if(!--Tilum) 
            output_low (PIN_A5) ;   // APAGA LCD
    }
    if (input(PIN_B7) == 1){
        output_high (PIN_A5);   // ENCIENDE LCD
        Tilum = 100.*20  ;      // Activa el display por 20"
    }                           // Resetea la cuenta si está encendido

Te olvidás de andar insertando en el resto del código llamados que enciendan (y apaguen) el display


Por otro lado, en tu código debe ir primero #use i2c  y después #include "DS3231.c"
Código: [Seleccionar]
#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)
#include "DS3231.c"

Citar
.. llevo varios días intentando que me funcione pero no domino el tema de I2C, ya que trabaja con SCL y SDA que lo tengo asignado por hardware al Pin B0 y B1 del pic18f2550 .
En principio es suficiente que SCL y SDA tengan una resistencia de pullup

Esto es de acuerdo al contenido de prueba I2C DS3231_LCDilumina_b.zip  , al otro no lo revisé.

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #17 en: 07 de Junio de 2023, 19:19:26 »
Hola Eduardo2 ,

He cogido , "contenido de prueba I2C DS3231_LCDilumina_b.zip" el otro fichero que te envié tiene el mismo problema del I2C ,pero de momento no lo he corregido y no lo he probado .Ya que de momento me centrare en este . La verdad es que una tontearía como cambiar el orden a la hora de llamar o declarar sentencias hace que el programa no funcione y solo con el cambio :

#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)
#include "DS3231.c"
 
Ya me compilaba bien. Y al elegir en menú 1 ya podía ver fecha, hora y temperatura. Y yo me había pasado horas mirando porque me daba fallo al compilar y no encontraba solución. Y gracias a ti ya me funciona.

Sobre el tema de la temporización , te agradezco la puntualización sobre el tema de entrar por  interrupción y no tener que estar haciendo llamadas desde cada parte del código para activar en este caso la iluminación del lcd. Un compañero de trabajo me comento de utilizar el tema de temporización por TIMER pero nunca he sabido aplicarlo correctamente y solo se me ocurría por bucle  "FOR ..." y la verdad es que en otro programa lo había echo y me funciono perfectamente y hora no me funcionaba. Pero con el código del TIMER2 ahora es mas cómodo y exacto en los tiempos y no detiene el funcionamiento normal del programa.
Si que me he fijado que cuando entro en cada opción si no pongo un delay_ms (xxxx); varios segundos , entro y  se sale automáticamente al menú principal y me gustaría que solo saliera al menú cuando pulsara el botón A2(ENTER) . He estado mirando la manera de hacerlo pero no encuentro forma de que se quede dentro de la opción . Como podría arreglarlo ? En el codigo "I2C DS3231_LCDilumina_b.zip" te puede servir porque hay aparecen delays dentro de las opciones .

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #18 en: 07 de Junio de 2023, 22:16:32 »
... La verdad es que una tontearía como cambiar el orden a la hora de llamar o declarar sentencias hace que el programa no funcione y solo con el cambio :

#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)
#include "DS3231.c"
Tiene su motivo, DS3231_STREAM se define en #use i2c , después lo usa DS3231.c y si no estaba definido...

Citar
Si que me he fijado que cuando entro en cada opción si no pongo un delay_ms (xxxx); varios segundos , entro y  se sale automáticamente al menú principal y me gustaría que solo saliera al menú cuando pulsara el botón A2(ENTER) . He estado mirando la manera de hacerlo pero no encuentro forma de que se quede dentro de la opción . Como podría arreglarlo ? En el codigo "I2C DS3231_LCDilumina_b.zip" te puede servir porque hay aparecen delays dentro de las opciones .
Lo acostumbrado es que tengas mas botones para moverte en el menú, por ejemplo: dos a modo de cursor (arriba y abajo) y dos para validación y volver al menú anterior, aunque la vuelta al menú anterior puede ser otra opción de la lista.
Si querés usar el botón A2 vas a tener que meter delays antes de monitorear A2 pues el botón de entrar es el mismo que para salir.

Como las tareas seleccionadas, además de una acción puede ser desplegar otros menúes cuyo bucle va a ser similar al del bucle principal, por legibilidad te conviene que las acciones sean llamados a procedimientos.
Algo asi:
Código: [Seleccionar]
#include <18F2550.h>
#FUSES XT,NOWDT
#use delay(crystal=4000000)     // reloj a 4 MHz.

#use standard_io(A)
#define BUTTON_UP_PIN    PIN_A1
#define BUTTON_ENTER_PIN PIN_A2
#define BUTTON_EXIT_PIN  PIN_A2

#use i2c(Master,fast,sda=PIN_B0,scl=PIN_B1,force_sw,STREAM=DS3231_STREAM)
#include "DS3231.c"

#include "LCD420_v2.C"

int horas=0,minutos=0,segundos=0,dia=0,mes=0,anio=0;
signed int16 temperatura=0;
char grados=223; //simbolo °
RTC_Time *reloj;

#define MENU_OPTION_COUNT 3
char* menuOptions[MENU_OPTION_COUNT]= {"Opcion 1","Opcion 2","Opcion 3"};

//=====================================================================

#define Ton  (100.*20)          // Tiempo de 20"
                                // Tiempo maximo 11minutos
                                // si hace falta mas se usa int32
#INT_TIMER2
void  TIMER2_isr(void)
{
    static int16 Tilum = Ton ;

    if(Tilum){
        if(!--Tilum)
            output_low(PIN_A5); // APAGA LCD
    }
    if (input(PIN_B7) == 1){
        output_high(PIN_A5);    // ENCIENDE LCD
        Tilum = Ton        ;    // Activa el display por 20"
    }                           // Resetea la cuenta si está encendido
}

//=====================================================================

void displayMenu(int8 select) {

    lcd_putc('\f');  // Limpiar la pantalla

    lcd_gotoxy(1, 1);  printf(lcd_putc, "Seleccione opcion:");

    for(int8 k=0;k<3;k++){
        lcd_gotoxy(1, k+2);
        if (select == k)
            printf(lcd_putc, "> %s", menuOptions[k]);
        else
            printf(lcd_putc, "  %s", menuOptions[k]);
    }
}
//=====================================================================

void reloj_lcd()
{
   lcd_gotoxy(1,2); printf(LCD_PUTC,"%02u:%02u:%02u  %Ld%cC",horas,minutos,segundos,temperatura,grados);
   lcd_gotoxy(1,3); printf(LCD_PUTC,"%02u/%02u/%02u",dia,mes,anio);
}
//=====================================================================

void proc_Opcion1(){
    reloj = RTC_Get();
    horas = reloj->hours;
    minutos = reloj->minutes;
    segundos = reloj->seconds;
    dia = reloj->day;
    mes = reloj->month;
    anio = reloj->year;

    temperatura = Get_Temperature()/100;
    reloj_lcd();

    delay_ms(500) ;
    while(input(BUTTON_EXIT_PIN)==0);
}

void proc_Opcion2(){
    lcd_gotoxy(3, 3);
    printf(lcd_putc, "pruebas ...");

    delay_ms(500) ;
    while(input(BUTTON_EXIT_PIN)==0);
}

void proc_Opcion3(){
    lcd_gotoxy(3, 3);
    printf(lcd_putc, "Mas pruebas ...");

    delay_ms(500) ;
    while(input(BUTTON_EXIT_PIN)==0);
}
//=====================================================================

void main() {

   lcd_init();
   lcd_putc('\f');      // Limpiar la pantalla inicialmente
   delay_ms(100);

   set_tris_c(0) ;

   setup_timer_2(T2_DIV_BY_16,125,5);   // 2.0 ms overflow, 10.0 ms interrupt
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);

   displayMenu(0);

   while (TRUE) {
      static signed int selectedOption = 0 ;

      if (input(BUTTON_UP_PIN)) {
         selectedOption--;
         if( selectedOption < 0)  selectedOption = MENU_OPTION_COUNT - 1;
         displayMenu(selectedOption);
         delay_ms(250);     // AntiRebote
      }

      if (input(BUTTON_ENTER_PIN)) {
         lcd_putc('\f');
         lcd_gotoxy(1, 1);
         switch (selectedOption) {

            case 0:
                printf(lcd_putc,"Opcion 1 seleccion");
                proc_Opcion1() ;
                break;

            case 1:
                printf(lcd_putc, "Opcion 2 seleccion");
                proc_Opcion2() ;
                break;

            case 2:
                printf(lcd_putc, "Opcion 3 seleccion");
                    proc_Opcion3() ;
               break;
         }
         displayMenu(selectedOption);
         delay_ms(500);     // AntiRebote
      }
   }
}



Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #19 en: 10 de Junio de 2023, 11:09:59 »
Hola Eduardo2,

gracias, por reorganizar el código. Lo he testeado y funciona correctamente . El tema de los botones es cierto normalmente se suele hacer con 3 o mas botones arriba, abajo, entrar y salir en Menús . Pero yo lo quería lo mas simplificado posible aunque eso implica que a la hora de programar pueda ser mas complejo o no puedas llegar a hacerlo . Pero recuerdo que en algún foro o video llegue haber una vez que con 2 botones se podía y me propuse adaptar esa forma aunque mis conocimientos de programación son escasos ,siempre intento realizarlo. Y en este caso he empezado el  por hardware y luego he seguido por el software.
Y gracias a tu ayuda estoy pudiendo tirar hacia adelante el proyecto.

Ahora estoy trabajando en implementar Opción 2 y 3 del  Menú .Que básicamente harán lo mismo pero para apartados distintos, monitorización . Haber que tal me sale . En breve te informo ...

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #20 en: 15 de Junio de 2023, 20:07:25 »
Hola Eduardo 2 ,
He añadido en la opción 2 , la función de voltimetro y amperimetro ,incluido potencia  la lectura del puerto AN3 y AN4 .Es para volti. y amper. Pero al declarar en Void Main , los puertos adc me encuentro que poniendo la sentencia  " setup_adc_ports(ALL_ANALOG);" Me bloquea por completo el Menú , no puedo seleccionar nada solo reacciona el boton de iluminación del lcd .
Entonces he decido cambiar la sentencia y Poner setup_adc_ports(AN3_AN4_ANALOG); y setup_adc_ports(AN3_AN4); y al compilar da error  de definición en an3 y an4. He estado buscando información y he encontrado unas tablas donde hay combinaciones de puertos para esta sentencia . Y estaba esta pero a mi me da error . Si quito es declaración compila bien y puedo acceder al Menú y ver monitorizar la lectura  Voltios,Corriente,Potencia. Aunque no he conectado nada todavía a esos puertos pero recibo lectura. También he podido comprobar que como he metido el programa en un bucle infinito . No puedo salir al menú principal y si meto dentro del bucle la petición de pulsar botón exit (salida a menú principal ) .la opción
* fichero_menu.zip
(148.6 kB - descargado 117 veces)
  2 se queda con una lectura no fluctúa y solo lo hace cuando pulso botón exit pero no se sale al menú principal.
También he podido observar que en la opcion 1 que es la del sensor DS3231 . No me marca la hora ni los minutos ni segundos reales y la fecha tan poco. Es decir cuando entro en la opcion los segundos deberían moverse y a los 60 seg. debería marcar 1 minuto y  así sucesivamente y la fecha debería ser la actual y no marca nada . Todo esto previo a poner en hora y fecha en la declaración de variables para que coja un tiempo real y a partir de hay empiece a funcionar . El sensor le he puesto pila cr2032 para que cuando apague el circuito siga funcionando, y si mantiene tiempo y fecha pero creo que es porque no esta cogiendo los valores de la declaración. He probado a salir al menú principal y luego entrar y cada vez que salgo y entro los segundos corren pero si me quedo dentro la hora se queda estática. Es como si se parase la lectura instantánea pero el sensor internamente siguiera funcionando pero no muestra el avance. No se porque pasa esto. No se que puede pasar . Haber si puedes echar una mano.  Gracias de antemano.
Pongo el fichero fuente .Para debugear.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #21 en: 16 de Junio de 2023, 10:17:19 »
Hola Eduardo 2 ,
He añadido en la opción 2 , la función de voltimetro y amperimetro ,incluido potencia  la lectura del puerto AN3 y AN4 .Es para volti. y amper. Pero al declarar en Void Main , los puertos adc me encuentro que poniendo la sentencia  " setup_adc_ports(ALL_ANALOG);" Me bloquea por completo el Menú , no puedo seleccionar nada solo reacciona el boton de iluminación del lcd .
Entonces he decido cambiar la sentencia y Poner setup_adc_ports(AN3_AN4_ANALOG); y setup_adc_ports(AN3_AN4); y al compilar da error  de definición en an3 y an4. He estado buscando información y he encontrado unas tablas donde hay combinaciones de puertos para esta sentencia .

Las entradas analógicas van en secuencia, no pueden ser cualquiera.
Las combinaciones son AN0, AN0_TO_ AN1, AN0_TO_ AN2, AN0_TO_ AN3, AN0_TO_ AN4 ...
Es decir, si necesitás que AN3 y AN4 sean analógicas --> AN0,AN1 y AN2 también lo será.

Esto no suele ser problema porque se tiene en cuenta a la hora de asignar los pines, pero si ya tenés hecho el circuito impreso...  --> Imaginación o trincheta.

Citar
También he podido observar que en la opcion 1 que es la del sensor DS3231 . No me marca la hora ni los minutos ni segundos reales y la fecha tan poco. Es decir cuando entro en la opcion los segundos deberían moverse y a los 60 seg. debería marcar 1 minuto y  así sucesivamente y la fecha debería ser la actual y no marca nada .
Es que en ese código se lee el DS3231 una sola vez, luego se queda esperando. Si querés leer continuamente el DS3231 tenés que escribir algo así:
Código: [Seleccionar]
    do{   
        reloj = RTC_Get();
        horas = reloj->hours;
        minutos = reloj->minutes;
        segundos = reloj->seconds;
        dia = reloj->day;
        mes = reloj->month;
        anio = reloj->year;
        temperatura = Get_Temperature()/100;
        reloj_lcd();                 
 
        delay_ms(500)) ;
    } while(input(BUTTON_EXIT_PIN)==0);   
Es un ejemplo, tiene la molestia del delay_ms(500), que hace que tengas que mantener pulsado como máximo 500ms para que lo lea.



Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #22 en: 19 de Junio de 2023, 19:06:08 »
Hola Eduardo2,
Con respecto a la tabla para definir los puertos analógicos de entrada en efecto tiene que ser una secuencia según tabla ,pero estoy siguiendo esa correlación y me sigue dando error a la hora de compilar por poner un ejemplo he puesto :
 setup_adc_ports(AN0_AN1_AN2); . Y si pongo todos los puertos a ALL ANALOG , no se porque motivo me bloquea el Menú y no responde ningún botón del menu .Solo el botón que me enciende  el LCD . Una sugerencia , si elimino este comando los puertos analógicos funcionarían de forma correcta ? O por lo contrario es necesario que este esta función .
El problema es que ya tengo echo la placa de circuito impreso , con los componentes montados y funcionando. Cuando lo diseñe en su día tuve que imaginar que puertos analógicos y que digitales podría llegar a utilizar he hice la distribución pensando en sus entradas y funcionalidades del pic 18f2550 y entre lo que utiliza el LCD y reservar puerto como USB. Y añadir botoneras que sea lo mas simplificado posible . No me da mucho margen para trabajar ...
En la opción 3 del menú ira el mismo código que en la opción 2 pero con otros 2 puertos analógicos distintos ya que monitorizare otra función de la rama de la placa de circuito impreso .  Pero antes he de solucionar la opción 2 y dejarla funcional .
Pero a pesar de todo esto va saliendo . En este apartado de monitorización he añadido la sentencia Do { , como en el ejemplo que has echo con lo del DS3231 y las lecturas de tensión ,amperios y potencia lo hace cada 500 ms y si aprieto botón exit sale al menú principal aunque no lo hace de forma inmediata al pulsar lo hace al cabo de unos segundos .

Por otra parte he probado el código que me has puesto del sensor ds3231 y ahora si realiza la lectura cada 500 ms pero sigo sin tener la fecha y la hora actualizada no coge el valor de la variable que le pongo en la declaración . Y no entiendo porque ya que en la declaración le indico hora ,minuto, segundo y fecha .Pero no se porque motivo no lo esta cogiendo.
Si necesitas que te pase el código con los errores dímelo ...  porque como sigo probando y para no liarte.
Saludos.


Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #23 en: 20 de Junio de 2023, 18:12:43 »
Con respecto a la tabla para definir los puertos analógicos de entrada en efecto tiene que ser una secuencia según tabla ,pero estoy siguiendo esa correlación y me sigue dando error a la hora de compilar por poner un ejemplo he puesto :
 setup_adc_ports(AN0_AN1_AN2); .
Es que el símbolo AN0_AN1_AN2 no está definido.
O lo definís vos o usás los que tiene definidos, en este caso sería AN0_TO_AN2.
Los demás símbolos los podés ver en ..\Devices\18F2550.h

Citar
Y si pongo todos los puertos a ALL ANALOG , no se porque motivo me bloquea el Menú y no responde ningún botón del menu .Solo el botón que me enciende  el LCD
El el datasheet del 18F2550 se lee claramente que cuando configurás un pin como entrada analógica te deshabilita la lectura digital.

Citar
Por otra parte he probado el código que me has puesto del sensor ds3231 y ahora si realiza la lectura cada 500 ms pero sigo sin tener la fecha y la hora actualizada no coge el valor de la variable que le pongo en la declaración . Y no entiendo porque ya que en la declaración le indico hora ,minuto, segundo y fecha .Pero no se porque motivo no lo esta cogiendo.
No puedo saber como lo estás declarando, si yo inicializo el reloj con:
Código: [Seleccionar]
//   Set reloj ;
   c_time.hours  = 23 ;
   c_time.minutes= 59 ;
   c_time.seconds= 40 ;
   c_time.day    = 31 ;
   c_time.month  = 12 ;
   c_time.year   = 23 ;
   
   RTC_Set(&c_time) ;
Lo inicializa lo mas bien e incrementa los registros a los 20" (como corresponde :) )

Citar
Si necesitas que te pase el código con los errores dímelo ...
Siempre es mejor acompañar con el código que se estaba usando + los necesarios para compilar + archivo de simulación si se está usando.

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #24 en: 21 de Junio de 2023, 19:56:09 »
Hola Eduardo2 ,

He estado probando el código :
//   Set reloj ;
   c_time.hours  = 23 ;
   c_time.minutes= 59 ;
   c_time.seconds= 40 ;
   c_time.day    = 31 ;
   c_time.month  = 12 ;
   c_time.year   = 23 ;
   
   RTC_Set(&c_time) ;
Lo inicializa lo mas bien e incrementa los registros a los 20" (como corresponde :) )

Lo he colocado dentro de la opción 1 y dentro del bucle "Do" ...
Y ahora si coge la fecha y la hora pero no contabiliza minutos y segundos se queda estático. He probado aunque salga al menú principal y entre de nuevo parece que contabiliza pero vuelve a quedarse estático. He probado a modificar la llamada que realiza antes del void Main   :    RTC_Time *reloj;     para adaptarlo al código que me has pasado pero algo no hago bien y me da error . Lo he dejado como lo tenia al principio pero añadiendo solo tu código . Y no encuentro la forma de que funcione ...  Haber si puedes sacarme del atasco porque debe ser una tontearía .

Por otro lado he consultado el fichero   \Devices\18F2550.h y  he verificado la tabla para definir los puertos analógicos y tal y como dices ha de ser combinaciones . He podido añadir una combinación
* fichero_menu_.zip
(172.85 kB - descargado 110 veces)
  . setup_adc_ports(AN0_TO_AN3); y he conseguido que al compilar me funcione , pero hacia que el menú al pulsar A1 O A2 botones de subir/bajar y enter . No funcionaban se quedaba Menú bloqueado. Y se me ha ocurrido cambiar esos 2 pines por otro puerto y pasarlos a C6 (SUBIR/BAJAR) C7 (ENTER/SALIR) y me ha funcionado perfectamente a si libero los puertos de A0 a A3 .Pero según el datasheet del pic 18f2550 el puerto A4 es digital y mi pregunta es : puedo convertirlo a analógico ? y como lo puedo definir ? para que lo vea como analógico . Esto si se pudiera me serviría para poder aplicarlo a otros puertos que me quedan libres y son digitales.
Adjunto fichero comprimido con la modificaciones comentadas . Gracias . Un saludo.
 

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #25 en: 21 de Junio de 2023, 22:57:49 »
...Lo he colocado dentro de la opción 1 y dentro del bucle "Do" ...
Y ahora si coge la fecha y la hora pero no contabiliza minutos y segundos se queda estático.
:shock:  Cómo no se va a quedar estático si en cada iteración se vuelve a programar la hora!
Eso tenía que ir en main() junto con las demás inicializaciones.
Por otro lado eso es para pruebas, porque vas a necesitar una rutina de puesta en hora.

Citar
...He podido añadir una combinación  - Tienes que ingresar para ver archivos adjuntos -   . setup_adc_ports(AN0_TO_AN3); y he conseguido que al compilar me funcione ,
La corriente la estás leyendo en AN4 --> debió ser: setup_adc_ports(AN0_TO_AN4);

Citar
pero hacia que el menú al pulsar A1 O A2 botones de subir/bajar y enter . No funcionaban se quedaba Menú bloqueado. Y se me ha ocurrido cambiar esos 2 pines por otro puerto y pasarlos a C6 (SUBIR/BAJAR) C7 (ENTER/SALIR) y me ha funcionado perfectamente a si libero los puertos de A0 a A3 .Pero según el datasheet del pic 18f2550 el puerto A4 es digital y mi pregunta es : puedo convertirlo a analógico ? y como lo puedo definir ? para que lo vea como analógico .
Lo  que tenés que hacer es consultar el datasheet.
El pin A4  es solo digital, pero el pin analógico AN4 está en el pin A5
 

* 18f2550.jpg
(44.17 kB, 600x277 - visto 320 veces)

Lo único que tenés que hacer es cambiar la salida que usabas para encender el display PIN_A5 por PIN_A4  e ingresar la lectura de corriente por el PIN_A5 (AN4 como analógico)

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #26 en: 29 de Junio de 2023, 20:40:05 »
Hola Eduardo2 ,
 
El pin A4  es solo digital, pero el pin analógico AN4 está en el pin A5
 
*
18f2550.jpg

(44.17 kB, 600x277 - visto 24 veces)

Lo único que tenés que hacer es cambiar la salida que usabas para encender el display PIN_A5 por PIN_A4  e ingresar la lectura de corriente por el PIN_A5 (AN4 como analógico)

Haciendo referencia a lo anterior da la casualidad que el PIN_A5 ya lo tengo ocupado con la salida hacia la iluminación del lcd por hardware. Ósea que en el diseño de la placa PCB lo tengo ya ocupado así que ya veré como soluciono los pines analogicos. Entendiendo que los pines digitales no los puedo a utilizar como analógicos ( si me equivoco corrígeme).

Por otro lado he implementado tu codigo en el Main Void ,  ;
//   Set reloj ;
   c_time.hours  = 23 ;
   c_time.minutes= 59 ;
   c_time.seconds= 40 ;
   c_time.day    = 31 ;
   c_time.month  = 12 ;
   c_time.year   = 23 ;
   
   RTC_Set(&c_time) ;

Y después de corregir fecha y hora ,al comprobar en menu comienza desde los datos que le he proporcionado . Luego he comentado la linea    RTC_Set(&c_time) ; PARA que no volviera a coger datos y ya he conseguido que el reloj cuente correctamente .En el fichero adjunto igual lo veras claro . He estado buscando alguna sentencia para adaptarla y hacerlo mejor pero no he sabido adaptar código y lo que he encontrado es para Arduino o el código para el pic se hacia complejo para mi comprensión y lo he dejado tal y como tu me lo has puesto. No se si hay  alguna manera de que lo coja (fecha y hora ) de forma automática aunque yo quite la pila. Ya me dirás.

También he añadido en la opción 3 la monitorización de otra tension y corriente . He estado comprobando las lecturas en puertos analógicos y parece que realiza bien la lectura son bastante reales. Por hay creo que lo tengo solucionado aunque seguiré con las pruebas.

Por otra parte He añadido otro sensor de temperatura DS18B20 . He estado realizando varias pruebas y tengo algunos problemas .Este sensor seria temperatura exterior . Mi intención es que se visualice dentro de la opcion 1 junto a la temperatura del DS3231. Pero no consigo que me la temperatura correcta . He creado en void Main los parámetros para que actualice constantemente y que luego visualice dentro de opcion 1 el resultado. Pero me da 51 grados o cualquier otro valor y no es real ya que el ds3231 me da 29 grados(este si es real). Y estado haciendo varios cambios pero no consigo cambiarlo. Por hardware lo tengo bien configurado , he creado incluso una subrrutina para que fuese llamada desde cualquier punto del código .Pero he tenido multitud de fallos a la hora de llamarla en distintos sitios y e desistido . Al final lo he dejado como esta actualmente en el fichero adjunto se vera . No se como podria solucionarlo ...
Adjunto fichero comprimido . Gracias de antemano.
 

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #27 en: 30 de Junio de 2023, 13:39:44 »
....
Haciendo referencia a lo anterior da la casualidad que el PIN_A5 ya lo tengo ocupado con la salida hacia la iluminación del lcd por hardware. Ósea que en el diseño de la placa PCB lo tengo ya ocupado así que ya veré como soluciono los pines analogicos. Entendiendo que los pines digitales no los puedo a utilizar como analógicos ( si me equivoco corrígeme).
No, pero mientras la lectura del ADC se haga siempre dentro del menú, podés declarar:
Código: [Seleccionar]
    setup_adc_ports(AN0_TO_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);
al ingresar en la opción, y
Código: [Seleccionar]
setup_adc_ports(NO_ANALOGS) ;al salir.



Citar
...He estado buscando alguna sentencia para adaptarla y hacerlo mejor pero no he sabido adaptar código y lo que he encontrado es para Arduino o el código para el pic se hacia complejo para mi comprensión y lo he dejado tal y como tu me lo has puesto. No se si hay  alguna manera de que lo coja (fecha y hora ) de forma automática aunque yo quite la pila.
:o Si sacás la pila se pierde la hora, necesitás un menú de servicio donde se la pueda escribir.

Citar
Por otra parte He añadido otro sensor de temperatura DS18B20 . He estado realizando varias pruebas y tengo algunos problemas .Este sensor seria temperatura exterior . Mi intención es que se visualice dentro de la opcion 1 junto a la temperatura del DS3231. Pero no consigo que me la temperatura correcta . He creado en void Main los parámetros para que actualice constantemente y que luego visualice dentro de opcion 1 el resultado. Pero me da 51 grados o cualquier otro valor y no es real ya que el ds3231 me da 29 grados(este si es real). Y estado haciendo varios cambios pero no consigo cambiarlo. Por hardware lo tengo bien configurado , he creado incluso una subrrutina para que fuese llamada desde cualquier punto del código .Pero he tenido multitud de fallos a la hora de llamarla en distintos sitios y e desistido . Al final lo he dejado como esta actualmente en el fichero adjunto se vera .
Adjunto fichero comprimido .

- Ponés el #include "ds18b20.c"  al principio el el pin a usar lo declarás después (Como el pin no está definido usa A5 por defecto). 
Los compiladores no son como las madres, a ellos no les interesa que fué lo que realmente quisiste escribir. 

Además el nombre es PIN_DS18B20_DATA, no DS18B20_PIN
Debiste escribir:
Código: [Seleccionar]
#define PIN_DS18B20_DATA PIN_A0
#include "ds18b20.c"

Pero si vas a usar PIN_A0, como te dije antes el puerto debe estar como digital.


- Leés mal el sensor.
Código: [Seleccionar]
   sensor =ds18b20_read(0);
   temper = (ds18b20_read(DS18B20_PIN), &value);  //Lee el sensor
:shock:  Sólo Dios sabe de donde sacaste eso.  El argumento de  ds18b20_read es una dirección de memoria no una constante y la 2da línea es un auténtico misterio.
Código: [Seleccionar]
float temper;
signed int16 value;
.................................
.................................
.................................
    ds18b20_read(&value) ;
    temper=value/16. ;      // Leer datasheet del DS18B20

----------------------------------------------------------

Adjunto un ejemplo con las modificaciones.
« Última modificación: 30 de Junio de 2023, 19:14:31 por Eduardo2 »

Desconectado genti

  • PIC10
  • *
  • Mensajes: 28
Re:Menu 3 opciones con lcd 20x4
« Respuesta #28 en: 06 de Julio de 2023, 17:46:04 »
Hola Eduardo2 ,

 He revisado el código del fichero adjunto y no entiendo el significado de estas 2 líneas .

#define CPU_MHZ 4
#define delay_ms_break(t_ms,pinx)  for(int32 n=15.46*CPU_MHZ*t_ms ; !input(pinx) && n>0 ; n--)

que significado tienen o que hace ?  :shock:

Por otro lado gracias a tu corrección sobre el sensor DS18B20 ahora ya me lee bien la temperatura . Y lo que comentas :
- Leés mal el sensor.
Código: [Seleccionar]
   sensor =ds18b20_read(0);
   temper = (ds18b20_read(DS18B20_PIN), &value);  //Lee el sensor

 Sólo Dios sabe de donde sacaste eso.  El argumento de  ds18b20_read es una dirección de memoria no una constante y la 2da línea es un auténtico misterio.

Lo deduje de buscar en libros que tengo sobre programación o por internet algunos ejemplos . Pero esta claro que no supe hacerlo bien . Y gracias a ti se ha podido corregir.

También he realizado un cambio el pin A0 que es donde en un principio entraba el dato de la lectura de sensor ds18b20 , lo he cambiado a un pin digital : B6 y parece que funciona sigue leyendo la temperatura correctamente. Si sigue FUNCIONANDO lo dejare así y ganare otro pin analógico .
#define PIN_DS18B20_DATA PIN_B6

Sobre lo que comentas a continuación :

No, pero mientras la lectura del ADC se haga siempre dentro del menú, podés declarar:
Código: [Seleccionar]
    setup_adc_ports(AN0_TO_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);
al ingresar en la opción, y
Código: [Seleccionar]
setup_adc_ports(NO_ANALOGS) ;
al salir.

Entiendo que si pongo estas líneas de comando dentro de Menú y la otra linea al salir podría, utilizar un Pin digital  . Creo que es lo que me quieres explicar ? Perdona mi torpeza a la hora de interpretar tus explicaciones pero me gustaría entenderlo para aprender. :oops:

Gracias . Por la ayuda que me estas echando .


Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Menu 3 opciones con lcd 20x4
« Respuesta #29 en: 06 de Julio de 2023, 19:45:06 »
Hola!

Citar
He revisado el código del fichero adjunto y no entiendo el significado de estas 2 líneas .
#define CPU_MHZ 4
#define delay_ms_break(t_ms,pinx)  for(int32 n=15.46*CPU_MHZ*t_ms ; !input(pinx) && n>0 ; n--)
que significado tienen o que hace ?  :shock:

Cosas de viejo mañoso, me molestaba tener que hacer una pulsación larga para salir del menú. Con retardos de 500ms es un simple detalle, pero si fueran varios segundos sería indispensable. 
Ojo, el delay_ms es  simple y cómodo, por eso lo ves hasta en la sopa, pero lo recomendable es usar interrupciones.

Ese macro trabaja igual que el delay_ms, pero se interrumpe al pulsar.
Como cada ciclo total  del for demora  x ms , si quiero un retardo de 500ms tengo que inicializar n con 500/x .   Eso es lo que se hace n=15.46*CPU_MHZ*t_ms   
No me pongo a sumar los tiempos de cada instrucción en assembler, sino que le doy un valor cualquiera, pongo un par de breakpoints en Proteus y veo cuanto demoró realmente --> con eso calculo la constante de proporcionalidad (el 15.46)
Si dentro del for se pusiera otra condición mas para salir la constante será otra, pero usamos el procedimiento anterior y listo.


Sobre lo que comentas a continuación :

Citar
No, pero mientras la lectura del ADC se haga siempre dentro del menú, podés declarar:
Código: [Seleccionar]
    setup_adc_ports(AN0_TO_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);
al ingresar en la opción, y
Código: [Seleccionar]
setup_adc_ports(NO_ANALOGS) ;
al salir.

Entiendo que si pongo estas líneas de comando dentro de Menú y la otra linea al salir podría, utilizar un Pin digital  . Creo que es lo que me quieres explicar ?

Claro, a un pin configurado analógico no se lo puede leer como digital y viceversa.  Esto en general se hace en la inicialización del programa, pero se puede hacer en cualquier parte las veces que quieras.
Por ejemplo antes de usar input() o read_adc(). Mientras los pines afectados sean entradas no hay problema.

Saludos.


 

anything