Como os dije en la entrada anterior, aquí voy a poneros el código para hacer exactamente lo mismo pero por interrupciones en vez de leyendo el estado del pin 3 cada vuelta del loop.
Mismo dibujo a medio terminar del circuito:
Y el código:
int boton = 3;
int redPin = 9;
int greenPin = 10;
int bluePin = 11;
long tiempo_anterior;
long diferencia;
bool flagLuces = false;
void setup() {
Serial.begin(9600);
pinMode(boton, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(boton), botonLuces, FALLING);
}
void loop() {
if(flagLuces){
flagLuces = false;
cambiaEstadoLED();
}
}
void botonLuces(){
diferencia = millis() - tiempo_anterior;
tiempo_anterior = millis();
if(diferencia > 500){
flagLuces = true;
}
}
void cambiaEstadoLED(){
if(digitalRead(greenPin) == false){
encender();
Serial.println("encendido");
}
else{
apagar();</span
Serial.println("apagado");
}
}
void encender(){
for (int brillo = 0; brillo <= 122; brillo++) {
setColor(0, brillo, brillo);
delay(30);
}
for(int brillo = 123; brillo <= 255; brillo++) {
setColor(0, brillo, brillo);
delay(5);
}
}
void apagar(){
for (int brillo = 255; brillo >= 0; brillo--) {
setColor(0, brillo, brillo);
delay(10);
}
}
void setColor(int red, int green,int blue){
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
Sobre el código:
Es bastante autoexplicativo. Como ahora la pulsación genera una interrupción, ya no hay que comprobar el estado del pin 3 a cada vuelta del loop.
El problema principal que me he encontrado es que el encendido de luces lleva delay
, y esa instrucción no se debe meter dentro del código que se ejecuta en una interrupción, porque hace que millis
se pare y trastoca la ejecución.
O sea que dentro del código de la interrupción pongo un flag a true
, y el código en sí sigue en el loop y solo se ejecuta si el flag está a true
.
Usar interrupciones supone una cierta mejora, porque con el código anterior si pulsabas el botón cuando el bucle de encendido/apagado se estaba ejecutando no te reconocía la pulsación; pero con interrupciones, aunque el código se esté ejecutando, una pulsación nueva pone a true
el flag – por eso lo ponemos a false
lo primero según entra en el código, y no al final – y se ejecutará en la siguiente vuelta del loop.
En botonLuces
el trozo de código que calcula el tiempo entre interrupciones es solo para evitar que interprete ruido en la pulsación del botón como “otra pulsación”.
Leí por algún lado que también podía añadir al circuito un condensador conectado a tierra, pero como soy programadora y no ingeniera electrónica no sé qué narices hace el condensador, pero sí sé qué hace ese trocito de código, así que me quedo con lo que entiendo.
Sentíos libres de quitar el código y poner un condensador, si a diferencia de mí sí sabéis de electrónica.
Sigo manteniendo los Serial.println
porque aunque no servirán de nada en el montaje final, para ir afinando con los tiempos de encendido y apagado viene muy bien.
************************************************************
Espero que esta entrada pueda ser de utilidad, y si no, como siempre, aquí tenéis un gato para compensar.