Ir ao conteúdo
  • Cadastre-se

PIC Criação de uma barra de progresso no display lcd 16x2 com PIC16F877A


Posts recomendados

Saudações a todos, estou desenvolvendo um aparelho semelhante a um computador de bordo veicular "Mas com poucas funções" para meu veiculo. Basicamente terei cinco parâmetros que serão mostrados no display LCD, são eles: Temperatura do motor, Temperatura externa, Tensão da bateria, Sinal de sonda lambda e Nível de combustível.

Minha dificuldade no momento é desenvolver a programação do progresso e retrocesso da barra do nível de combustível, consegui faze-la avançar mas, não consigo faze-la retroceder.

No hardware montado no ISIS estou utilizando um pic 16F877A e um display LCD, existe uma botoeira que faz a seleção dos menus. O microcontrolador faz a leitura dos sinais analógicos pelas entradas AN1, AN2 e AN5, que correspondem, respectivamente a: Temperatura externa, Temperatura do motor e nível de combustível. Segue imagens do circuito e o código desenvolvido no MikroC.
 

/*

Computador de bordo veicular simples versão 1.0

Microcontrolador: PIC18F877A

Clock: 8MHz

*/



//Configração da pinagem Lcd



sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;



// Diração da pinagem do lcd



sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;



//Mapeamento de hardware



#define change          RB1_bit         //Botão para seleção das telas

//Definição de flags e constantes

#define ntela          5                //Quantidade de telas para o sistema de menus
#define flag_option    flags.B1
#define lcd_clr        flags.B2
#define motor          flags.B3



//Prototipos de função



void menu_temp_motor();
void menu_temp_ext();
void menu_tensaobat();
void menu_lambda();
void menu_comb();
void temp_celsius();
void temp_celsius_exter();
void voltimetro();
void clear_lcd();
void read_but();
int average_temp();
void comb();
void CustomChar(char pos_row, char pos_char);



//Variavaeis globais



unsigned short flags = 0x00, 
                         screen = 0x01;
unsigned short level_flags = 0x00;
unsigned short level_flag = 0x00;
const char character[] = {31,31,31,31,31,31,31,31};

int result_ADC = 0x00;
unsigned long volt = 0x00;
float temperatura = 0.0;
float current_temp = 0.0;
char txt[15];



// Função principal
               
void main() {
     ADCON0 = 0x01;                  //AN0 como entrada analogia
     ADCON1 = 0x00;                  //PORTA 0,1,2 e 4 como analogico
     CMCON = 0x07;                   //Desbilita os comparadores
     TRISB = 0x01;
     TRISD = 0x00;                   //PORTD como saida digital
     PORTD = 0x00;                   //Inicai PORTD em 0
     Lcd_Init();                     //Inicia o display LCD
     Lcd_Cmd (_LCD_CLEAR);           //Limpa o lcd
     Lcd_Cmd (_LCD_CURSOR_OFF);      //Desliga o cursor
     Lcd_Out (1,1, "Iniciando"); //Mensagem inicial
     delay_ms(1000);
     Lcd_Cmd (_LCD_CLEAR);           //Limpa lcd
     
     
     while(1)
     {
      read_but();
      switch(screen)
      {
       case 0x01: menu_temp_motor(); break;
       case 0x02: menu_temp_ext();   break;
       case 0x03: menu_tensaobat();  break;
       case 0x04: menu_lambda();     break;
       case 0x05: menu_comb();       break;
      } //end switch
     } //end while
     

} 

//=============== Desenvolvimento das funções auxiliares ======================

//===============LEITURA DOS BOTÕES ===========================================
void read_but()
{
 if(!change) flag_option = 0x01;             //Seta a flag de mudança do menu
 if(change && flag_option)
 {
  flag_option = 0x00;                        //Limpa a flag
  screen ++;
  if(screen > ntela) screen = 0x01;
  lcd_clr = 0x01;                            //Seta flag de limpeza da tela
 }
}
//========================= LIMPEZA DO DISPLAY ================================
void clear_lcd()
{
 if(lcd_clr)
 {
  Lcd_Cmd(_LCD_CLEAR);                       //Limpa display
  lcd_clr = 0x00;                            //Limpa a flag
 }
}

//================================= MENUS =====================================

