Lectura Erronea sensor magnético

Hola, llevo un par de dias estancado.

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.

Hola, gracias por responder.

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

Hi

No me dices que tipo de sensor es el que tienes?

-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.

Muchas gracias por la respuesta

Si es un hall effect sensor

Acabo de probar lo que me comentaste pero nada, me sige igual que antes :frowning:

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.

Gracias

pusiste las variables como globales?

static byte lectura, ultimaLectura; // también pueden ir así dentro del loop!

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.

Gracias

Entonces, no es un sensor de efecto hall

Un reed swith!!

Yo uso este http://www.banggood.com/Hall-Effect-Magnetic-Sensor-Module-DC-5V-For-Arduino-p-76469.html y funciona perfecto ,pero si quieres asegurarte la recepcion de los pulsos deberias usar una interrupcion y en las conexiones las correspondientes resistencias pullup o pulldown en la entrada de la señal del sensor,segun el tipo de disparador que uses en la interrupcion. http://arduino.cc/en/Reference/AttachInterrupt

Oh es cierto lo de la resistencia, se me había olvidado. :astonished:
También pensaba en ese jose pero el que menciona surbyte es mas simple:

pero me parece raro que no quede, tal vez me olvide de algo, pero te dejo un código que hice ya hace tiempo utilizando un fan de un pc viejo:

unsigned long ms = 500;
unsigned long oms;
int vel;
boolean latch;

void setup(){
 pinMode(4,INPUT_PULLUP);
 Serial.begin(9600);
 Serial.println("Wind Force");
}
void loop(){
 int candado0, candado1;
oms = millis();
while((oms + ms) > millis()){
if(digitalRead(4)){
 //Serial.print("-");
latch =1;
candado1++;
candado0=0;
}
else{
 //Serial.print(".");
latch=0;
candado0++;
candado1=0;
}
delay(1);
if((latch == 1) && (candado1 == 1))Serial.print(".");

}
Serial.println("");
vel=0;
delay(ms);
}

Y la salida:

Wind Force

.














. <-----my finger being cut




























… <----- a hand turn on the desktop

ehrja que código tan poco documentado. Obvio que no es tuyo.
El resto de tu post no se lee nada.

:smiley: Jjejeje...

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. :cry:

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. 

}

loquino:
Hola, llevo un par de dias estancado.

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
  }

Gracias a todos asi da gusto.

Soy novato en el tema de ahi los errores.

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.

Mil gracias de nuevo.

Ahhh las resistencias ya las tenia puestas y todo lo demas, lo unico que me fallaba era eso de las variables globales.

Tendre que probarlo a una velocidad mayor a ver si funciona igual de bien.

o simplemente usar la interrupcion externa y listo

las variables globales deben llevar volatile si son compartidas por la interrupción!!!