
¡Hola de nuevo! Comparto aquí un codekata para construir una luz automática con Arduino. La idea es que se encienda con un sensor, y se mantenga encendida durante 30 segundos. Si mientras está encendida, se producen nuevos movimientos, entonces resetea la cuenta atrás a 30 segundos de nuevo para que se mantenga la luz encendida. A los 30 segundos de no haber movimiento se apagará.
Como único input tiene un sensor PIR, el clásico sensor de movimiento basado en infrarojos. Como output usa 3 pines, dos son simplemente leds para ver que está activo o no, y un tercer output que es un relay para encender y apagar luces usando voltajes y amperajes más altos como lámparas a 220v, por ejemplo.
Al grano, el código fuente
unsigned long stopMs = 0; // Timestamp to stop..
int secsWait = 30;
bool debug = false;
// Inputs..
int pirSensor = 9;
// Outputs..
int internalLed = 13;
int externalLed = 5;
int relay = 7;
void setup() {
pinMode(internalLed, OUTPUT);
pinMode(externalLed, OUTPUT);
pinMode(relay, OUTPUT);
pinMode(pirSensor, INPUT);
Serial.begin(9600);
}
void loop() {
int currentStatus = digitalRead(pirSensor);
if(debug) {
String sms = (String) millis() + "=>" + (String) stopMs + " Sensor: " + (String) currentStatus;
Serial.println(sms);
}
if(stopMs > millis()) {
if (currentStatus == HIGH) {
stopMs = millis() + secsWait * 1000;
}
} else {
// Switch on/off lights if counter is zero..
if (currentStatus == HIGH) {
stopMs = millis() + secsWait * 1000;
digitalWrite(internalLed, HIGH);
digitalWrite(externalLed, HIGH);
digitalWrite(relay, HIGH);
} else {
digitalWrite(internalLed, LOW);
digitalWrite(externalLed, LOW);
digitalWrite(relay, LOW);
}
}
// Reset..
if(stopMs > millis() && stopMs - millis() > 2 * (secsWait * 1000)) {
stopMs = 0;
}
}
La parte final del reset es para tener en cuenta la vuelta a cero de millis(). No sea que se quede encendida si se activó justo antes de la puesta a cero de millis():
if(stopMs > millis() && stopMs - millis() > 2 * (secsWait * 1000)) {
stopMs = 0;
}
Muy buen proyecto
Muchas gracias Marcos