Sensor de nivel utilizando hcsr04

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 03 Ago 2014 15:45

Na verdade queria juntar o util ao agradavel, pois esse sensor é barato e eficiente. E ja vi que algumas pessoas conseguiram fazer isso. So que como ainda sou meio iniciante, por isso procurei a ajuda de voces.

Vou tentar quebrar a cabeça com relação a formula, pelo visto o caminho pode ser esse.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 14 Ago 2014 15:01

Parece que consegui resolver o problema. Realmente o problema estava na maneira de se montar a formula.
Pelo que andei pesquisando a maneira correta de se colocar a formula e que deu certo para medir, a não ser o zero que fica oscilando em 0 e 255 é esta:

Código: Selecionar todos

while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
      }



Sendo: 710mm a altura total a ser medida e "* 50 ) >> 8 ) )" e para se multiplicar por 0,196 o fator de conversão de mm para m³ ou litros. Lembrando que nesse caso para testes como usei a altura da mesa para servir de padrão de altura a capacidade do recepiente que utilizei é de 139litros (V = 3,14 x 0,0625 (raio de 50cm) x 0,71(altura do sensor em relação a mesa).





Tambem descobri a formula para calcular percentual, so que estou sabendo onde inclui-la no programa para fazer a leitura.
A formula é esta:

Nivel percentual = (exibe_distancia *100) / 710.

Sera que alguem pode me ajudar.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor andre_luis » 14 Ago 2014 19:39

Você teria de criar uma nova função para isso, pois a rotina exibe_distancia utiliza 4 dígitos, e imprime o ''mm'' após, e também não considera o ponto decimal. Não seria complicado, mas um pouco trabalhos, pois demandaria diversas tentativas-e-erro, que apenas com um display do lado dá pra simular e ir corrigindo linha por linha.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 20 Ago 2014 22:33

Preciso de um auxilio para descobrir onde estou errando, na modificação do codigo. Abaixo o local da alteração:

Código: Selecionar todos
while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
     
      linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250);
      Porcentagem(((exibe_distancia) * 100) / 133) ; //transforma distancia / litros em valor por %.
     
      }




Quando compilo aparece a seguinte mensagem:

A numeric expression must appear here.


O codigo completo abaixo:

Código: Selecionar todos

#include <16F877A.h>
#device *=16
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)

#ZERO_RAM

//#define k_vazio 130
//#define k_cheio 113
#include <LCD_MSS.h>
/******************************************************************************
*  Ligações do LCD                                                            *
*   D7 -> RD7 (PORTD 7)                                                       *
*   D6 -> RD6 (PORTD 6)                                                       *
*   D5 -> RD5 (PORTD 5)                                                       *
*   D4 -> RD4 (PORTD 4)                                                       *
*   RS -> RD3 (PORTD 3)                                                       *
*   EN -> RD2 (PORTD 2)                                                       *
*   R/W -> Deve ser conectado ao GND                                          *
*   VCC -> Deve ser conectado ao +5V                                          *
*   GND -> Deve ser conectado ao GND                                          *
*   VO -> Deve ser conectado ao potenciômetro/trimpot de ajuste de brilho     *
******************************************************************************/

/******************************************************************************
* Ligações do Sensor HC-SR04                                                  *
*  Trig -> Pino RC0 do PORTC                                                  *
*  Echo -> Pino RC1 do PORTC                                                  *
*  VCC -> Deve ser conectado ao +5V                                           *
*  GND -> Deve ser conectado ao GND                                           *
******************************************************************************/
 
#use fast_io(c)//O Controle de direção (Entrada/Saida) dos pinos será feito no programa
#use fast_io(d)//O Controle de direção (Entrada/Saida) dos pinos será feito no programa

#byte PORTC = 0x07//Endereço do PORTC
#byte PORTD = 0x08//Endereço do PORTD

#bit Trig = PORTC.0 //pino que dispara o ultrasom
#bit Echo = PORTC.1 //pino que lê a resposta


