Ir ao conteúdo
  • Cadastre-se

PIC Display LCD 20x4 e PIC18f4580


Posts recomendados

Bom dia a todos;

 

Estou enfrentando um problema com um display LCD 20x4 conectado a um PIC18f4580;

o LCD inicializa normalmente, mas começa a embaralhar as escritas, como se terminasse um comando e na sequencia começasse uma nova escrita, estou utilizando conforme arquivo em anexo; 

O código em anexo é apenas uma parte do software, que refiz para poder testar, mas comente com isso já tenho problemas.

 tentei utilizar o comando Lcd_out(1,1,"Descric Atual Limit"); mas sem sucesso a única forma que encontrei até o momento e utilizando o Lcd_Chr, conforma abaixo, 

 <Lcd_Chr(1,3,'I');
 Lcd_Chr(1,4,'N');
 Lcd_Chr(1,5,'C');
 Lcd_Chr(1,6,'I');
 Lcd_Chr(1,7,'A');
 Lcd_Chr(1,8,'L');
 Lcd_Chr(1,9,'I');
 Lcd_Chr(1,10,'Z');
 Lcd_Chr(1,11,'A');
 Lcd_Chr(1,12,'N');
 Lcd_Chr(1,13,'D');
 Lcd_Chr(1,14,'O');
 Lcd_Chr(1,15,'.');
 Lcd_Chr(1,16,'.');
 Lcd_Chr(1,17,'.');>

agora o que mais me chamou a atenção é que no Protheus funciona normalmente e no físico da este problemas .

Já substitui o display pois o que estou utilizando é um pouco antigo, mas  o problema permanece.

Alguém poderia me dar uma orientação?

 

 

teste.txt

 

teste.txt

Link para o comentário
Compartilhar em outros sites

@rodolfogravena ,

 

Ví este trecho de código seu :

if (tela == 1){
        	Lcd_out(1,1,txtCab);
        	Lcd_out(2,2,txtRco2);
        	Lcd_out(3,2,txtRco);
        	Lcd_out(4,2,txtRc2);
        }
        

 

Noto que você está enviando caracteres em sequencia, sem respeitar um tempo mínimo entre eles ( 4 comandos LCD_OUT ).... não vejo qual biblioteca você está usando para os comandos do display, esse tempo está definido dentro da biblioteca, e deve ter relação direta com o clock utilizado.

 

Entre dois caracterers basta cerca de 0,5 milissegundo .... se quiser garantir ainda mais deixa 0,8 milissegundo.

 

Não sei onde está esse seu tempo de 20 milissegundos....  para evitar ter de atribuir delays que apenas tomam tempo a mais, você pode ler o status do display antes de fazer outra gravação, mas isso hoje eu chamo de escovar bit à toa ..... pois existem bibliotecas que você define se quer usar o bit de status ou não ( mas terá de usar também o sinal R/W do display ) , acho que você tem de ver como funciona essa sua bliblioteca ok ?

 

Paulo

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Olás

Quem faz esta temporização é a lib do display. Geralmente o programador nem dá bola pra ela mas neste caso penso que você não tem acesso à ela. Experimenta apenas diminuir o clock do mc nos fuses pra ver. Ou veja se tem como informar tal clock ao compilador ou a lib. Como este mc trabalha até 40Mhz ou 32Mhz interno de fato pode estar rápido d+ pro display.

Caso de fato seja este o problema, há a alternativa de criar sua própria lib

 

Link para o comentário
Compartilhar em outros sites

Bom dia a todos, e muito obrigado pela ajuda que estão dando,

 

Respondendo o @aphawk , estou utilizando a biblioteca do próprio Mikroc, os timers estavam entre as linha citadas em sua resposta, mas no arquivo enviado já havia retirado os mesmos porque na surtiram efeito, fiz uma nova logica e melhorou um pouco, mas não resolveu, segue abaixo a nova logica feita, sei que o nome "I2C_LCD_Out"  não é adequado, mas aproveitei de uma biblioteca de comunicação I2C, mas futuramente irei alterar o nome da função. @vtrx em anexo o vídeo do problema já com esta função implementada.

