Mi problema es que el sensor magnetici en vez de marcarme solo un pulso en el contador acsa vez que pasa el iman cerca de el, me marca varios seguidos cuando pasa despacio o por veces.
A ver si alguien me puede echar una mano a solucionar el problema.
int lectura=LOW; // Lectura guarda la lectura en reposo que es LOW
int lectura1= digitalRead(sonda); // Lectura1 guarda la lectura de la sonda
if (lectura != lectura1){ // Si lectura1 y Lectura son distintas
delay(5); // Se espera 100 milisegundos
contador++; // Sumamos 1 al contador de vueltas de la rueda
kmReales=(contador*diametroCalibracion)/10000;// Calculamos los Km Reales con esa fórmula
kmEntero=abs(kmReales); // Guardamos el número entero de los Km reales
s= kmEntero%10; // Cálculo del número a mostrar en las unidades
S= (kmEntero/10)%10; // Cálculo del número a mostrar en las Decenas
m= (kmEntero/100)%10; // Cálculo del número a mostrar en las Centenas
M= (kmEntero/1000); // Cálculo del número a mostrar en los Millares
}
Por el poco código que pones, entiendo que el sensor magnético, es para medir distancia, y que debe estar en una rueda. Bueno, el primer error está en el analogRead. Un sensor de ese tipo, lo que debe detectar, son pulsos por vuelta. Eso debe estar en una entrada digital, y más aún, cuando comparas lectura con lectura1, siendo lectura=LOW y no un valor de lectura analógico.
Por último, asegúrate de que el sensor está lo más cerca posible del imán, y cuando digo cerca, digo pocos milímetros, cono 2 o 3 mm máximo, ya que a más, puede que no funcione bien.
Lo de analogicRead esta mal quye estube haciendo pruebas y quedo asi, pero lo tengo con digitalRead y no me va tampoco.
Si el sensor espara colocar en una parte fija y el iman en una rueda.
El imán lo tengo cerca que por ahora estoy haciendo pruebas a pasar el imán cerca del sensor con la mano, pero me marca mas de un impulso, no se que puedo hacer
-Supongo que es un hall effect sensor.
En todo caso me parece que parte del fallo esta aquí:
int lectura=LOW;
int lectura1= analogRead(sonda); // Lectura1 guarda la lectura de la sonda
if (lectura != lectura1){ // Si lectura1 y Lectura son distintas
posible solución:
byte lectura, ultimaLectura;
lectura = digitalRead(sonda); // digitalRead() para mirar si es LOW o HIGH
if(lectura != ultimaLectura){
contador++;
ultimaLectura = lectura;
//delay(5);
[OPERACIONES]
}
Primero declaro las variables sin asignarles valores, estas tienen que ser globales al menos ultimaLectura para que permanezca el ultimo valor.
Enseguida de leer el valor del sensor se comprueba si es diferente al ultimo, si y solo si lo es pasa el punto de control y hace las operaciones necesarias; no necesitas delay(), supongo que lo utilizabas para darle un margen de error.
Si es un sensor de efecto hall, tiene que estar muuuuuy cerca, y no se debe usar un imán, ya que es capaz de detectar metal, siempre y cuando, no sea titanio. Con la mano, puede funcionar mal, por la proximidad "variable". Deberías probarlo en la rueda.
El sensor es un sigma de los que traen los biciclometros y el iman que venia con el.
A ver si lo puedo probar en la rueda y asi funciona bien. Pero mi duda es que si la rueda se para por casualidad, mucha casualidad en la posicion imán y sensor enfrentado tal como esta el programa ahora parece que se volvera loco y contara seguido, pero no probare en la rueda y os digo.
loquino:
El sensor es un sigma de los que traen los biciclometros y el iman que venia con el.
A ver si lo puedo probar en la rueda y asi funciona bien. Pero mi duda es que si la rueda se para por casualidad, mucha casualidad en la posicion imán y sensor enfrentado tal como esta el programa ahora parece que se volvera loco y contara seguido, pero no probare en la rueda y os digo.
Pues si que es mio, tengo un problema con los comentarios, aveces no se que poner, en momentos como este entiendo la importancia de los comentarios.
Ademas creo que tiene inconsistencias porque estaba experimentando.
pero creo que en aquel entonces logre buenos resultados.
No, creo que tiene el mismo problema, pero que tal este mas simple y con comentarios:
lo propongo para dejarlo como referencia si vale!.
espero que valga porque no lo he probado.
/*Lectura de Revoluciones con hall sensor sin interrupciones
evita cuenta repetida, por estancamiento de sensor.
herja 28/01/2015
*/
boolean latch; // ----- variables de control
byte vuelta;
const byte sensor = 4; // ------ pin de sensor
long revoluciones; // ------ cuenta larga de revoluciones
void setup(){
pinMode(sensor, INPUT_PULLUP); // --- configura el pin del sensor como entrada y activa la resistencia pullup
Serial.begin(9600); // Serial 9600
}
void loop(){
if(sensor){ // --- si sensor HIGH:
latch = 1; // --- latch indica el estado actual del sensor.
vuelta++; // --- su valor solo es util cuando es 1, lo cual indica una vuelta.
if (vuelta > 2) vuelta = 2; // --- evita desbordamiento y cuentas falsas cada 255 ciclos.
}
else{ // --- si sensor LOW:
latch = 0; // --- latch indica el estado actual del sensor
vuelta = 0; // --- vuelta se reinicia, para poder contar otra vuelta.
}
if(latch == 1 && vuelta == 1) Serial.println(++revoluciones); // Finalmente, solo si se cumplen las condiciones
// cuenta una vuelta en revoluciones.
// La variable vuelta evita contar + de una vez.
}
Mi problema es que el sensor magnetici en vez de marcarme solo un pulso en el contador acsa vez que pasa el iman cerca de el, me marca varios seguidos cuando pasa despacio o por veces.
A ver si alguien me puede echar una mano a solucionar el problema.
int lectura=LOW; // Lectura guarda la lectura en reposo que es LOW
int lectura1= digitalRead(sonda); // Lectura1 guarda la lectura de la sonda
if (lectura != lectura1){ // Si lectura1 y Lectura son distintas
delay(5); // Se espera 100 milisegundos
contador++; // Sumamos 1 al contador de vueltas de la rueda
kmReales=(contador*diametroCalibracion)/10000;// Calculamos los Km Reales con esa fórmula
kmEntero=abs(kmReales); // Guardamos el número entero de los Km reales
s= kmEntero%10; // Cálculo del número a mostrar en las unidades
S= (kmEntero/10)%10; // Cálculo del número a mostrar en las Decenas
m= (kmEntero/100)%10; // Cálculo del número a mostrar en las Centenas
M= (kmEntero/1000); // Cálculo del número a mostrar en los Millares
}
No te funciona porque estas contando cada 5 milisegundos en el estado alto, si el sistema se mantiene en estado alto te incrementa cada 5 milisegundos el contador. Mas arriba ehrja lo corrigió detectando diferencia de estado de la señal, es decir cuenta tanto el flanco ascendente como descendente , incrementado el contado dos veces por paso del sensor. Simplemente deberías dividir el resultado por dos o contar solo uno de los flancos de la señal.
Saludos
Y una vez mas una respuesta que creí habia salido no lo hizo. Gracias a carmeloco que me recordó que queda en el draft restauro la respuetsa.
En ella hacía un análisis de tiempos. Espero sirva
Esto iba en el post#2 o 3 asi que disculpen que esta fuera de tiempo.
Sin el código completo te diré:
delay(5); // Se espera 100 milisegundos
Eso para mi son 5 milisegundos o ahora me diras que el que usas dice 100.
Resulta que el codigo dice analogRead y respondes que tu código usa digitalRead
El codigo dice 5 mseg y el comentario dice 100mseg
Y para terminar
int lectura=LOW; // Lectura guarda la lectura en reposo que es LOW
int lectura1= digitalRead(sonda); // Lectura1 guarda la lectura de la sonda
if (lectura != lectura1){
Eso da por sentado que vamos de 0 a 1 pero no dice nada salvo por rebotes de 5 mseg que no se pueda dar otro 0 a 1.
Una rueda rodado 28 son 635mm de diametro eso da un perímetro de P = 2PIxR o PixD
Perim = 199.4 cm
A una velocidad de 60km/h = 60 x 1000 mts/ 3600 seg = 16.66 m/seg
Entonces T = D/V = 1.994 mts/16.66 m/seg = 0.119 seg
Quiere decir que a 60km/h una vuelta de la rueda tarda 0.119 seg de modo que un delay de 100 mseg es imposible.
Creo que 50 mseg me darán posible lecturas de V = D/T = 1.994 m/ 0.05seg = 40 m/seg = 144 km/h
Yo haría esa parte del código de otro modo.
//defino
int lectura = LOW;
en setup()
en loop()
int lectura1= digitalRead(sonda); // Lectura1 guarda la lectura de la sonda
if (lectura != lectura1){ // Si lectura1 y Lectura son distintas
if (lectura == LOW && lectura1 == HIGH) { // transición 0 a 1
contador++; // Sumamos 1 al contador de vueltas de la rueda
kmReales=(contador*diametroCalibracion)/10000;// Calculamos los Km Reales con esa fórmula
kmEntero=abs(kmReales); // Guardamos el número entero de los Km reales
s= kmEntero%10; // Cálculo del número a mostrar en las unidades
S= (kmEntero/10)%10; // Cálculo del número a mostrar en las Decenas
m= (kmEntero/100)%10; // Cálculo del número a mostrar en las Centenas
M= (kmEntero/1000); // Cálculo del número a mostrar en los Millares
}
lectura = lectura1; // actualizo estado anterior
}
El codigo ya me funciona tenia razon ehrja en su primera respuesta meti las variables como globales otra vez (que la primera vez no me fuera) y ya me funciono. Despues como decian dividí el resultado entre dos y lo probe en la rueda y parece que va perfecto.
El delay ese no le deais muchas vueltas, lo tenia puesto para ver cuantas veces contaba mientras no me funcionaba de la otra manera.
Tengo que probarlo mas a fondo pero parece que todo ok.