void menu_temp_motor()
{
 char i;
 clear_lcd();                               //Seta flag de leitura do ADC 0
 Lcd_Chr(1,4,'T');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('M');
 Lcd_Chr_Cp('P');
 Lcd_Chr_Cp('.');
 Lcd_Chr_Cp('M');
 Lcd_Chr_Cp('O');
 Lcd_Chr_Cp('T');
 Lcd_Chr_Cp('O');
 Lcd_Chr_Cp('R');
 //Lcd_Cmd(_LCD_SHIFT_LEFT);
 motor = 0x01;                                        //Seta flag de leitura da temperatura do motor
 temp_celsius();
}

void menu_temp_ext()
{
 clear_lcd();                                           
 Lcd_Chr(1,3,'T');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('M');
 Lcd_Chr_Cp('P');
 Lcd_Chr_Cp('.');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('X');
 Lcd_Chr_Cp('T');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('R');
 Lcd_Chr_Cp('N');
 Lcd_Chr_Cp('A');
 motor = 0x00;
 temp_celsius();
}
void menu_tensaobat()
{
 clear_lcd();
 Lcd_Chr(1,3,'T');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('N');
 Lcd_Chr_Cp('.');
 Lcd_Chr_Cp('B');
 Lcd_Chr_Cp('A');
 Lcd_Chr_Cp('T');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('R');
 Lcd_Chr_Cp('I');
 Lcd_Chr_Cp('A');
 voltimetro();
}
void menu_lambda()
{
 clear_lcd();
 Lcd_Chr(1,5,'L');
 Lcd_Chr_Cp('A');
 Lcd_Chr_Cp('M');
 Lcd_Chr_Cp('B');
 Lcd_Chr_Cp('D');
 Lcd_Chr_Cp('A');
}
void menu_comb()
{
 clear_lcd();
 Lcd_Chr(1,3,'N');
 Lcd_Chr_Cp('I');
 Lcd_Chr_Cp('V');
 Lcd_Chr_Cp('E');
 Lcd_Chr_Cp('L');
 Lcd_Chr_Cp(' ');
 Lcd_Chr_Cp('C');
 Lcd_Chr_Cp('O');
 Lcd_Chr_Cp('M');
 Lcd_Chr_Cp('B');
 Lcd_Chr_Cp('U');
 Lcd_Chr_Cp('S');
 Lcd_Chr_Cp('.');
 Lcd_Chr(2,1,'R');
 Lcd_Chr(2,16,'F');
 comb();
}
//=============================== SENSOR DE TEMPERATURA =======================
void temp_celsius()
{
 result_ADC = average_temp();                          //Recebe o valor da média das cem medições de temperatura
 temperatura = ((result_ADC * 5.0)/1024.0)*100;         //Converte para volts, depois para graus Celsius
       
 if(temperatura < (current_temp - 0.5) || temperatura > (current_temp + 0.5))
 {
  current_temp = temperatura;
  FloatToStr(temperatura, txt);                          //Converte de Float para String
         
  Lcd_Chr(2,7,txt[0]);                                   //Imprimi o valor da temperatura no display
  Lcd_Chr_Cp(txt[1]);
  Lcd_Chr_Cp(txt[2]);
  Lcd_Chr_Cp(txt[3]);
  Lcd_Chr_Cp(txt[4]);
 }
}
//======================= FILTRO DE LEITURA DA TEMPERATURA ====================
int average_temp()
{
 char i, o = 0x00;
 int temp_store = 0x00;
 for(i=0x00; i<0x64; i++)
 {
  if(motor)temp_store =  temp_store + ADC_Read(0);
  else     temp_store =  temp_store + ADC_Read(1);
 }
 return(temp_store/0x64);
}
//================================ VOLTIMETRO =================================

void voltimetro()
{
 unsigned char mil, cen, dez, uni;
 
 volt = adc_read(2);
 volt = (volt*1400)>>10;       //Para valores maiores de tensão, este valor deve ser modificado (ADCx500/1024) para 10V 1000, para 20V 2000

 mil = volt/1000;
 cen = (volt%1000)/100;
 dez = (volt%100)/10;
 uni = volt%10;

 lcd_chr(2,6,mil+48);
 lcd_chr_cp(cen+48);
 lcd_chr_cp('.');
 lcd_chr_cp(dez+48);
 lcd_chr_cp(uni+48);
 lcd_chr_cp('V');
}