OBS Já foram trocados o LCD, Processador e o Flat que interliga o Display ao processador.

 

Citação

sbit LCD_RS at RB0_bit;

sbit LCD_EN at RB1_bit;

sbit LCD_D4 at RB2_bit;

sbit LCD_D5 at RB3_bit;

sbit LCD_D6 at RB4_bit;

sbit LCD_D7 at RB5_bit;

 

sbit LCD_RS_Direction at TRISB0_bit;

sbit LCD_EN_Direction at TRISB1_bit;

sbit LCD_D4_Direction at TRISB2_bit;

sbit LCD_D5_Direction at TRISB3_bit;

sbit LCD_D6_Direction at TRISB4_bit;

sbit LCD_D7_Direction at TRISB5_bit;

 

char txtRco2[] = "CO2.... 0000  0000";

char txtRco[]  = "CO..... 0000  0000";

char txtRo2[]  = "O2..... 000%  000%";

char txtRh2s[] = "H2S.... 0000  0000";

char txtRvop[] = "VOP.... 0000  0000";

char txtRhum[] = "Humid.. 000.0%";

char txtRtem[] = "Temp... 000.0C";

char txtRpo[] =  "P.O.... 000.0C";

char txtRtco[] = "Comp..  000C  000C";

char txtCo2[]   = "SENSOR CO2";

char txtCo[]    = "SENSOR CO";

char txtO2[]    = "SENSOR O2";

char txtH2s[]   = "SENSOR H2S";

char txtVop[]   = "SENSOR VOP" ;

char txtTemp[]  = "TEMPERATURA AR";

char txtHum[]   = "umidade AR";

char txtPo[]    = "PONTO DE ORVALHO" ;

char txtCompr[] = "TEMP. COMPRESSOR";

char txtTroca[] =   "Trocado:   xx/xx/xx";

char txtProxima[] = "Prox Troca:xx/xx/xx";

char txtLimite[] =  "Limite max:0000 ppm";

char txtLimitep[] =  "Limite max: 000 %";

char txtSalva[] = "SALVANDO";

char txtData[] = "00/00/00";

char txtHora[] = "00:00:00";

char txtRtc[] = "RELOGIO";

char txtAlmCab[] = "ALARMES ATIVOS 1";

 

int res,i;

unsigned tela, timertela;

sbit Out1 at RD2_Bit;

bit Writeok;

void interrupt(){

 

    if(TMR1IF_bit)                           //Houve overflow do Timer1?

    {                                          //Sim...

        TMR1IF_bit = 0x00;                     //limpa flag TMR1IF

        TMR1L      = 0xE0;                        //byte menos significativo

        TMR1H      = 0xB1;                        //byte mais significativo

        TimerTela++;

    } //end if INT1IF

 

 

}

 void I2C_LCD_Out(char row, char col, char *text) {

    while(*text){

         LCD_Chr(row, col++, *text++);

         delay_ms(8);

    }

}

 

 

void main() {

     ADCON1 = 0x09;                  // Configure AN pins as digital

     CMCON  = 7;                     // Turn off comparators

     ECCP1CON = 0x00;

     TRISA = 0b11111111;

     PORTA = 0x00;

     TRISB = 0b00000000;

     PORTB = 0x00;

     TRISD = 0b11110000;              // Configura os pinos como entrada ou saida

     PORTD = 0x00;

     GIE_bit =       0x01;

     PEIE_bit =      0x01  ;

     TMR1IE_bit = 0x01;

     T1CON = 0x81;

     TMR1L      = 0xE0;                        //byte menos significativo

     TMR1H      = 0xB1;    //98

     Lcd_Init();

     Lcd_Cmd(_LCD_CLEAR);               // Clear display

     Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

     I2C_LCD_Out(1,2,"Descric  Atual Limit");

     Out1 = 0;

     tela = 0;

     timertela = 0;

 

     while(1){

 

         if (TimerTela > 1000){

             tela++;

             if (tela > 3 ){tela = 1;}

             TimerTela = 0 ;

             Lcd_Cmd(_LCD_CLEAR);

          }

         if (tela == 1){

            I2C_LCD_Out(1,2,"Descric  Atual Limit");

            I2C_LCD_Out(2,2,txtRco2);

            I2C_LCD_Out(3,2,txtRco);

            I2C_LCD_Out(4,2,txtRo2);

           }

 

         if (tela == 2){

            I2C_LCD_Out(1,1,"Descric  Atual Limit");

            I2C_LCD_Out(2,1,txtRh2s);

            I2C_LCD_Out(3,1,txtRvop);

            I2C_LCD_Out(4,1,txtRhum);

         }

 

         if (tela == 3){

            I2C_LCD_Out(1,1,"Descric  Atual Limit");

            I2C_LCD_Out(2,1,txtRtem);

            I2C_LCD_Out(3,1,txtRpo);

            I2C_LCD_Out(4,1,txtRtco);

          }

      }

}

 