//Declaração de funções
//const float k = 182; // 109 litros (capacidade) / 600mm = 0,182 por isso utilizei 182 /10 = 0,182litros a constante para 1 mm
unsigned int16 ler_US(void); //função que lê e retorna a distância em mm
void exibe_distancia(unsigned int16);//rotina que converte a distância em caracteres e envia para o LCD
void porcentagem (unsigned int16);

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   // TODO: USER CODE!!
   
   //Os Pinos RD2 a RD7 são usados pelo LCD, os pinos RD0 e RD1 estão livre para uso
   set_tris_d(0b00000000);//Configurando todos os pinos como saída
   //Os pinos Trig e Echo estão conectados no PORTC, Trig -> RC0 e Echo -> RC1
   set_tris_c(0b00000010);//Pino RC1 como entrada e o restante como saída
   
   PORTC = 0;//Inicia com todos os pinos que forem saída em zero
   PORTD = 0;//Inicia com todos os pinos que forem saída em zero
 
   configura_lcd();//Chama a rotina que faz as configurações básica para o LCD funcionar
   inicio_lcd();//Coloca o cursor no inicio
   limpa_lcd();//Limpra o LCD
   
   linha_1_lcd(3);//Começa a escrever apartir do caracter 4 na primeira linha
   caracter_lcd('N');
   caracter_lcd('I');
   caracter_lcd('V');
   caracter_lcd('E');
   caracter_lcd('L');
   caracter_lcd(':');
   caracter_lcd(' ');
   
   linha_2_lcd(3);//Começa a escrever apartir do caracter 4 na primeira linha
   caracter_lcd('A');
   caracter_lcd('p');
   caracter_lcd('r');
   caracter_lcd('o');
   caracter_lcd('x');
   caracter_lcd(':');
   caracter_lcd(' ');
 
   while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
     
      linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      Porcentagem(((exibe_distancia) * 100) / 133) ;
     
      }

 //{
   //   linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
     // delay_ms(250);
     // Porcentagem(((exibe_distancia) * 100) / 133) ; // transforma os litros medidos em %.
     
     // }




}

unsigned int16 ler_US(void)//Esta rotina realiza a leitura da distancia e a retorna em mm
   {
   unsigned int16 vl_timer = 0;//Variavel para armazenar o tempo
   unsigned int16 distancia = 0;//Armazena a distancia convertida
   Trig = 1;//Dispara o Ultrasom
   delay_us(20);//Aguarda um tempo (minimo de 10us)
   Trig = 0;//Volta para 0 (zero)
   
   while(!Echo){}//Aguarda começar a enviar a resposta
   
   set_timer1(0);//Reinicia o TIMER1
         
   while(Echo){}//Fica parado até receber a resposta
   
   vl_timer = get_timer1();//Le o tempo em que ficou recebendo a resposta (Tempo de instrução / 2 em uS)

   distancia = (((((vl_timer * 2) * 10) / 58) + 10));//Como o divisor do TIMER1 estar 1:2, multiplicamos por 10, passo para mm (x 10) e converto ( / 58)
   return distancia;//A função retorna o valor convertido em mm
   }

void exibe_distancia(unsigned int16 distancia)//Rotina responsavel por converter em caracter e enviar a distância
   {
   unsigned int16 x;//declara uma váriavel auxiliar
   
   x = distancia / 10000;//Pega a dezena de milhar(Ex: 12345, pega apenas o '1') Inteiro de 12345/10000
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia / 1000;//Pega a Dezena e Unidade de Milhar (Ex: 12345, pega '12') Inteiro de 12345/1000
   x = x % 10; //Pega a Unidade de milhar (Ex: 12345, pega apenas '2') resto da divisão 12/10
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x); //Envia para o LCD
   
   x = distancia / 100; //Pega dezena, unidade de milhar e a centena (Ex:12345, pega '123') Inteiro de 12345/100
   x = x % 10; //Pega a centena (Ex: 12345, pega apenas '3') o resto da divisão 123/10
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia / 10; //Pega dezena e unidade de milhar, centena e desena (Ex: 12345, pega '1234') Inteiro de 12345/10
   x = x % 10; //Pega a dezena (Ex: 12345, pega apenas '4') o resto da divisão 1234/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia % 10;//Pega a unidade (Ex: 12345, pega apenas '5')  Resto de 12345/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   caracter_lcd('l');
   caracter_lcd('t');//Exibe mm   
   }




Sera que alguem pode me esclarecer o que esta errado?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 02 Set 2014 14:32

Sera que alguem pode me dar uma luz para resolver este problema?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor ze » 02 Set 2014 15:27

here? where?
geralmente dando duplo click na mensagem, vai no local do erro
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 02 Set 2014 16:02

Caro ze,

Voce leu o primeiro trecho da postagem que fiz no dia 20/08? Lá é o local onde esta o problema. Resumindo agora que apresentar o valor que esta em litros na primeira linha em % na segunda linha. So não sei o que tenho que alterar ou acrecentar.

