Autor Tema: Simbolos personalizados en LCD20X4 CGRAM  (Leído 2373 veces)

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

Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Simbolos personalizados en LCD20X4 CGRAM
« en: 11 de Junio de 2026, 18:15:19 »
Hola , estoy intentando añadir Simbolos personalizados utilizando un LCD 20X4 y una aplicación que termite generar el simbolos pintando cuadros pixeles y luego te genera el código que deberías implementar en el programa .He conseguido que funcione en lcd 16x2 .Pero en el LCD 20X4 me salen rayas y no símbolos .Para este LCD20X4 estoy utilizando una librería algo modificada (LCD420_V2) ya que esta dentro de un proyecto y no puedo utilizar otra librería del LCD. Como podría integrar esos simbolos u otros en LCD20X4 utilizando esta libreria retocada. Si alguien ha podido hacerlo con la librería normal del lcd20x4 o me puede ayudar a integrarlo para que se vea como en la foto del lcd16x2. Adjunto código en texto plano con un ejemplo para experimentar y foto del lcd16x2 donde se ven los símbolos creados (visionado correcto) y foto del lcd20x4 (visionado erróneo) supongo que será por la librería ,haber si alguien arroja luz ...  Gracias. :shock:


ejemplo :

#include <18F2550.H>
#fuses XT
#fuses NOWDT
#FUSES PUT
#FUSES NOPROTECT
#USE DELAY (clock = 4M)

#DEFINE LCD_DB4 pin_D4
#DEFINE LCD_DB5 pin_D5
#DEFINE LCD_DB6 pin_D6
#DEFINE LCD_DB7 pin_D7
#DEFINE LCD_RS pin_D1
#DEFINE LCD_RW pin_D2
#DEFINE LCD_E pin_D0

#include <lcd.c>

void main(){
   int BARRAT[8] = {0,10,10,0,17,14,0,0};
 
   
   lcd_init();
   delay_ms(700);
   lcd_set_cgram_char(0,BARRAT);
   
   
   lcd_putc("\f");// Borrar contenido de la LCD
   
      while(1){
         
         lcd_gotoxy(7,2);//             lcd_gotoxy("columna", "fila")
         printf(lcd_putc,"%c", 0);
       
         
      }
}

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1007
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #1 en: 23 de Junio de 2026, 21:03:49 »
En el código que subiste usás un 18F2550 y  el display en el port D --> El 18F2550 no tiene port D porque es de 28 pines.

De todas maneras el problema que me hace el programa subido es que las filas 3 y 4 se muestran en la 2,   el caracter especial (smiley) lo muestra bien.

Ese problema es de la libreria LCD.C, se soluciona modificando la funcion lcd_gotoxy con un switch()  (LCD_20x4.C == LCD.C parcheada)


Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #2 en: 06 de Agosto de 2026, 17:46:58 »
Hola Eduardo2 , Siento no haber respondido antes  ,ya que he tenido un parón largo .Te comento he probado tu version del lcd_20x4.c y a la hora de compilar con el programa que utilizo me da un error y no termina de realizar la compilación . Subo captura del error haber a que puede ser ese error (error comienza en el sombreado). De todas formas esta versión difiere bastante de la que subí en el inicio del post que es la que hace funcionar todo el programa salvo la integración de CGRAM .

Por otro lado lado tienes razón al decir que el pic no tiene por "D" y que el código que subí lo estaba haciendo con un pic18f2550. Hay me equivoque . Ya que las pruebas iniciales las hice un PIC16F876 . y un lcd 16x2 mezcle alguna cosa. Pero cuando pase a realizar pruebas con el PIC18F2550 Y LCD20X4 utilizando la compilación el lcd(LCD420_V2) que hace que me funciona el proyecto correctamente . Hay en es donde ya no funcionaba nada de las figuras ya que esta  versión (LCD420_V2) tiene modificado los puertos acorde al diseño de circuito en PCB que estoy utilizando y que m funciona perfectamente. De hay las capturas que subí con un lcd 16x2 y pic 16f876 y la otra captura que subí era con un lcd20x4 y pic18f2550 y compilación (LCD420_V2).