WhatsApp Video 2023-08-11 at 09.07.58.zip

Link para o comentário
Compartilhar em outros sites

O display é direto no controlador, a função I2c, é somente o nome da  função que fiz para tentar escrever no display através do comando "Lcd_Chr", a placa contem reles, mas os mesmos não estão sendo acionados, quanto ao ruido, também pensei nisso, e coloquei um capacitor de desacoplamento entre o 5v e o gnd, direto nos pino do display, até estou pensando de colocar resistor de pushdown nos pinos de dados. Uma coisa que observei que quando mando escrever na linha 1, assim que ele termina aparece a mensagem anterior na linha 3, ai escreve a linha 2, e ao final acontece o mesmo na linha 4, depois segue sobrescrevendo as linha 3 e 4.

aparentemente esta ficando sujeira na memória do display.

   

Link para o comentário
Compartilhar em outros sites

55 minutos atrás, rodolfogravena disse:

aparentemente esta ficando sujeira na memória do display.

   

 

95% de certeza : problema de velocidade de escrita ......  tem de tornar a escrita mais lenta, já passei por isso ..... a cada escrita que você faz no display, precisa aumentar o timeout. 

 

Paulo

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
28 minutos atrás, aphawk disse:

tornar a escrita mais lenta

9 horas atrás, .if disse:

apenas diminuir o clock do mc nos fuses

 

Em 10/08/2023 às 17:19, aphawk disse:

tempo está definido dentro da biblioteca, e deve ter relação direta com o clock

9 horas atrás, .if disse:

trabalha até 40Mhz ou 32Mhz interno de fato pode estar rápido d+ pro display.

Se achar que deve, teça algum comentário sobre... ou melhor ainda, tome alguma providência no sentido.

 

Há uma alternativa nada ortodoxa de se criar uma função mista com algo como

char txtCab[] = "Descric  Atual Limit";
while (*txtCab++) {Lcd_Chr(*txtCab);delay(tempo_do_Paulao);} //não é bem isso mas bem parecido

Coloca 1 caractere por vez no display... Situações desesperadoras, medidas desesperadoras

Obs: na próxima publique seu fonte direto no post e não pra baixar

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

13 horas atrás, rodolfogravena disse:

void I2C_LCD_Out(char row, char col, char *text) {

    while(*text){

         LCD_Chr(row, col++, *text++);

         delay_ms(8);

    }

}

Boa noite pessoal, obrigado pelas dicas, mas infelizmente ja tinha testado algo parecido com a sugestão do @if. 

 

Desculpe pessoal, na proxima vez coloco o código no post.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

ok mas permita-me opinar que não foi muito inteligente colocar a expressão i2c na coisa toda. Isso gerou confusão - pelo menos na minha cabecinha de bagre mesmo com seus warnings. Resta-lhe agora a questão da coisa física...

Em 10/08/2023 às 08:59, rodolfogravena disse:

no Protheus funciona normalmente e no físico da este problema

... que podem lhe ser iluminados com publicação de fotos... embora continuo achando que a ignorada questão do clock é igualmente relativamente relevante

