Oi boa tarde, estou fazendo um projeto do sensor fs300 que vai emitir o sinal para o arduino que passara a leitura para o lcd, usei a ligal so sensor nesta figura a seguir.
soh que fiz a ligacao do lcd na figura a seguir.
soh coloquei a ligação nos pinos 4,5,6,7,8,9, respectivamente, o lcd ligou, msd tem um sombreado na parte de baixo, gostaria de saber o que poderia ser ,
desde ja agradeço
se puder me orientar tenha a programacao, soh queria colocar as varieaveis
segue em anexo em portugues
#include <LiquidCrystal.h>
// Inicializa a libraria do lcd com os pinos de interface
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
// Especifica os pinos para os dois botoes de reset dos contadorese o led indicador de estado
byte reset_total_A = 11;
byte reset_total_B = 12;
byte led_de_estado = 13;
byte interrupt_do_sensor = 0; // 0 = pino 2; 1 = pino 3
byte pino_do_sensor = 2;
// O sensor de fluxo por efeito Hall envia 4.5 pulsos por segundo por litro de fluxo
float factor_calibragem = 4.5;
volatile byte contagem_pulsos = 0;
float fluxo = 0.0;
unsigned int fluxo_ml = 0;
unsigned long ml_total_A = 0;
unsigned long ml_total_B = 0;
unsigned long tempo_antigo = 0;
void setup() {
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
// Inicializa a conexao serial para comunicar com o pc
Serial.begin(38400);
// Define os pinos do led indicador de estaddo como saida
pinMode(led_de_estado, OUTPUT);
digitalWrite(led_de_estado, HIGH); // ativa o led indicador de estado
// Define os botoes de reset e ativa os resistores pullup internos
pinMode(reset_total_A, INPUT);
digitalWrite(reset_total_A, HIGH);
pinMode(reset_total_B, INPUT);
digitalWrite(reset_total_B, HIGH);
pinMode(pino_do_sensor, INPUT);
digitalWrite(pino_do_sensor, HIGH);
// O sensor de efeito Hall esta conetado ao pino 2 e usa a interupcao 0.
// Configurado para mudança de estado FALLING (transicao de estado HIGH para estado LOW)
attachInterrupt(interrupt_do_sensor, contador_de_pulsos, FALLING);
}
/**
* Ciclo principal
*/
void loop() {
if (digitalRead(reset_total_A) == LOW) {
ml_total_A = 0;
lcd.setCursor(0, 1);
lcd.print("0L ");
}
if (digitalRead(reset_total_B) == LOW) {
ml_total_B = 0;
lcd.setCursor(8, 1);
lcd.print("0L ");
}
if ((digitalRead(reset_total_A) == LOW) || (digitalRead(reset_total_B) == LOW)) {
digitalWrite(led_de_estado, LOW);
}
else {
digitalWrite(led_de_estado, HIGH);
}
if((millis() - tempo_antigo) > 1000) { // Apenas processar os contadores a cada um segundo
detachInterrupt(interrupt_do_sensor); // Desactivar o interupt enquanto calculamos o fluxo e envio do valor
//lcd.setCursor(15, 0);
//lcd.print("*");
// Por causa de este ciclo poder não ser executado em intervalos de um segundo
// calculamos os milissegundos que passaram desde a ultima execução e usamos esse
// valor apra a escala do calculo. Também é aplicado o factor de calibração baseado no
// numero de pulsos por segundo por litro (litros/minuto nestes caso) emitidos pelo sensor.
fluxo = ((1000.0 / (millis() - tempo_antigo)) * contagem_pulsos) / factor_calibragem;
// Anotar o tempo no qual fazemos este calculo. Repara que neste caso porque nós
// interrompemos os interrupts a função millis() não está incrementando e vai nos
// retornar o valor de millisegundos de quando nós desactivamos os interrupts.
tempo_antigo = millis();
// Dividir o fluxo em litros/minuto por 60 para determinar quantos litros passaram no
// sensor neste intervalo de 1 segundo, e multiplicar por 1000 para converter em ml.
fluxo_ml = (fluxo / 60) * 1000;
// Adicionar os mililitros medidos neste segundo ao total cumulativo
ml_total_A += fluxo_ml;
ml_total_B += fluxo_ml;
// Durante o teste pode ser util imprimir a variavel de contagem dos pulsos
// para poder ser comparado com o fluxo esperado no datasheet do sensor.
Serial.print(contagem_pulsos, DEC);
Serial.print(" ");
// Escrever o valor calculado para a porta serial. Porque queremos imprimir um valor
// fracional e print() não suporta, faremos um calculo para imprimir a parte inteira,
// o ponto decimal e a parte fracional.
unsigned int fracao;
// Imprime o fluxo neste segundo em litros/minuto
Serial.print(int(fluxo)); // Imprime a parte inteira da variavel de fluxo
Serial.print("."); // Imprime o ponto decimal
// Calcula a parte fracional. O multiplicador 10 calcula 1 casa decimal.
fracao = (fluxo - int(fluxo)) * 10;
Serial.print(fracao, DEC) ; // Imprime a parte fracional da variavel de fluxo
// Imprime o numero de litros fluidos neste segundo
Serial.print(" "); // Separador
Serial.print(fluxo_ml);
// Imprime o total cumulativo de litros desde o inicio
Serial.print(" "); // Separador
Serial.print(ml_total_A);
Serial.print(" "); // Separador
Serial.println(ml_total_B);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Fluxo: ");
if(int(fluxo) < 10) {
lcd.print(" ");
}
lcd.print((int)fluxo); // Imprime a parte inteira da variavel de fluxo
lcd.print('.'); // Imprime o ponto decimal
lcd.print(fracao, DEC) ; // Imprime a parte fracional da variavel de fluxo
lcd.print(" L");
lcd.print("/min");
lcd.setCursor(0, 1);
lcd.print(int(ml_total_A / 1000));
lcd.print("L");
lcd.setCursor(8, 1);
lcd.print(int(ml_total_B / 1000));
lcd.print("L");
// Resetar a contagem de pulsos
contagem_pulsos = 0;
// Ativa a interrupt do sensor novamente
attachInterrupt(interrupt_do_sensor, contador_de_pulsos, FALLING);
}
}
/**
* Chamado por interrupt0 uma vez por cada rotação do sensor de efeito hall.
*/
void contador_de_pulsos() {
// Incrementa a variavel de contagem dos pulsos
contagem_pulsos++;
}
.
Tags:
Agora me diz em que parte dessa programação foi usado o pino 2? o pino que vem do sensor...
byte interrupt_do_sensor = 0; // 0 = pino 2; 1 = pino 3
byte pino_do_sensor = 2;
isso é só declaração de variavel.
Exato.
Olá Giuliano. ^^
Dei uma olhada no seu código e no seu esquema elétrico, e observei um erro.: existe diferença entre o esquema que você mostrou e projeto que está no código. Então teríamos a oportunidade de arrumar o código, ou arrumar o esquema. Como existe mais alguma coisa para mexer no esquema elétrico, optei por alterá-lo e manter o que existe no código.
O primeiro erro é o pino 2, que está sendo usado tanto pelo sensor quanto pelo LCD.
O segundo erro é a declaração dos pinos do LCD na função "LiquidCrystal lcd(9, 8, 7, 6, 5, 4);"
E uma característica que não apareceu no esquema é que existem 2 botões de reset, chamados RESET A e RESET B.
A solução melhor é você refazer as ligações se possível. Montei um esquema elétrico para você se guiar. Além de ter montado a planta do seu projeto no simulador PROTEUS.
Compilei o código, não houve nenhum erro de compilação. E consegui simular ele no PROTEUS.
A ligação do sensor você pode manter da mesma forma.
Estarei anexando os arquivos, do Proteus, do Arduino, a imagem do esquema e o código .hex.
Se quiser as bibliotecas do Arduino no Proteus, visite: http://blogembarcado.blogspot.com.br
Abaixo a imagem do esquema e do seu projeto simulado funcionando.
Espero que tenha lhe ajudado. Boa sorte no projeto.
Att.
amigo, poderia explicar esse programa seu? como é contada a vazão? não consigo visualizar onde o pino_do_sensor está sendo usado. Como já vi em vários lugares esse programa, creio que o erro está na minha cabeça! uahhuaha se puder me ajudar a entender eu agradeço. Obrigado
Olá Eduardo.
Acho que a pergunta seria para o Giuliano, pois só verifiquei os erros no programa dele, mas creio que posso lhe responder. =]
Me parece que a sua dúvida é quanto a contagem da vazão e a relação com o pino do sensor.
O que acontece é o seguinte:
1)Logo no inicio do programa tem uma linha que diz qual é o pino utilizado pelo sensor, que é:
byte pino_do_sensor = 2;
2)Depois você precisa falar para o Arduino que este pino é uma entrada, para que possa ser feita uma leitura dele.E também precisa ser habilitado o "pull-up" deste pino. Então temos dentro da rotina "void setup()":
pinMode(pino_do_sensor, INPUT);
digitalWrite(pino_do_sensor,HIGH);
3)Agora que já configuramos o pino como entrada, precisamos dizer como será feita a leitura. Você poderia sim usar a função "digitalRead(pino_do_sensor)", que é uma técnica que chamamos de "pooling", onde você precisa ficar perguntando a todo momento ao pino qual o estado dele.
O problema é quando o pulso que aparece neste pino tem curta duração, então se demorarmos muito tempo para olhar ele novamente e perguntar qual o seu estado, o pulso já passou e ficamos sem saber que houve o pulso. Ou mesmo se for em um programa que tem vários outros controles e funções rodando ao mesmo tempo, e como precisamos ficar olhando este pino também, iriamos consumir muito processamento (entre aspas. ^^) só para olhar o pino, e isto poderia afetar outras funções.
Então para resolver o autor do programa usou uma interrupção ligada ao pino do sensor. Verificamos isto na linha:
attachInterrupt(interrupt_do_sensor, contador_de_pulsos, FALLING);
Olhando para as linhas temos que:
a) interrupt_do_sensor: Se configurado como "0" ele olhará o pino 2 do Arduino.
Se configurado como "1" ele olhará o pino 3 do Arduino.
b)contador_de_pulsos: É o nome da função que irá fazer a contagem dos pulsos.
Se olhar ao final do programa esta função está lá só incrementando uma variável. Caso queira fazer uma experiência, você pode mudar o nome desta função para uma chamada por exemplo: "acende_led", e dentro da função você manda acender um pino para acender um led por exemplo.
c)FALLING: ou "queda" em inglês. Quer dizer que você ficará olhando no pino 2 todas as transições de borda (edge) do sinal do sensor, que vai de "1" para "0".
Então, todas as vezes que o sinal mudar de "1" para "0" ele irá chamar a função "contador_de_pulsos" para incrementar a variável que mede a vazão.
Caso queira usar mais de um sensor, você iria copiar a linha de cima, e criar a configuração para outro pino do Arduino. Algo do tipo:
byte interrupt_do_sensor_2 = 1; // pino 3 do Arduino.
volatile byte contagem_pulsos_2 = 0;
attachInterrupt(interrupt_do_sensor_2, contador_de_pulsos_2, FALLING);
void contador_de_pulsos_2() {
// Incrementa a variavel de contagem dos pulsos do sensor 2
contagem_pulsos_2++;
}
Acho que é só tudo isso. rs
Precisando de algo e eu puder ajudar, é só pedir.
Att.
acho que to começando a entender... então quer dizer que os pinos de interrupção do arduino sao o 2 e o 3, certo?
Olá Eduardo. ^^
Então, você está correto, nos pinos 2 e 3 do Arduino estão disponíveis as interrupções do periférico de interrupção externa INT0 e INT1, dos ports PD2 e PD3 do microcontrolador.( ref. ATMEGA328)
Isso é diretamente relacionado aos ports do microcontrolador que possuem estes periféricos de interrupções, que podem ficar "transparentes" devido a biblioteca do Arduino.
O que quero dizer é que hoje escolhemos entre a interrupção externa 0 ou 1 (devido a biblioteca do Arduino), e isto faria a gente ler os sinais de interrupção nos pinos 2 e 3 (devido ao Hardware do Arduino), isso porque os ports do microcontrolador que possuem estas interrupções são o PD2 e PD3(devido ao MCU), e estes são os que estão ligados aos pinos 2 e 3 do Arduíno.
Parece confuso eu sei. ^^
Veja datasheet do ATMEGA328: http://www.atmel.com/Images/doc8161.pdf
Att.
mais uma pergunta... pra que serve esses 2 resets na programação? desculpe a amolação ai! huahuauha
rs, Relax. ^^
Pelo que entendi eles funcionam assim:
1) Quando você inicia a contagem da vazão, os dois devem contar exatamente iguais. E assim ficam direto.
2)Vamos supor que você queira ver qual a sua vazão durante uma hora, ou durante um dia inteiro, mas que ainda deseja saber quanto foi a vazão durante a semana toda. Então você teria que usar por exemplo o RESET A diariamente para saber a vazão do dia. Assim o outro valor estará totalmente acumulado.
E só ao final da semana você iria usar os 2 RESETS para acumular a leitura semanal novamente.
Mas tem formas melhores de fazer isto. Depende da aplicação.
Agora só testando para saber se entendi certo o programa. ^^
Você tem um sensor destes para o teste?
Att.
comprei... estou esperando receber! uhahuauha
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por