void comb()
{
 unsigned int i;
 unsigned char cont, level_1=0x00, level_2=0x00, level_3=0x00, level_4=0x00,
               level_5=0x00, level_6=0x00, level_7=0x00,level_8=0x00, 
               level_9=0x00, level_10=0x00, level_11=0x00, level_12=0x00, 
               level_13=0x00, level_14=0x00, level_15=0x00;
 
 i = (ADC_Read(5)/0x49);
 
 if(i<=0x01 && i<0x02) level_flags.B1 = 0x01;
 if(i>=0x02 && i<0x03) level_flags.B2 = 0x01;
 if(i>=0x03 && i<0x04) level_flags.B3 = 0x01;
 if(i>=0x04 && i<0x05) level_flags.B4 = 0x01;
 if(i>=0x05 && i<0x06) level_flags.B5 = 0x01;
 if(i>=0x06 && i<0x07) level_flags.B6 = 0x01;
 if(i>=0x07 && i<0x08) level_flags.B7 = 0x01;
 if(i>=0x08 && i<0x09) level_flag.B0 = 0x01;
 if(i>=0x09 && i<0x0A) level_flag.B1 = 0x01;
 if(i>=0x0A && i<0x0B) level_flag.B2 = 0x01;
 if(i>=0x0B && i<0x0C) level_flag.B3 = 0x01;
 if(i>=0x0C && i<0x0D) level_flag.B4 = 0x01;
 if(i>=0x0D && i<0x0E) level_flag.B5 = 0x01;
 if(i>=0x0E && i<0x0F) level_flag.B6 = 0x01;
 
  if((level_flags.B1) && (!level_2))
    {
     level_flags.B1 = 0x00;
     level_1 = 0x01;
     CustomChar(2,2);
    }
 if((level_flags.B2) && (!level_3))
    {
     level_flags.B2 = 0x00;
     level_2 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
    }
 if((level_flags.B3) && (!level_4))
    {
     level_flags.B3 = 0x00;
     level_3 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
    }
 if((level_flags.B4) && (!level_5))
    {
     level_flags.B4 = 0x00;
     level_4 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
    }
 if((level_flags.B5) && (!level_6))
    {
     level_flags.B5 = 0x00;
     level_5 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
    }
 if((level_flags.B6) && (!level_7))
    {
     level_flags.B6 = 0x00;
     level_6 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
    }
 if((level_flags.B7) && (!level_8))
    {
     level_flags.B7 = 0x00;
     level_7 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
    }
 if((level_flag.B0) && (!level_9))
    {
     level_flag.B0 = 0x00;
     level_9 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
    }
 if((level_flag.B1) && (!level_10))
    {
     level_flag.B1 = 0x00;
     level_10 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,10);
    }
 if((level_flag.B2) && (!level_11))
    {
     level_flag.B2 = 0x00;
     level_11 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
    }
 if((level_flag.B3) && (!level_12))
    {
     level_flag.B3 = 0x00;
     level_12 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,12);
    }
 if((level_flag.B4) && (!level_13))
    {
     level_flag.B4 = 0x00;
     level_13 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,13);
    }
 if((level_flag.B5) && (!level_14))
    {
     level_flag.B5 = 0x00;
     level_14 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,13);
     CustomChar(2,14);
    }
 if((level_flag.B6) && (!level_15))
    {
     level_flag.B6 = 0x00;
     level_15 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,13);
     CustomChar(2,14);
     CustomChar(2,15);
    }
}

void CustomChar(char pos_row, char pos_char) {
  char i;
    Lcd_Cmd(64);
    for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]);
    Lcd_Cmd(_LCD_RETURN_HOME);
    Lcd_Chr(pos_row, pos_char, 0);
}

 

Circuito.png

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

  • Membro VIP

Não vi o programa todo. Publique apenas a parte onde você não consegue fazer o lance da barra. Fale o que acontece e o que quer que aconteça. Também não vejo nada impresso no display do seu circuito.

Se for uma barra preta indo e vindo, essencialmente você deve imprimir o caracter da barra pra ir. E pra vir você deve imprimir espaço em branco.

Pra imprimir num caracter só, lembre-se que cada caracter tem 8 linhas ou seja, são só 8 barras custom char. Você pode indexá-las baseando no resultado do seu ad algo minimalista como
 

ad=adc_read(0)/128; //ad=10bits...1023/128=8 valores
CustomChar(2,ad);

 

Com um pouco + de sofrimento saudável, você consegue até imprimir uma barra saindo da linha de baixo e passando pra de cima. Fica mais "longa" o que melhora a visualização...

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

Peço desculpas por não colocar a imagem do circuito funcionando, vou corrigir isto. Acontece que no avanço as barras aparecem perfeitamente, mas não consigo faze-las retornarem, tentei criar uma logica com flags para que por exemplo, quando a variável (level_14 = 1 e level_flag.B4=1) imprimisse um carácter em branco, pois isso significaria decréscimo do nível de combustível, mas esta logica não funcionou. Estou buscando uma forma de fazer com que as barras retrocedam, indicando nível baixo de combustível. Segue abaixo o trecho do código em questão.

 

 

 

