Como tener un conteo de pulsos confiables?

Saludos.

Esta es mi primera experiencia con arduino o con un PIC.

Solo estoy probando en Proteus 8

Proyecto: sensar velocidad y temperatura de (cojinetes y alineación) para una transportadora, para detenerla si sale de rango.

Uso: un arduino mega 2560, conectado una pantalla LCD16x4, con cuatro pulsadores para parametrizar y leds para indicar si alguno entro en falla, una señal de pulso (simula sensor inductivo que lee velocidad) y 6 medidores de temperatura NTC.

He podido elaborar un programa que me permite mostrar los dados en el lcd poder parametrizar, generar las alarmas, el problema el calcula de la velocidad fluctúa.

muestro la velocidad en lo que llamo mi pantalla principal y me muestra 47 (deberia ser 50 por que muestreo por 2 s una señal de 40ms, todavía no lo paso a rpm, pero esto no importa por que le puedo colocar un factor) el problema es que cuando cambio a lo que llamo pantalla de monitoreo pasa a 13, esta también muestra los datos de temperatura que llevan cálculos logarítmico. pero este calculo siempre lo hago en la raiz del loop() cíclico por que si sale de rango tengo que dar una alarma.

el punto es que se nota que la lectura de pulsos se ve influenciado por lo demás que esta ejecutando, como hago para tener una medida constante, ya que a partir de esta debo de generar una alarma si sale de rango,

la velocidad la mido con esta funcion : donde "in" es la entrada del pin y "ban" una bandera que declare afuera y cuenta cuando reconoce el flanco de bajada.

//      Velocidad por pulsos
void velocidad (bool in) {
 unsigned long currentMillis = millis();
 if ( in == true) {
   ban = true;
 }
 if ( ban == true && in == false) {
   suma = suma + 1;
   ban = false;

 }
 if (currentMillis - previousMillis >= 2000) {
   previousMillis = currentMillis;
   velocida =  suma;
   suma = 0;
 }
}

Atento a su ayuda
gracias

David Ramos

me piden poner el programa pero me dice que excedo de 9000 caracteres y solo estaba colocando declaraciones setup() loop()

creo a ver que las interrupciones es la opcion. ahora a aprender como se hacen

Hola.
Por favor; edita tu post y pon el código entre etiquetas code. Sólo debes seleccionar el texto y pinchar en el icono </>. De paso, pon el código completo, porque así es muy difícil ayudarte.
Como respuesta rápida, te puedo decir que la solución a tu problema esté muy probablemente en utilizar una interrupción.

hola ya he podido solucionar con interrupcion.

no les puedo colocar todo el codigo, pero les explico

coloco la siguiente instrucion en setup()

attachInterrupt( 2,velocidad, FALLING);

donde 2 es el pin 21 int0 donde coloco la señal de pulso, velocidad es la funcion que llama la interrupcion, y falling es que quiero cuando vea flanco de high a low.

la funcion velocidad me quedo de este modo (recordando que no lo he pasado a rpm)

//      Velocidad por pulsos
void velocidad () {
  unsigned long currentMillis = millis();
      suma = suma + 1;
    if (currentMillis - previousMillis >= 2000) {
    previousMillis = currentMillis;
    velocida =  suma;
    suma = 0;
  }
}

y me da perfecto me cuenta los 50 ciclos que debe de contar a 40ms en 2000 s de ventana de muestreo

saludos.

¡Perfecto!
Gracias por molestarte en poner tus post con buena presencia y enhorabuena por tu iniciativa en aprovechar las "pistas". Sólo la palabra interrupción ha bastado para que salgas tú sólo del atolladero.
Por completar un poco más de información, comentarte que hasta cierto nivel de frecuencia es más exacto e instantáneo calcularla midiendo el periodo entre dos flancos que contando los flancos en un determinado tiempo.
Por ejemplo, si tu cinta baja drásticamente la velocidad, tardarás dos segundos con tu código actual en detectar esa circunstancia.
Sin embargo, si mides el periodo entre flanco y flanco en cada entrada en la interrupción tendrás un cálculo de la frecuencia, con lo que la detección de una salida de los límites sería más inmediata. Probablemente recurriría, eso sí, a medir la diferencia entre los dos flancos en micros, en lugar de en millis.
Queda un pequeño fleco que habría que mirar en todo caso, pues no sé si existe la posibilidad de una parada brusca y total; pero si la posibilidad existe y no instauramos un mecanismo (timeout) para detectarlo, como las mediciones se realizan al entrar en la interrupción y como dejarían de producirse interrupciones, nos estaríamos quedando con la última lectura tomada.

Tienes una simulación y funciona con millis() pero no con interrupciones.
Porque no adjuntas tu simulación y pones el código que no funciona?
Usa etiquetas por favor.