Link para o comentário
Compartilhar em outros sites

Em 10/08/2023 às 08:59, rodolfogravena disse:

agora o que mais me chamou a atenção é que no Protheus funciona normalmente e no físico da este problemas

 

O Proteus não tem nenhum problema de temporização. Mas na vida real a coisa é bem mais crítica. 

Mas sempre simulo no Proteus, mesmo programas com mais de 4.000 linhas , ganho muito tempo no debug....

 

Paulo

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

1/2 que tem meu querido amigo. P.ex. já aconteceu o mesmíssimo problema do sumido autor comigo e no proteus mesmo. Errei as temporizações e ficava encavalando caractere. O legal é que o proteus avisa algo como "você está tentando escrever enquanto o display está ocupado". Qualquer dia acho o fonte que causava isso e tento reproduzir...

 

2 horas atrás, aphawk disse:

na vida real a coisa é bem mais crítica

De fato. p.ex. a distância que o barramento percorre até o display. De novo, incrivelmente já passei por isso também. e sim, solucionei.. mas parece que o autor perdeu o interesse ou solucionou e prefere não nos compartilhar a solução... Seu direito mas...

edit

teste...

Link para o comentário
Compartilhar em outros sites

@.if ,

 

No modelo dos LCD do Proteus você define o tempo mínimo para acesso. Basta mudar esse tempo e fica ok.....

 

Já tive problema de fios de conexão ao display também kkkkk tive de trocar o flat cable por um tipo coaxial com malha. O pior é que quando acionava um contator da máquina o display ficava doido com o flat cable ...... troquei por um coaxial , coloquei dois capacitores na alimentação por trás do display, e resolveu....

 

Enfim acho que o autor não está mais interessado ....

 

Paulo

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

 

49 minutos atrás, aphawk disse:

trocar o flat cable por um tipo coaxial com malha. O pior é que quando acionava um contator da máquina o display ficava doido com o flat cable ...... troquei por um coaxial

Incrivelmente foi esta a minha solução também kk.. e quase e mesmíssima coisa do contator mas era a.t. Mas,  pow Paul ... não era pra dar a solução de mão beijada pra ele pow! ... mas sim, pode não ser totalmente inútil pra incautos navegantes do futuro

 

Off

Ia colocar isso lá em cima pra não alimentar páginas a toa mas "alguém" removeu neste exato segundo meu (meu) direito de editar mesmo em menos de 1 hora kk.. tenta editar o seu aí e me conta pfv... 🤪

Aff!

 

edit... teste.. agora voltou (ou voltei) ao "normal" kk é alguma atualização  que G.T. está fazendo

51 minutos atrás, aphawk disse:

LCD do Proteus você define o tempo mínimo para acesso. Basta mudar esse tempo e fica ok

Boa... De fato nem mexi. Mas nem vale muito mexer nisso senão ele sai do padrão da vida real

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Tmj kk.. Mas a ideia era esperar algum retorno do pedinte

1 hora atrás, aphawk disse:

décadas de experiência ???? Prefiro espalhar um pouco por aí kkkkk, igual às minhas futuras cinzas !

Só o pó da bagaça 😁

 

1 hora atrás, aphawk disse:

Gozado, agora eu que não posso editar ...... vai saber ....

Né... depois a gente pede pra apagar... se não apagarem sem a gente pedir kk

  • Haha 1
Link para o comentário
Compartilhar em outros sites

Boa noite pessoal, deculpe o sumiço, mas quase enloqueci com isso, bem vamos lá no formato inicial não consegui resolver, Troquei processador, até mesmo de modelo, display, flat, oscilador, fonte e outras coisas mais, até mesmo escrever no display sem biblioteca,(isso funcionou, mas iria perder muito tempo desenvolvendo uma nova biblioteca...kkk)

