Lectura pin digital defectuosa

Buenas tardes,

Estoy intentando hacer un simple codigo para incrementar un contador cada vez que se pulsa un pulsador. Para ver la cuenta estoy utilizando el monitor serial.

El problema es que cuando el pulsador no esta pulsado la cuenta se incrementa sola. Por ello deduzco que arduino esta leyendo HIGH en el pin de entrada cuando no deberia.

He escrito diferentes codigos para intentar solucionarlo y no lo consigo, ni utilizando solamente digitalRead, ni detectando los cambios de estado. Cuando utilizo delays la cosa parece mejorar pero sigue atascandose en HIGH algunas veces cuando en realidad es low.

Adjunto el codigo aunque es algo muy basico:

const int buttonPin = 2; // the pin that the pushbutton is attached to const int ledPin = 13; // the pin that the LED is attached to

// Variables will change: int buttonPushCounter = 0; // counter for the number of button presses int buttonState = 0; // current state of the button int lastButtonState = 0; // previous state of the button

void setup() { // initialize the button pin as a input: pinMode(buttonPin, INPUT); // initialize the LED as an output: pinMode(ledPin, OUTPUT); // initialize serial communication: Serial.begin(9600); }

void loop() { // read the pushbutton input pin: buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state if (buttonState != lastButtonState) { // if the state has changed, increment the counter if (buttonState == HIGH) { // if the current state is HIGH then the button // wend from off to on: buttonPushCounter++; Serial.println("on"); Serial.print("number of button pushes: "); Serial.println(buttonPushCounter); } else { // if the current state is LOW then the button // wend from on to off: Serial.println("off"); } } // save the current state as the last state, //for next time through the loop lastButtonState = buttonState; }

1-Pull up resistor ~ 1KOhm to 5V, switch to ground. 2-Rebote de los contactos (Bouncing). Puedes tartar de eliminarlo con: -delay() -Utilizando banderas como aqui: http://forum.arduino.cc/index.php?topic=222479.0 Quizas eso te ayude Suerte.

Saludos. Por que no usar una interrupción ya que usas el pin2 como entrada?

Seguramente es un problema de ruido (un azote en Arduino). Al ser una señal transitoria tienes dos caminos para solucionarlo : - Filtrado electrónico -Filtrado por programa

En el filtrado electrónico se debería usar un filtro pasa bajo . El mas sencillo es el RC Acá hay una pagina para calcular los valores de la resistencia y condensador. http://gzaloprgm.com.ar/filtrorc/ El valor de frecuencia de corte se calcula con el ancho de pulso de la señal a medir. Por ejemplo si un humano tiene presionado al menos 0,1 S un pulsador como mínimo, daría 10 Hz .

En el filtrado por programa es algo similar . Con el delay estas disminuyendo el tiempo de muestreo. Si se trata de ruido de transitorios (señales únicas de corta duración) seria suficiente. La probabilidad de muestrear en el mismo momento que se sucede el transitorio es baja (si el transitorio tiene un ancho de pulso pequeño y es de baja ocurrencia). Si se tiene una orgía de transitorios o una señal recurrente, como por ejemplo ruido de linea eléctrica de 60 Hz, el delay no funcionara. En ese caso se puede tratar de validar la señal. En el código que pusiste se genera un evento (activación del pulsador) cuando la señal pasa de negativo a positivo, comúnmente llamada flanco ascendente. Se podría validar la señal midiendo el ancho de pulso de esta. Al ocurrir un flanco ascendente se dispara un temporizador que se desactiva cuando ocurre el flanco descendente . Si ese tiempo es corto , por ejemplo menor a 0,1 seg, se descarta. En el caso extremo se podría obligar a tener presionado el pulsador por 2 seg para obtener un evento. Esto ultimo es común en la industria, para arrancar una maquina potencialmente peligrosa, se obliga a tener presionado el pulsador unos segundos y al mismo tiempo se genera una señal auditiva.