No se si se podría trabajar en esta compilación  y añadir las líneas necesarias para que se integre CGRAM. o BIEN tengo que utilizar la versión que me enviaste ultima y que aparte del error que me da al compilar ,posiblemente no tenga algún otro problema por la modificación de los puertos para poder visualizar en el lcd con la configuración de la pcb. Gracias . Haber si es posible...



Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1007
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #3 en: 06 de Agosto de 2026, 19:20:08 »
La resolución de esa imagen es muy baja, no se alcanza a leer nada.

Mucho mejor es que subas los fuentes.

Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #4 en: 07 de Agosto de 2026, 16:51:22 »
La resolución de esa imagen es muy baja, no se alcanza a leer nada.

Mucho mejor es que subas los fuentes.


Hola Eduardo2 , He echo una captura con mas calidad. vuelvo a subirla y añado código del programa base F.A. ,librería LCD420_v2 ,la ultima que me enviastes y la que genera el error que ves en la captura (imagen) y librería del LCD420_V2_b con la que el programa base funciona sin problemas pero no tiene implementado la posibilidad de caracteres CGRAM . Haber si ahora sale algo en claro.... Saludos.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1007
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #5 en: 07 de Agosto de 2026, 20:07:15 »
El problema parece ser el argumento de nombre which .
¿No tenés un macro definido con ese nombre?   Renombrala witch (mas acorde al problema) y fijate si compila.

Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #6 en: 14 de Agosto de 2026, 15:09:21 »
El problema parece ser el argumento de nombre which .
¿No tenés un macro definido con ese nombre?   Renombrala witch (mas acorde al problema) y fijate si compila.

Hola Eduardo ,  llevo varios días haciendo pruebas pero no consigo solucionar el error ,el tema de la macro con nombre "witch" no existe en el código fuente. Y no se como implementarla tal y como tengo generado el código. También he podido ver que la librería lcd420_v2. Que me proporcionaste es distinta a la que uso. Y que funciona bien con el codigo fuente. Solo le faltaría implementar que pueda entender el codigo CGRAM.
La librería a utilizar y donde se debería añadir código de CGRAM seria en la que esta definida como : lcd420_v2_b.c  . En esta es donde deberíamos trabajar para implementarlo. A continuación pongo el codigo fuente del programa donde tengo implementado las líneas del codigo para símbolos CGRAM. Y que al compilar lo hace bien me genera el . hex (pero solo faltaría añadir en la libreria del lcd420....)  .


#include <18F2550.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(crystal=4000000)     // reloj a 4 MHz.

#use standard_io( A )
#use STANDARD_IO( B )

#define BUTTON_UP_PIN    PIN_C6    //PIN_A1
#define BUTTON_ENTER_PIN PIN_C7    //PIN_A2
#define BUTTON_EXIT_PIN  PIN_C7    //PIN_A2

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

#define DS18B20_PIN PIN_B6
#define PIN_DS18B20_DATA DS18B20_PIN
#include "ds18b20.c"

#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--)
#define lcd_set_cgram_char

//int     sensor;
float   temper;
signed  int16 value;

#include "LCD420_v2.C"

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

int16 voltaje_adc,corriente_adc;
float voltaje,corriente,potencia;

#define MENU_OPTION_COUNT 7
char* menuOptions[MENU_OPTION_COUNT]= {"Fecha-Hora-Tem.I/E","Fuente 5VDC/Regul.","Fuente 5VDC(FIJO)","Fuente 3,3V(FIJO)","Opcion 5","Opcion 6","Opcion 7"};

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

#define Ton  (100.*50)          // Tiempo de 50"
                                // 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 50"
    }                           // Resetea la cuenta si está encendido
}

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

void displayMenu(int8 select) {

    lcd_putc('\f');  // Limpiar la pantalla   
    lcd_gotoxy(2, 1); printf(lcd_putc, "Menu F.A. Opcion:");
               
    static int8 base=0;                                         
   
    if((select-base)>0x80)   base-- ;          // Para cuenta descendente
    else if((select-base)>2) base=select-2 ;

//    if((select-base)>0x80)   base=0 ;        // Para cuenta ascendente 
//    else if((select-base)>2) base++ ;
   
    for(int8 j=2,k=base ; j<5 ; j++,k++){
        lcd_gotoxy(1, j);
        if (select == k)
            printf(lcd_putc, "> %s", menuOptions[k]);
        else
            printf(lcd_putc, "  %s", menuOptions[k]);
    }       
}

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

