viernes, 11 de julio de 2014

Punteros en programas arduino

Recientemente realicé un proyecto con arduino. Necesitaba que al tener presionado un botón desde el protoboard conectado a un pin de arduino se encendiera un led, pero que únicamente validara el primer pulso sobre el botón.
Un programa en arduino se ejecuta en loop, es decir en un ciclo infinito, para detener un proceso se usan retardos, esto con la función delay(100), el parámetro que recibe son el total de milisengundos que se retardará le programa.
El problema que tuve en primer lugar es cómo validar únicamente el primer pulso, e ignorar los demás pulsos, lo que ocurre es que arduino sensa los pines cada 100 milisegundos, al menos ese es el tiempo que yo le dí, entonces cada 100 ms realizaba la misma acción, algo que no quería.
EL segundo problema fue usar apuntadores.
La solución quedó de la siguiente manera:
Primero vea el circuito y el material que usé para esta parte:

Ahí pueden ver los materiales usados, así como la conexión de cada componente. La idea es que cuando se presione un botón se encienda el led de salida, solo tomando en cueta el primer pulso, es decir, tanto en pantalla como en el resultado solo mostrará un uno sólo una vez.
El código es el siguiente:

const int buttonPinEntrada1 = 2;
const int buttonPinEntrada2 = 3;
const int ledPinSalida1 =  8;
const int ledPinSalida2 =  9;
int buttonState1 = 0;
int buttonState2 = 0;
int bBoton1=0;
int bBoton2=0;
int *band;

void setup(){
  Serial.begin(9600);
  pinMode(ledPinSalida1, OUTPUT);
  pinMode(ledPinSalida2, OUTPUT);
  pinMode(buttonPinEntrada1, INPUT);
  pinMode(buttonPinEntrada2, INPUT);
}

void loop(){
  /*boton 1*/
  buttonState1 = digitalRead(buttonPinEntrada1);
  band=&bBoton1;
  validarUnicoPulsoBoton(ledPinSalida1,band,buttonState1);
  /*boton 2*/
  buttonState2 = digitalRead(buttonPinEntrada2);
  band=&bBoton2;
  validarUnicoPulsoBoton(ledPinSalida2,band,buttonState2);
  delay(100);
}

/*procedimiento que se usa para validar una sola pulsacion de un boton*/
void validarUnicoPulsoBoton(int ledPinSalida,int *band,int buttonState){
  /*se verifica si el estado del buton es igual a uno, es decir, si esta presionado, de tal forma que si el boton se mantiene presionado
  por mucho tiempo, pasara la siguiente condicion, esto evita que se realize la misma accion muchas veces*/
  if(buttonState == 1){
    /*se veirifica si la bandera de ese boton esta desactivada, lo que significa que no se ha realizado ninguna accion
    tras a ver pulsado dicho boton*/
    if(*band == 0){
      /*se realiza la accion, en este caso se enciende un led*/
      digitalWrite(ledPinSalida, HIGH);
      /*se actualiza la bandera para indicar que la accion ya se ha realizado al menos una vez*/
      *band=1;
      /*se imprime en pantalla el valor de la bandera, solo para asegurar en que estado se encuentra (opcional)*/
      Serial.println(*band);
    }
  }
  /*se verifica si el estado del boton es igual a cero, esto indicara que el boton ha cambiado de valor, presionado a no presionado*/
  if(buttonState == 0){
    /*se valida que la bandera sea igual a 1, indica que la accion que se realiza cuando es presionado el boton se ha realizado al menos
    una vez*/
    if(*band == 1){
      /*sin la bandera esta activada, en este caso se encendio el led, entonces es necesario apagarlo*/
      digitalWrite(ledPinSalida, LOW);
      /*se actuliza el valor de la bandera, para indicar que el  estado del boton ha sido actualizado*/
      *band=0;
      /*opcional se imprime el nuevo valor de la bandera*/
      Serial.println(*band);
    }
  }
}

Y eso es todo, buena suerte.

2 comentarios:

  1. hola me sirvió mucho tu programa, y lo modifique para que se mantuvieran encendidos los leds al oprimir una vez cada boton, y apagar cada led cuando se volviera a oprimir el boton correspondiente:

    int buttonPinEntrada1 = 2;
    int buttonPinEntrada2 = 3;
    int ledPinSalida1 = 8;
    int ledPinSalida2 = 9;
    int buttonState1 = 0;
    int buttonState2 = 0;
    int bBoton1=0;
    int bBoton2=0;
    int bencender1=0;
    int bencender2=0;
    int *band,*encender;

    void setup(){
    //Serial.begin(9600);
    pinMode(ledPinSalida1, OUTPUT);
    pinMode(ledPinSalida2, OUTPUT);
    pinMode(buttonPinEntrada1, INPUT);
    pinMode(buttonPinEntrada2, INPUT);
    }

    void loop(){
    /*boton 1*/
    buttonState1 = digitalRead(buttonPinEntrada1);
    delay(40);
    band=&bBoton1;
    encender=&bencender1;
    validarUnicoPulsoBoton(ledPinSalida1,band,buttonState1,encender);
    /*boton 2*/
    buttonState2 = digitalRead(buttonPinEntrada2);
    delay(40);
    band=&bBoton2;
    encender=&bencender2;
    validarUnicoPulsoBoton(ledPinSalida2,band,buttonState2,encender);
    }


    /*procedimiento que se usa para validar una sola pulsacion de un boton*/
    void validarUnicoPulsoBoton(int ledPinSalida,int *band,int buttonState,int *encender){
    if(buttonState && *band == 0){*encender=1-*encender;}
    *band=buttonState;
    if(*encender == 1){digitalWrite(ledPinSalida,1);} //se enciende el led
    else digitalWrite(ledPinSalida,0);
    }

    ResponderEliminar
    Respuestas
    1. Gracias por la aportación @mauricio ... lo probaré en cuando llegué mi nueva arduino... se me quemó la que tenía...

      Eliminar