En esta nueva entrada del curso de programación con Protocoder vamos a partir de la entrada anterior y crearemos un nuevo botón que permitirá apagar o encender un relé y además, configuraremos un temporizador para el apagado automático de éste.
Circuito eléctrico
En esta entrada vamos a utilizar un modulo de relés conectado al pin número 2 de la placa ZUM. Para conectar el aparato externo, utilizaremos una fuente de conexión de 12 V, ya que en este caso se utilizará una tira de LED que funciona a 12 voltios.
Las conexiones eléctricas que vamos a realizar son las siguientes:
El relé que hemos utilizado soporta 10 A a diferentes voltajes. Es necesario que el relé que se use soporte más corriente de la que se suministra al sistema para evitar que se estropee el relé.
Código Arduino
En el código Arduino, con respecto al código de la entrada anterior, se incluyen variables para controlar el relé, la función checkAuto y dos nuevos casos en el switch que se encuentra dentro de la función checkIncomming.
Las nuevas variables que se han incluido son relay1Pin y nextTime. Su declaración es:
1 2 3 |
//Relay Variables int relay1Pin = 2; unsigned long nextTime; |
Se utilizará el pin número 2 de la placa ZUM para activar o desactivar el relé (utilizaremos un módulo de relé que incorpora lo necesario para la protección de la placa). Para la variable nextTime se ha utilizado el tipo unsigned long para aumentar el rango de la variable y permitir que el dispositivo funcione correctamente durante más tiempo. Si quieres conocer más sobre este tipo de variable, puedes visitar la página de referencia de Arduino.
Dentro de la función setup, hay que declarar mediante la orden pinMode el pin del relé como salida, quedando la función setup:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup() { Serial.begin(19200); pinMode(relay1Pin, OUTPUT); Wire.begin(); hts221.begin(); if (hts221.checkConnection()) { Serial.println("Error checking HTS221 connection"); } else { Serial.println("HTS221 connected"); } } |
Para controlar los nuevos modos de funcionamiento, se crean dos nuevos case dentro del switch de la función checkIncomming. Para el modo manual de control del relé se utiliza el case 2 y para el modo automático, se utiliza el case 3. Programaremos la parte de Protocoder en consonancia para que se envíe el flag correspondiente a cada modo.
Además, creamos la variable isOn, que utilizaremos para saber si se ha utilizado el control manual del relé y en caso de que se haya activado, igualaremos a true esta variable para, en caso de que se haya programado un temporizador, no se desactive el relé una vez que el tiempo de activación sea superado.
Para el control manual del relé utilizaremos el case 2 del switch:
1 2 3 4 5 6 7 8 |
case 2: // 2 for change the state of the relay1 if (data == 0) { isOn = false; digitalWrite(relay1Pin, LOW); } else if (data == 1) { isOn = true; digitalWrite(relay1Pin, HIGH); } |
Desde Protocoder, enviamos un 0 con el estado correspondiente a apagado y un 1 para encendido. Dentro del condicional if comprobamos cual es el dato que se ha enviado, se modifica la variable isOn a false y se pone a LOW el pin del relé si el dato que se ha recibido es 0. Por el contrario, si se ha leído un 1, se modifica la variable isOn a true y se pone a HIGH el pin del relé.
Para el control automático del relé utilizaremos el case 3 del switch:
1 2 3 4 5 |
case 3: nextTime = data * 60000 + millis() ; digitalWrite(relay1Pin, HIGH); break; } |
Desde Protocoder enviamos el tiempo en minutos que el relé tiene que estar activo, por lo que al recibir el dato lo multiplicamos por 60000 para pasar de minutos a milisegundos y sumamos el valor actual de millis (que devuelve el tiempo en milisegundos que ha pasado desde el encendido o reseteo de la placa) y se almacena en la variable nextTime. Además, activamos el pin del relé.
Con la nueva función checkAuto se comprueba si el valor de millis ha superado el valor de la variable nextTime y si la variable isOn es false, es decir, no se ha activado el control manual del relé desde Protocoder.
1 2 3 4 5 |
void checkAuto() { if (millis() > nextTime && !isOn) { digitalWrite(relay1Pin, LOW); } } |
Si ambas condiciones se cumplen se desactiva el pin del relé, apagando el dispositivo conectado a éste.
Código Protocoder
En el código de Protocoder vamos a crear un cuadro de texto y un botón que se encargarán del modo automático de funcionamiento y, un botón con imágenes que activará o desactivará manualmente el pin del relé.
Para crear el nuevo cuadro de texto y el botón que activará el modo automático, se utiliza el código:
1 2 3 4 5 6 7 8 |
var setSleep = ui.addInput("Set Sleep (m)", margin, 7*y, w/2, h).onChange(function(val){ timeToSend = val; // Will change it to miliseconds on Arduino. }); var setSleepBtn = ui.addButton("Set Sleep",margin +w/2,7*y,w/2,h).onClick(function(){ flag = 3; // set flag to 1 to set intervale on Arduino send(flag,timeToSend); }); |
Para almacenar el valor del tiempo, utilizamos la variable timeToSend, que se había creado en la entrada anterior, para almacenar el valor que se ha introducido en el cuadro de texto setSleep. Cuando se pulsa sobre el botón setSleepBtn, asignamos el valor 3 a la variable flag y pasamos a la función send los parámetros flag y timeToSend. En el código Arduino se procesarán estos datos para cambiar el tiempo de minutos a milisegundos.
Para controlar de manera manual el relé, vamos a utilizar un botón con imágenes y controlaremos el estado del botón con una variable. Además, crearemos variables para controlar la altura (hImg) y ancho (wImg) de la imagen.
1 2 3 4 |
var wImg = w/2; var hImg = wImg * 210/500; var R1State = false; var relayStatus; |
Las imágenes que hemos utilizado tienen un ancho de 500 px y un alto de 210, por lo que utilizamos el factor de escala 210/500 para ajustar el alto en función del ancho y conseguir que la proporción de la imagen sea correcta.
El código completo del botón con imágenes es:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var relay1 = ui.addImageButton(margin,8.2*y,wImg,hImg, "off.png").onClick(function(){ R1State = !R1State; // Change value flag=2; ui.jump(relay1); if(R1State){ relay1.setImage("on.png"); relayStatus=1; }else{ relay1.setImage("off.png"); relayStatus=0; } send(flag,relayStatus); }); |
La variable R1State se incia a false, ya que en la programación Arduino hemos hecho que el relé esté apagado al comenzar la ejecución. Cada vez que se pulse sobre el botón se cambiará el R1State de false a true y viceversa. Dentro de la programación del botón comprobamos con condicionales if el valor de la variable R1State, si es true asignaremos un 1 a la variable relayStatus, si es false asignaremos un 0 a la variable relayStatus.
También modificaremos la imagen (on/off) para mostrar la que corresponda al estado de la variable relayStatus. Para cambiar la imagen, utilizamos las ordenes relay1.setImage(“on.png”); y relay1.setImage(“off.png”);.
![]() |
![]() |
Para enviar el estado del botón a la placa ZUM, utilizamos la orden send(flag,relayStatus);.