void reloj_lcd()
{
   lcd_gotoxy(2,2); printf(LCD_PUTC,"T.FA.:%Ld%cC",temperatura,grados);
   lcd_gotoxy(3,3); printf(LCD_PUTC,"%02u:%02u:%02u",horas,minutos,segundos);
   lcd_gotoxy(2,4); printf(LCD_PUTC,"%02u/%02u/20%02u",dia,mes,anio);
   lcd_gotoxy(1,2); printf(lcd_putc,"%c", 0);
   
}
//=====================================================================

void proc_Opcion1(){
       
    delay_ms(200) ;
    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();
         
        // ---------------------------------------------------
        ds18b20_read(&value) ;
        temper=value/16. ;

        lcd_gotoxy(14,3);
        printf(lcd_putc, "%.2f", temper); // temperatura exterior
        lcd_putc(223);                    // Imprimir el símbolo de grados Celsius (°)
        lcd_putc('C');     
        lcd_gotoxy(15,4); printf(lcd_putc, "T.EXT.");
       
        // ------------------------------------------------------------
        delay_ms_break(500,BUTTON_EXIT_PIN) ;
    } while(input(BUTTON_EXIT_PIN)==0);
}

void proc_Opcion2(){
    setup_adc_ports(AN0_TO_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);

    do {
        set_adc_channel(0);
        delay_ms(100);
        voltaje_adc=READ_ADC();
        voltaje= 50.0 * voltaje_adc/1023.0;
        set_adc_channel(1);
        delay_ms(100);
        corriente_adc=READ_ADC();
        corriente= 5 * corriente_adc/1023.0;
        potencia= voltaje * corriente;
        lcd_gotoxy(2,2);
        printf(lcd_putc, " %02.2fV    %02.3fA ",voltaje,corriente);
        lcd_gotoxy(6,3);
        printf(lcd_putc, "P=%02.2fW  ",potencia);

        delay_ms_break(300,BUTTON_EXIT_PIN) ;
    } while(input(BUTTON_EXIT_PIN)==0);
   
    setup_adc_ports(NO_ANALOGS) ;         
}

void proc_Opcion3(){
    setup_adc_ports(AN0_TO_AN3);
    setup_adc(ADC_CLOCK_INTERNAL);

    do {
        set_adc_channel(2);
        delay_ms(100);
        voltaje_adc=READ_ADC();
        voltaje= 5.0 * voltaje_adc/1023.0;
        set_adc_channel(3);
        delay_ms(100);
        corriente_adc=READ_ADC();
        corriente= 5 * corriente_adc/1023.0;
        potencia= voltaje * corriente;
        lcd_gotoxy(2,2);
        printf(lcd_putc, " %02.2fV    %02.3fA ",voltaje,corriente);
        lcd_gotoxy(6,3);
        printf(lcd_putc, "P=%02.2fW  ",potencia);
 
        delay_ms_break(300,BUTTON_EXIT_PIN) ;
    } while(input(BUTTON_EXIT_PIN)==0);
   
    setup_adc_ports(NO_ANALOGS) ;

}
void proc_Opcion4(){

    lcd_gotoxy(6,2);
    printf(lcd_putc,"pruebas...");

    delay_ms(200) ;

    do {
        ds18b20_read(&value) ;
        temper=value/16. ;

        lcd_gotoxy(8,3);
        printf(lcd_putc, "%.2f", temper); // temperatura exterior
        lcd_putc(223);                    // Imprimir el símbolo de grados Celsius (°)
        lcd_putc('C');   
        lcd_gotoxy(1,3); printf(lcd_putc, "T.EXT.");
// ------------------------------------------------------------
        delay_ms_break(300,BUTTON_EXIT_PIN) ;
    } while(input(BUTTON_EXIT_PIN)==0);
    setup_adc_ports(NO_ANALOGS) ;
}

void proc_Opcion57(){

    lcd_gotoxy(6,2);
    printf(lcd_putc,"pruebas xx...");

    delay_ms(250) ;

    do {
// ------------------------------------------------------------
        delay_ms_break(300,BUTTON_EXIT_PIN) ;
    } while(input(BUTTON_EXIT_PIN)==0);
}