A solução até este momento foi a seguinte, escrever no display caractere a caractere sem utilizar nenhum laço de repetição, e utilizando o menor número de variaveis possível. tive que reformular todo o software novamente, 2k de linhas, este foi o motivo do sumiço kkkk, as vezes desconfio da biblioteca do Mikroc, porque levei em cosideração as mesnsagens acima e reduzi o oscilador de 16 MHz para 5 MHz, melhorei alimentação, alimentei com fonte separado, e muitas outras coisa e nada, mas agora esta caminhando bora para o proxima etapa, abaixo uma parte do software para vocês entenderem da forma que eu fiz. 

Citação

...

void cabeça(){
      LCD_Chr(1,1,'D');
      LCD_Chr_Cp('e');
      LCD_Chr_Cp('s');
      LCD_Chr_Cp('c');
      LCD_Chr_Cp('r');
      LCD_Chr_Cp('i');
      LCD_Chr_Cp('C');
      LCD_Chr_Cp(' ');
      LCD_Chr_Cp(' ');
      LCD_Chr_Cp('A');
      LCD_Chr_Cp('t');
      LCD_Chr_Cp('u');
      LCD_Chr_Cp('a');
      LCD_Chr_Cp('l');
      LCD_Chr_Cp(' ');
      LCD_Chr_Cp('L');
      LCD_Chr_Cp('i');
      LCD_Chr_Cp('m');
      LCD_Chr_Cp('i');
      LCD_Chr_Cp('t');
}


void corpo(char troca,char limit){
      if (troca==1){
         LCD_Chr(2,1,'T');
         LCD_Chr_Cp('r');
         LCD_Chr_Cp('o');
         LCD_Chr_Cp('c');
         LCD_Chr_Cp('a');
         LCD_Chr_Cp('d');
         LCD_Chr_Cp('o');
         LCD_Chr_Cp(':');
         LCD_Chr_Cp(' ');
         LCD_Chr_Cp(' ');
         LCD_Chr_Cp(' ');

         LCD_Chr(3,1,'P');
         LCD_Chr_Cp('r');
         LCD_Chr_Cp('o');
         LCD_Chr_Cp('x');
         LCD_Chr_Cp(' ');
         LCD_Chr_Cp('T');
         LCD_Chr_Cp('r');
         LCD_Chr_Cp('o');
         LCD_Chr_Cp('c');
         LCD_Chr_Cp('a');
         LCD_Chr_Cp(':');

      }
      if (limit == 1){
         LCD_Chr(4,1,'A');
         LCD_Chr_Cp('j');
         LCD_Chr_Cp('u');
         LCD_Chr_Cp('s');
         LCD_Chr_Cp('t');
         LCD_Chr_Cp('e');
         LCD_Chr_Cp(' ');
         LCD_Chr_Cp('O');
         LCD_Chr_Cp('f');
         LCD_Chr_Cp('f');
         LCD_Chr_Cp('s');
         LCD_Chr_Cp('e');
         LCD_Chr_Cp('t');
         LCD_Chr_Cp(':');
      }
}

void valor(char TrocaDia, char TrocaMes, char TrocaAno, char ProxDia, char ProxMes,
           char ProxAno,unsigned Calibra, char Convtroca,char Convlimit ){
       char txtConv[6];
       if (Convtroca==1){
           ByteToStr(TrocaDia, txtConv);
           Lcd_Chr(2,12,txtConv[1]);
           Lcd_Chr(2,13,txtConv[2]);
           Lcd_Chr(2,14,'/');
           ByteToStr(TrocaMes, txtConv);
           Lcd_Chr(2,15,txtConv[1]);
           Lcd_Chr(2,16,txtConv[2]);
           Lcd_Chr(2,17,'/');
           ByteToStr(TrocaAno, txtConv);
           Lcd_Chr(2,18,txtConv[1]);
           Lcd_Chr(2,19,txtConv[2]);

           ByteToStr(ProxDia, txtConv);
           Lcd_Chr(3,12,txtConv[1]);
           Lcd_Chr(3,13,txtConv[2]);
           Lcd_Chr(3,14,'/');
           ByteToStr(ProxMes, txtConv);
           Lcd_Chr(3,15,txtConv[1]);
           Lcd_Chr(3,16,txtConv[2]);
           Lcd_Chr(3,17,'/');
           ByteToStr(ProxAno, txtConv);
           Lcd_Chr(3,18,txtConv[1]);
           Lcd_Chr(3,19,txtConv[2]);
       }
       if (Convlimit == 1){
           wordToStr(Calibra, txtConv);
           Lcd_Chr(4,19,txtConv[4]);
           Lcd_Chr(4,18,txtConv[3]);
           Lcd_Chr(4,17,txtConv[2]);
           Lcd_Chr(4,16,txtConv[1]);
       }
       corpo(Convtroca,Convlimit);


}