void comb()
{
 unsigned int i;
 unsigned char cont, level_1=0x00, level_2=0x00, level_3=0x00, level_4=0x00,
               level_5=0x00, level_6=0x00, level_7=0x00,level_8=0x00, 
               level_9=0x00, level_10=0x00, level_11=0x00, level_12=0x00, 
               level_13=0x00, level_14=0x00;
 
 i = (ADC_Read(5)/0x49); 	//São 14 niveis, 1023/14 ~= 73, ad/73=14
 
 if(i<=0x01 && i<0x02) level_flags.B1 = 0x01;
 if(i>=0x02 && i<0x03) level_flags.B2 = 0x01;
 if(i>=0x03 && i<0x04) level_flags.B3 = 0x01;
 if(i>=0x04 && i<0x05) level_flags.B4 = 0x01;
 if(i>=0x05 && i<0x06) level_flags.B5 = 0x01;
 if(i>=0x06 && i<0x07) level_flags.B6 = 0x01;
 if(i>=0x07 && i<0x08) level_flags.B7 = 0x01;
 if(i>=0x08 && i<0x09) level_flag.B0 = 0x01;
 if(i>=0x09 && i<0x0A) level_flag.B1 = 0x01;
 if(i>=0x0A && i<0x0B) level_flag.B2 = 0x01;
 if(i>=0x0B && i<0x0C) level_flag.B3 = 0x01;
 if(i>=0x0C && i<0x0D) level_flag.B4 = 0x01;
 if(i>=0x0D && i<0x0F) level_flag.B5 = 0x01;
 
  if((level_flags.B1) && (!level_2))
    {
     level_flags.B1 = 0x00;
     level_1 = 0x01;
     CustomChar(2,2);
    }
 if((level_flags.B2) && (!level_3))
    {
     level_flags.B2 = 0x00;
     level_2 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
    }
 if((level_flags.B3) && (!level_4))
    {
     level_flags.B3 = 0x00;
     level_3 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
    }
 if((level_flags.B4) && (!level_5))
    {
     level_flags.B4 = 0x00;
     level_4 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
    }
 if((level_flags.B5) && (!level_6))
    {
     level_flags.B5 = 0x00;
     level_5 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
    }
 if((level_flags.B6) && (!level_7))
    {
     level_flags.B6 = 0x00;
     level_6 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
    }
 if((level_flags.B7) && (!level_8))
    {
     level_flags.B7 = 0x00;
     level_7 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
    }
 if((level_flag.B0) && (!level_9))
    {
     level_flag.B0 = 0x00;
     level_9 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
    }
 if((level_flag.B1) && (!level_10))
    {
     level_flag.B1 = 0x00;
     level_10 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,10);
    }
 if((level_flag.B2) && (!level_11))
    {
     level_flag.B2 = 0x00;
     level_11 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
    }
 if((level_flag.B3) && (!level_12))
    {
     level_flag.B3 = 0x00;
     level_12 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,12);
    }
 if((level_flag.B4) && (!level_13))
    {
     level_flag.B4 = 0x00;
     level_13 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,13);
    }
 if((level_flag.B5) && (!level_14))
    {
     level_flag.B5 = 0x00;
     level_14 = 0x01;
     CustomChar(2,2);
     CustomChar(2,3);
     CustomChar(2,4);
     CustomChar(2,5);
     CustomChar(2,6);
     CustomChar(2,7);
     CustomChar(2,8);
     CustomChar(2,9);
     CustomChar(2,11);
     CustomChar(2,13);
     CustomChar(2,14);
    }
}

 

 

Circuito 2.png

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

  • Membro VIP

Olá amigo. Você pode pegar um atalho. Só pra "treinar o meu dragão", olha isso...

Suponho que os argumentos da CustomChar(y,x) são linha e coluna, acertei? Use o próprio resultado do ad como coluna (como já lhe disse lá atrás)
Isso deve plotar "pontos"

i = (ADC_Read(5)/0x49); //São 14 niveis, 1023/14 ~= 73, ad/73=14
CustomChar(2,i);

e apague todas as colunas adiante ou só uma pra ver que merdadá

Lcd_Chr_Cp(' ');

 

Pra plotar "linha" imagino algo tipo

while(i--) {CustomChar(2,i);Lcd_Chr_Cp(' ');}

 

  • Curtir 1
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...