Pra ficar mais facil entender o trecho referido,onde na segunda linha (porcentagem) aparece a mensagem de erro : A numeric expression must appear here.

Código: Selecionar todos

while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
     
      linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250);
      Porcentagem(((exibe_distancia) * 100) / 133) ; //transforma distancia / litros em valor por %.
     
      }



Segundo no amigo andre disse a uns dias atras


Re: Sensor de nivel utilizando hcsr04
Mensagem por andre_teprom » 14 Ago 2014 19:39

Você teria de criar uma nova função para isso, pois a rotina exibe_distancia utiliza 4 dígitos, e imprime o ''mm'' após, e também não considera o ponto decimal. Não seria complicado, mas um pouco trabalhos, pois demandaria diversas tentativas-e-erro, que apenas com um display do lado dá pra simular e ir corrigindo linha por linha.


Não estou sabendo fazer isso pois este codigo do programa foi modificado ( o programa consegui quando comprei o hcsr04 e modifiquei para minha necessidade) e eu ainda sou meio inexperiente em trabalhos com lcd.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor MOR_AL » 02 Set 2014 22:28

Bom.
Tive problema com minha água.
No início pensei em fazer um sistema para monitorar a altura da água na caixa. Como a caixa fica na laje do telhado, pensei em usar um uC para transmitir a leitura via aqueles módulos de 433MHz. Um segundo uC receberia a medida e mostraria no display. Um alarme seria acionado, caso o nível da água ficasse abaixo de um valor preestabelecido por mim. Parecia legal, mas comecei a esbarrar em alguns pontos negativos:
Dois uC, um par Tx/Rx em 433MHz, fonte de alimentação no telhado, potência na transmissão para o receptor identificar os dados, etc.
Aí pensei naquele ditado que diz: "O ótimo é o inimigo do bom". Tinha que resolver o problema de modo mais simples e confiável possível.
Tá legal, que saber quanta água (256 níveis distintos) tem na caixa seria ótimo, mas seria realmente necessário?
Aí mudei radicalmente o pensamento e solucionei o problema de modo bem simples, barato e funcional.
Fiz uma boia constituída por uma ampola de mercúrio e dois eletrodos. Sei que, hoje em dia, usar mercúrio não é uma boa, mas tenho quase 200 dessas ampolas, então usei.
Já há nas lojas de material de construção aquelas boias para caixa d'água (sem mercúrio), que ligam a bomba quando o volume da água fica baixo. Até comprei, mas a qualidade parecia XingLing. Não durou 3 meses.
A ampola fica dentro de um tubo de remédio. Tem um peso e espaço livre. Isso para forçar o tubo a ficar vertical (chave aberta) quando há água. Sem o peso, movendo o centro de gravidade para o extremo que contém a saída dos fios, a boia ficaria na horizontal e qualquer movimento da água acionaria o dispositivo (uma lâmpada de 5W e uma campainha). A rigidez dos fios que chegam à boia também forçam a posição do tubo e disparos indevidos ocorreram.
Quando a água baixava para cerca de 20% da capacidade total, a campainha dava o alerta sonoro e a lâmpada acendia. A campainha comum foi projetada para toques esporádicos e curtos. Para não queimar a campainha, coloquei um interruptor em série com ela. Assim posso desligá-la assim que toca. Claro que tem gente em casa quando o alarme dispara. A exceção seria haver um vazamento na casa. Aí a campainha vai pro brejo. Com a chave da campainha desligada, fico monitorando a lâmpada de 5W. Com o retorno da água na caixa, a lâmpada apaga e eu torno a ligar o interruptor da campainha.
A altura da boia é determinada por um nó no fio paralelo, que fica preso na borda da caixa d'água. Retirei da borda da caixa, um retângulo com cerca de 10mm de profundidade por 5mm de largura. O nó fica limitado neste retângulo.
Depois descobri que quando o alarme tocava já tinha pouca água, o que não é bom, né? Então alterei a localização do nó para disparar o alarme com cerca de 65% da água na caixa. Ficou beleza. Dava para tentar resolver o problema a tempo de não faltar água.
Espero que esta narrativa do meu caso possa ser útil.
MOR_AL
"Para o triunfo do mal só é preciso que os bons homens não façam nada." Edmund Burke.
"Nunca discutas com pessoas estúpidas. Elas irão te arrastar ao nível delas e vencê-lo por possuir mais experiência em ser ignorante". Mark Twain
Avatar do usuário
MOR_AL
Dword
 