void Display(char tela){
       if (tela == 1){
           cabeça();
           LCD_Chr(2,2,'C');
           LCD_Chr_Cp('O');
           LCD_Chr_Cp('2');
           LCD_Chr_Cp('.');
           LCD_Chr_Cp('.');
           LCD_Chr_Cp('.');
           LCD_Chr_Cp('.');
           LCD_Chr_Cp(' ');
           wordToStr(AtualCo2, txtDate);
           LCD_Chr_Cp(txtDate[1]);
           LCD_Chr_Cp(txtDate[2]);
           LCD_Chr_Cp(txtDate[3]);
           LCD_Chr_Cp(txtDate[4]);
           LCD_Chr_Cp(' ');
           LCD_Chr_Cp(' ');
           wordToStr(MaxCo2, txtDate);
           LCD_Chr_Cp(txtDate[1]);
           LCD_Chr_Cp(txtDate[2]);
           LCD_Chr_Cp(txtDate[3]);
           LCD_Chr_Cp(txtDate[4]);
...

case 3:

                           if (DpyControl == 1){
                               Display(1);
                           }
                           if (DpyControl == 2){
                              Display(2);
                           }
                           if (DpyControl == 3){
                              Display(3);
                           }
                           if (DpyControl == 4){
                              Display(12) ;
                              LCD_Chr(1,17,'1');
                              if (AlmCo2 == 1){
                                 LCD_Chr(2,6,'S');
                                 LCD_Chr_Cp('E');
                                 LCD_Chr_Cp('N');
                                 LCD_Chr_Cp('S');
                                 LCD_Chr_Cp('O');
                                 LCD_Chr_Cp('R');
                                 LCD_Chr_Cp(' ');
                                 LCD_Chr_Cp('C');
                                 LCD_Chr_Cp('O');
                                 LCD_Chr_Cp('2');
                              }

.....

acima duas partes do software, uma das funções e outra de como elas são chamadas, mas agradeço de coração toda a ajuda e espero contribuir um dia com o forum...kkkkk

  • Triste 1
Link para o comentário
Compartilhar em outros sites

  • 2 meses depois...

Bom dia

Acho que o problema esta relacionado com o numero máximo de colunas do LCD, no seu caso 20.

Notei que dentro do loop você colocou col++, o que dificulta a conta do numero máximo de caracteres.

Se tentar mais de 20 caracteres por linha da esse problema.

Tenta colocar esta proteção:

void I2C_LCD_Out(char row, char col, char *text) {

unsigned char t=0;

 

    t=col;

    while(*text && t<20){

         LCD_Chr(row, col, *text++);

         t++;

         //delay_ms(8);

    }

Link para o comentário
Compartilhar em outros sites

@Alepower ,

 

No código mostrado pelo @rodolfogravena, não tem nenhuma string que passe de 20 caracteres de comprimento. Então não deve ocorrer este problema que você citou.

 

Como eu não entendo patavina nenhuma de C, posso estar errado, mas no seu código de proteção me parece que não vai ser possível escrever 20 caracteres, apenas 19 ....

 

Paulo

Link para o comentário
Compartilhar em outros sites

16 horas atrás, aphawk disse:

Como eu não entendo patavina nenhuma de C, posso estar errado, mas no seu código de proteção me parece que não vai ser possível escrever 20 caracteres, apenas 19 ..

Vai de 0 a 19,então são vinte,pois dentro do looping o zero é executado e depois aumentado em 1(t++;),a menos que eu esteja me confundindo.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!