void main() {
 
  int BARRAT[8] = {0,10,10,0,17,14,0,0};[/b][/b]
    ds18b20_read(&value) ;
    temper=value/16. ;

    lcd_init();
    lcd_set_cgram_char(0,BARRAT);
    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);

    c_time.hours  = 00 ;
    c_time.minutes= 54 ;
    c_time.seconds= 20 ;
    c_time.day    = 04 ;
    c_time.month  = 06 ;
    c_time.year   = 26 ;
    //RTC_Set(&c_time) ; // activar esta linea solo para poner en hora y fecha
                      // Luego desactivar para que no vuelva a cojer parametros
 
    while (TRUE) {
        static signed int selectedOption = 0 ;

        if (input(BUTTON_UP_PIN)) {

            selectedOption--;                                                    // Para cuenta descendente 
            if( selectedOption < 0)  selectedOption = MENU_OPTION_COUNT - 1;

//            selectedOption++;                                                  // Para cuenta ascendente 
//            if( selectedOption > (MENU_OPTION_COUNT - 1))  selectedOption = 0;

            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,"Fecha/Hora/Temp.I/E");
                    proc_Opcion1() ;               
                    break;

                case 1:
                    printf(lcd_putc, "Selecc. 5v/Regul.");
                    proc_Opcion2() ;
                    break;

                case 2:
                    printf(lcd_putc, "Selecc. 5vdc/Amp.");
                    proc_Opcion3() ;
                    break;
               
                case 3:
                    printf(lcd_putc, "Selecc. 3,3Vdc/Amp.");
                    proc_Opcion4() ;
                    break;
           
               default:
                    printf(lcd_putc, "Opcion x seleccion");
                    proc_Opcion57() ;
            }
            displayMenu(selectedOption);
            delay_ms(500);     // AntiRebote
        }
    }
}



Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1007
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #7 en: 15 de Agosto de 2026, 09:45:54 »
Revisá la configuración del CCS.
Al código que subiste lo copypego, agrego el DS3231.c, y compila sin problemas.


* Clipboard 1.jpg
(146.41 kB, 640x511 - visto 91 veces)

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1007
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #8 en: 15 de Agosto de 2026, 10:03:31 »
Olvidate del mensaje anterior.  Habia usado una version anterior del lcd420_v2.c.

El problema es que escribiste un:    #define lcd_set_cgram_char
lcd_set_cgram_char es una función declarada mas adelante, donde te da el error.

Eliminá esa línea por el amor del cielo.
 

Desconectado Jiha

  • PIC10
  • *
  • Mensajes: 30
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #9 en: 15 de Agosto de 2026, 12:41:44 »
demo proteus

Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #10 en: 20 de Agosto de 2026, 15:11:08 »
Olvidate del mensaje anterior.  Habia usado una version anterior del lcd420_v2.c.

El problema es que escribiste un:    #define lcd_set_cgram_char
lcd_set_cgram_char es una función declarada mas adelante, donde te da el error.

Eliminá esa línea por el amor del cielo.

Hola Eduardo2 ,   He eliminado la linea :  #define lcd_set_cgram_char .
Y ahora si compila bien  :mrgreen:  Pero ahora no se ve nada en display ,si que alguna función la hace ósea que parte del código creo que se esta ejecutando ya que la iluminación del lcd la hace y temporizada y luego se apaga . Pero nada mas no puedo tener acceso a nada del menú tocando botones . Adjunto captura foto del lcd ,de como queda al quitar linea y compilar.


Desconectado genti

  • PIC10
  • *
  • Mensajes: 31
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #11 en: 20 de Agosto de 2026, 15:20:33 »
demo proteus

Hola Jiha ,  He probado el código ,pero no se ve nada en display ,adjunto captura foto ,me pasa lo mismo que lo que me recomendó (Eduardo2) el post de mas arriba ,parece que ejecuta parte del código ya que si pulso botón de iluminar lcd(temporizado) lo hace correctamente pero aparte de eso no puedo ver nada del menú .Por no repetir captura foto. mírate la que le puesto a EDUARDO2. ya que me pasa lo mismo. No se si al probarlo en Proteus ves algo porque en real no se ve nada. Ya me diréis . Gracias por echarme un cable a ti y a EDUARDO2.

Desconectado Jiha

  • PIC10
  • *
  • Mensajes: 30
Re:Simbolos personalizados en LCD20X4 CGRAM
« Respuesta #12 en: 20 de Agosto de 2026, 20:00:50 »
Esta es la conexión del lcd funcionando en proteus con el programa que adjunté anteriormente