Mensagens: 2934
Registrado em: 19 Out 2006 09:38
Localização: Mangaratiba - RJ

Re: Sensor de nivel utilizando hcsr04

Mensagempor ze » 03 Set 2014 08:03

carlucio escreveu:Caro ze,

Voce leu o primeiro trecho da postagem que fiz no dia 20/08?....


perdão mas preferi não ler as páginas todas. preguiça... sacuméquié. e ainda não consegui localizar facilmente a linha problemática. idade... sacuméquié. bom... verifique se os argumentos das funções estão como tipo correto. por enquanto é só isso que intuo.
sugiro criar novo post. muitas páginas... enjoativo
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 06 Set 2014 14:14

Pessoal, ainda não penso em desistir até alguem me orientar. Ja esta quase pronto falta so resolver a parte de colocar porcentagem na 2º linha do display.

Código: Selecionar todos
#include <16F877A.h>
#device *=16
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)

#ZERO_RAM

//#define k_vazio 130
//#define k_cheio 113
#include <LCD_MSS.h>
/******************************************************************************
*  Ligações do LCD                                                            *
*   D7 -> RD7 (PORTD 7)                                                       *
*   D6 -> RD6 (PORTD 6)                                                       *
*   D5 -> RD5 (PORTD 5)                                                       *
*   D4 -> RD4 (PORTD 4)                                                       *
*   RS -> RD3 (PORTD 3)                                                       *
*   EN -> RD2 (PORTD 2)                                                       *
*   R/W -> Deve ser conectado ao GND                                          *
*   VCC -> Deve ser conectado ao +5V                                          *
*   GND -> Deve ser conectado ao GND                                          *
*   VO -> Deve ser conectado ao potenciômetro/trimpot de ajuste de brilho     *
******************************************************************************/

/******************************************************************************
* Ligações do Sensor HC-SR04                                                  *
*  Trig -> Pino RC0 do PORTC                                                  *
*  Echo -> Pino RC1 do PORTC                                                  *
*  VCC -> Deve ser conectado ao +5V                                           *
*  GND -> Deve ser conectado ao GND                                           *
******************************************************************************/
 
#use fast_io(c)//O Controle de direção (Entrada/Saida) dos pinos será feito no programa
#use fast_io(d)//O Controle de direção (Entrada/Saida) dos pinos será feito no programa

#byte PORTC = 0x07//Endereço do PORTC
#byte PORTD = 0x08//Endereço do PORTD

#bit Trig = PORTC.0 //pino que dispara o ultrasom
#bit Echo = PORTC.1 //pino que lê a resposta


//Declaração de funções
//const float k = 182; // 109 litros (capacidade) / 600mm = 0,182 por isso utilizei 182 /10 = 0,182litros a constante para 1 mm
unsigned int16 ler_US(void); //função que lê e retorna a distância em mm
void exibe_distancia(unsigned int16);//rotina que converte a distância em caracteres e envia para o LCD
void porcentagem (unsigned int16);

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   // TODO: USER CODE!!
   
   //Os Pinos RD2 a RD7 são usados pelo LCD, os pinos RD0 e RD1 estão livre para uso
   set_tris_d(0b00000000);//Configurando todos os pinos como saída
   //Os pinos Trig e Echo estão conectados no PORTC, Trig -> RC0 e Echo -> RC1
   set_tris_c(0b00000010);//Pino RC1 como entrada e o restante como saída
   
   PORTC = 0;//Inicia com todos os pinos que forem saída em zero
   PORTD = 0;//Inicia com todos os pinos que forem saída em zero
 
   configura_lcd();//Chama a rotina que faz as configurações básica para o LCD funcionar
   inicio_lcd();//Coloca o cursor no inicio
   limpa_lcd();//Limpra o LCD
   
   linha_1_lcd(3);//Começa a escrever apartir do caracter 4 na primeira linha
   caracter_lcd('N');
   caracter_lcd('I');
   caracter_lcd('V');
   caracter_lcd('E');
   caracter_lcd('L');
   caracter_lcd(':');
   caracter_lcd(' ');
   
   linha_2_lcd(3);//Começa a escrever apartir do caracter 4 na primeira linha
   caracter_lcd('A');
   caracter_lcd('p');
   caracter_lcd('r');
   caracter_lcd('o');
   caracter_lcd('x');
   caracter_lcd(':');
   caracter_lcd(' ');
 
   while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
     
      linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      Porcentagem(((exibe_distancia) * 100) / 133) ;  ----------------->>>> o problema aparece aqui
     
      }

 //{
   //   linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
     // delay_ms(250);
     // Porcentagem(((exibe_distancia) * 100) / 133) ; // transforma os litros medidos em %.
     
     // }




}

