Faz um teste ai.
Retire todas as instruções println para o lcd, menos a que mostra a velocidade, tenta trabalhar com menos variaveis float, minhas suspeitas está em cima do ciclo do arduino do loop().
Ou coloque para as informções sairem na Serial.
Me de um feedback.
LegendBR:
Só vai passar de 96 km quando você passar de 115 km/h. Faça as contas e você vai entender.
Dica: millis() retorna um long, que não passa de um inteiro.
sera que se usar micros() resolve ??? nâo entendi direito
Vamos lá, seu problema está na matemática da coisa. A função millis() retorna um long, que é um valor inteiro. Fazendo as contas, você vai ver que, quando a velocidade é 96 km/h, é porque se passaram 6 milissegundos entre as duas leituras (3600 * 0.16 / 6 = 96). A próxima velocidade seria quando a diferença entre as duas leituras fosse de 5 milissegundos, que daria 3600 * 0.16 / 5 = 115.2. Como a diferença nunca vai dar 5.5, por exemplo, você não vai conseguir ler as velocidades intermediárias.
A função micros() pode resolver, mas você teria 2 questões:
a cada 70 minutos o micros() é zerado. Isso não traria muito impacto, somente a cada 70 minutos um valor estranho iria aparecer, mas logo seria substituído;
o display iria mostrar valores mudando muito rapidamente, e pode ficar pouco legível, pois a cada pequena variação de velocidade, a velocidade mostrada seria diferente.
Pense no velocímetro digital de um carro. Ele se atualiza em uma frequência constante (1 vez por segundo, por exemplo), ao invés de ficar se atualizando a cada pequena variação de velocidade. O que ele faz é pegar uma velocidade média naquele intervalo de 1 segundo, e acho que assim o velocímetro fica mais legível. Vou modificar o seu código para você ver como seria esse velocímetro com valor "médio":
#include <LiquidCrystal.h>
// Atualiza a cada 1000 milissegundos. Modificar para o tempo que te agradar melhor
#define REFRESH_TIME 1000
LiquidCrystal lcd(8,9,4,5,6,7);
long lastRefresh; // Para trabalhar com o millis(), use long, e não float.
float circMetric=0.16;
float speedk;
long loopCount; // Contador de giros
void setup()
{
attachInterrupt(0, speedCalc, RISING);
lcd.begin(16,2);
lcd.clear();
loopCount = 0;
lastRefresh = millis();
speedk = 0.0
}
void speedCalc()
{
loopCount++;
}
void loop()
{
if (millis() - lastRefresh >= REFRESH_TIME)
{
speedk = (3600*circMetric*loopCount)/(millis() - lastRefresh);
loopCount = 0;
lastRefresh = millis();
}
lcd.setCursor(5,0);
lcd.print(int(speedk));
lcd.print(" km/h ");
}
Testa esse código e o seu substituindo o millis() pelo micros(), e fazendo o ajuste no cálculo (speedk=(3600000*circMetric)/elapsed) e vê qual resultado te agrada mais. Depois posta se funcionou ;).
LegendBR:
Só vai passar de 96 km quando você passar de 115 km/h. Faça as contas e você vai entender.
Dica: millis() retorna um long, que não passa de um inteiro.
sera que se usar micros() resolve ??? nâo entendi direito
Vamos lá, seu problema está na matemática da coisa. A função millis() retorna um long, que é um valor inteiro. Fazendo as contas, você vai ver que, quando a velocidade é 96 km/h, é porque se passaram 6 milissegundos entre as duas leituras (3600 * 0.16 / 6 = 96). A próxima velocidade seria quando a diferença entre as duas leituras fosse de 5 milissegundos, que daria 3600 * 0.16 / 5 = 115.2. Como a diferença nunca vai dar 5.5, por exemplo, você não vai conseguir ler as velocidades intermediárias.
A função micros() pode resolver, mas você teria 2 questões:
a cada 70 minutos o micros() é zerado. Isso não traria muito impacto, somente a cada 70 minutos um valor estranho iria aparecer, mas logo seria substituído;
o display iria mostrar valores mudando muito rapidamente, e pode ficar pouco legível, pois a cada pequena variação de velocidade, a velocidade mostrada seria diferente.
Pense no velocímetro digital de um carro. Ele se atualiza em uma frequência constante (1 vez por segundo, por exemplo), ao invés de ficar se atualizando a cada pequena variação de velocidade. O que ele faz é pegar uma velocidade média naquele intervalo de 1 segundo, e acho que assim o velocímetro fica mais legível. Vou modificar o seu código para você ver como seria esse velocímetro com valor "médio":
#include <LiquidCrystal.h>
// Atualiza a cada 1000 milissegundos. Modificar para o tempo que te agradar melhor #define REFRESH_TIME 1000
LiquidCrystal lcd(8,9,4,5,6,7);
long lastRefresh; // Para trabalhar com o millis(), use long, e não float.
float circMetric=0.16;
float speedk;
long loopCount; // Contador de giros
lcd.setCursor(5,0);
lcd.print(int(speedk));
lcd.print(" km/h ");
}
Testa esse código e o seu substituindo o millis() pelo micros(), e fazendo o ajuste no cálculo (speedk=(3600000*circMetric)/elapsed) e vê qual resultado te agrada mais. Depois posta se funcionou ;).
Acabei de me registrar no forum,e gostaria da sua permissao pra usar o codigo do velocimetro, terminei nessa semana uma gaiola e pretendo fazer um mini computador de bordo, nao sei muito de programaçao e to apanhando qui nem gente grande.
Acabei de me registrar no forum,e gostaria da sua permissao pra usar o codigo do velocimetro, terminei nessa semana uma gaiola e pretendo fazer um mini computador de bordo, nao sei muito de programaçao e to apanhando qui nem gente grande.
Amigo, eu preciso de um programa com a mesma função que o seu, no entanto estou utilizando um sensor indutivo e não entendo muito de programação, mudaria muito? Teria como você mandar o esquema do seu circuito para eu dar uma olhada?
fiz o seguinte programa com arduino para fazer um velocimetro.
mais somente consegui fazer com que o arduino detecte os polos do ima. e conte a quantidade de vezes que o polo sul passou pelo ima.
estou usando um sensor que a saida dele fica em nivel alto, somente quando passa o polo sul do imã a saida vai para nivel baixo.
ou seja entao o arduino esta detectando a passagem do polo sul pelo sensor.
gostrai que alguem me ajudasse a fazer essa mediçao de velocidade.
estou utiltizando o sensor de efeito hall 277
ele tem quatro terminais dois sao alimentaçao e duas saidas.
uma das saidas a que estou utilizando ela fica em nivel alto somente com a pssagem do polo sul do imã ele vai para nivel baixo. e a outra saida e o inverso porem nao estou utilizando.
a partir desta contagem de quantas vezes a entrada foi para nivel baixo neste casso o (" i ")quero calcular a velocidade.
mais nao estou conseguindo manipular isto no arduino.
sei que vou precisar da formula de area.
e a velocidade= vai ser a quantidade de vezes que passou para o nivel baixo em 1 segundo * a area.
mais como colocar isso no programa?
ola pessoal. sou novo aqui no forum e isto é justamente o que procuro um velocimetro a baixo custo, mas gostaria que tivesse uma saida digital do tipo BCD alem da informacao no LCD. E tambem gostaria que a leitura fosse a velocidade real do veiculo e nao as leituras erroneas do velocimetro original do carro. Acho que meu carro usa sensor hall o carro eh uma ecosport 1.6 zetec rocam. Obrigado.
olá,sou novo aki no Fórum, Gostaria de uma ajuda, achei interessante o codigo do velocimetro, usei ele mas não consegui a leitura do sensor hall, como faço para definir a porta do sinal do sensor, muito obrigado.
luisilva:
O sensor é lido por interrupção, por isso deve ser ligado ao pino 0:
attachInterrupt(0, speedCalc, RISING);
Boas.
Permita discordar.
O sensor deve ser ligado no pino 2(em Arduino Uno): (#define PMS_PIN 2)
O código que fez quote (attachInterrupt(0, speedCalc, RISING) refere a interrupção 0, a função a chamar, e em que tipo de actividade no pino, que é referente ao pino 2.
Podem ver AQUI o código das interrupções e a forma de as usar..