unsigned int16 ler_US(void)//Esta rotina realiza a leitura da distancia e a retorna em mm
   {
   unsigned int16 vl_timer = 0;//Variavel para armazenar o tempo
   unsigned int16 distancia = 0;//Armazena a distancia convertida
   Trig = 1;//Dispara o Ultrasom
   delay_us(20);//Aguarda um tempo (minimo de 10us)
   Trig = 0;//Volta para 0 (zero)
   
   while(!Echo){}//Aguarda começar a enviar a resposta
   
   set_timer1(0);//Reinicia o TIMER1
         
   while(Echo){}//Fica parado até receber a resposta
   
   vl_timer = get_timer1();//Le o tempo em que ficou recebendo a resposta (Tempo de instrução / 2 em uS)

   distancia = (((((vl_timer * 2) * 10) / 58) + 10));//Como o divisor do TIMER1 estar 1:2, multiplicamos por 10, passo para mm (x 10) e converto ( / 58)
   return distancia;//A função retorna o valor convertido em mm
   }

void exibe_distancia(unsigned int16 distancia)//Rotina responsavel por converter em caracter e enviar a distância
   {
   unsigned int16 x;//declara uma váriavel auxiliar
   
   x = distancia / 10000;//Pega a dezena de milhar(Ex: 12345, pega apenas o '1') Inteiro de 12345/10000
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia / 1000;//Pega a Dezena e Unidade de Milhar (Ex: 12345, pega '12') Inteiro de 12345/1000
   x = x % 10; //Pega a Unidade de milhar (Ex: 12345, pega apenas '2') resto da divisão 12/10
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x); //Envia para o LCD
   
   x = distancia / 100; //Pega dezena, unidade de milhar e a centena (Ex:12345, pega '123') Inteiro de 12345/100
   x = x % 10; //Pega a centena (Ex: 12345, pega apenas '3') o resto da divisão 123/10
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia / 10; //Pega dezena e unidade de milhar, centena e desena (Ex: 12345, pega '1234') Inteiro de 12345/10
   x = x % 10; //Pega a dezena (Ex: 12345, pega apenas '4') o resto da divisão 1234/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = distancia % 10;//Pega a unidade (Ex: 12345, pega apenas '5')  Resto de 12345/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   caracter_lcd('l');
   caracter_lcd('t');//Exibe mm   
   }




A seguinte mensagem : "
A numeric expression must appear here.
", aparece no trecho a seguir:

Código: Selecionar todos

while(1)//Loop infinito do programa
      {
      linha_1_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
     
      linha_2_lcd(10);//Imprime a distância apartir do caracter 10
     
      delay_ms(250);
      Porcentagem(((exibe_distancia) * 100) / 133) ; //transforma distancia / litros em valor por %.



No inicio do programa fiz a seguinte referencia no codigo ( a variavel para porcentagem) :
Código: Selecionar todos
//Declaração de funções
//const float k = 182; // 109 litros (capacidade) / 600mm = 0,182 por isso utilizei 182 /10 = 0,182litros a constante para 1 mm
unsigned int16 ler_US(void); //função que lê e retorna a distância em mm
void exibe_distancia(unsigned int16);//rotina que converte a distância em caracteres e envia para o LCD
void porcentagem (unsigned int16); -------->>> Não sei se esta certo assim ou falta alguma coisa


E o programa quando compilado faz aquela mensagem acima na qual sitei :
A numeric expression must appear here.
.

Pessoal não estou pedindo para ninguem fazer o codigo pronto para mim, apenas que me oriente no que tenho que fazer / consertar pra funcionar.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor andre_luis » 07 Set 2014 06:48

Voce está instanciando a função exibe_distancia sem argumento algum na ultima linha do código acima.
Deveria ser algo do tipo exibe_distancia(xxxx)
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Sensor de nivel utilizando hcsr04

Mensagempor ze » 08 Set 2014 09:07

aqui ó...
"Porcentagem(((exibe_distancia) * 100) / 133) ; //transforma distancia / litros em valor por %."
mesmo assim não daria certo. exibe_distancia() não retorna nada. talvez você queira usar
"Porcentagem((ler_US() * 100) / 133) ; //transforma distancia / litros em valor por %."
sucessos
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Sensor de nivel utilizando hcsr04

Mensagempor andre_luis » 08 Set 2014 13:21

Outra coisa que pode dar problema, é que na chamada anterior há 2 ponto-e-virgula ( ;; ) no final da função:

exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 08 Set 2014 17:47

Caro andre e ze.

Suas informaçoes foram muito importantes para o resultado abaixo:




Foram ascrecentados e alterados as seguintes dados:

Código: Selecionar todos
unsigned int16 ler_US(void); //função que lê e retorna a distância em mm
unsigned int16 nivel_porcento(void); //função que lê e retorna a distância em mm --->>>acrescentado
void exibe_distancia(unsigned int16);//rotina que converte a distância em caracteres e envia para o LCD
void porcentagem (unsigned int16);





Código: Selecionar todos
while(1)//Loop infinito do programa
      {
      linha_1_lcd(12);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      exibe_distancia( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;;//Chama a rotina que exibe a distancia no LCD, e passa como parametro a distancia lida em ler_US()
    //  }
     
    //  {
      linha_2_lcd(12);//Imprime a distância apartir do caracter 10
     
      delay_ms(250); //Garante o tempo minimo para aquisição de nova distancia (O fabricante exige minimo 50ms)
      porcentagem (((nivel_porcento() * 100) / 133 )); --->>> a mudança conforme orientado
     
      }

}




A inclusão de uma variavel de conversão para %:

Código: Selecionar todos

unsigned int16 nivel_porcento(void)
{

unsigned int16 conversao = 0;

conversao=( ( ( (710 - ler_US() ) * 50 ) >> 8 ) ) ;
return conversao;
}




E a rotina para apresentação na 2º linha do display:

Código: Selecionar todos
 void porcentagem(unsigned int16 conversao)
 {
 unsigned int16 x;//declara uma váriavel auxiliar
   
     
   x = conversao / 100; //Pega dezena, unidade de milhar e a centena (Ex:12345, pega '123') Inteiro de 12345/100
   x = x % 10; //Pega a centena (Ex: 12345, pega apenas '3') o resto da divisão 123/10
   x = x + 48; //Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = conversao / 10; //Pega dezena e unidade de milhar, centena e desena (Ex: 12345, pega '1234') Inteiro de 12345/10
   x = x % 10; //Pega a dezena (Ex: 12345, pega apenas '4') o resto da divisão 1234/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   
   x = conversao % 10;//Pega a unidade (Ex: 12345, pega apenas '5')  Resto de 12345/10
   x = x + 48;//Converte em caracter ASCII
   caracter_lcd(x);//Envia para o LCD
   caracter_lcd('%');
   
   }



Queria saber como fazer para quando o nivel ficar abaixo de 20% a indicação da porcentagem ficasse piscando a 2 vezes por segundo e abaixo de 10% quatro vezes por segundo.
Alguem pode me dar uma dica?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Sensor de nivel utilizando hcsr04

Mensagempor carlucio » 11 Set 2014 21:25


Queria saber como fazer para quando o nivel ficar abaixo de 20% a indicação da porcentagem ficasse piscando a 2 vezes por segundo e abaixo de 10% quatro vezes por segundo.
Alguem pode me dar uma dica?




Queria saber se desta forma a qual se usa para lançar os valores no display, no caso a rotina de apresentação do display, tem como fazer um if ou while cercando os valores acima citados para conseguir piscar a porcentagem quando se estivesse no referido valor.

EX:

cpp code
if (porcentagem <= 20)
{

x = conversao / 10; //Pega dezena e unidade de milhar, centena e desena (Ex: 12345, pega '1234') Inteiro de 12345/10
x = x % 10; //Pega a dezena (Ex: 12345, pega apenas '4') o resto da divisão 1234/10
x = x + 48;//Converte em caracter ASCII
caracter_lcd(x);//Envia para o LCD
limpa_lcd();//Limpra o LCD
delay_ms(500);
caracter_lcd(x);//Envia para o LCD


x = conversao % 10;//Pega a unidade (Ex: 12345, pega apenas '5') Resto de 12345/10
x = x + 48;//Converte em caracter ASCII
caracter_lcd(x);//Envia para o LCD
caracter_lcd('%');
limpa_lcd();//Limpra o LCD
delay_ms(200);
caracter_lcd(x);//Envia para o LCD
caracter_lcd('%');



Seria dessa forma que deveria declarar e seria abaixo da rotina de apresentação do lcd?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x