// First pin connected to LED strips of the stair
const byte outputsOffset = 4;
// Number of LED strips on the stair
const byte numSteps = 16;
// Define the pin used by the "LOW" PIR sensor - for going upstairs
const byte lowSensorPin = 2;
// Define the pin used by the "HIGH" PIR sensor - for going upstairs
const byte highSensorPin = 3;
// Define delay between concurrent stairs turning on
const int stepOnDelay = 400;
// Define delay between concurrent stairs turning off
const int stepOffDelay = 100;
// Define cooldown time before the next trigger is allowed
const int cooldownTime = 3000;
// Define turn off delay if someone is sitting at the top/bottom of the stair
const int presenceTime = 5000;
// Define time all stairs will be illuminated after the on animation
const int lightTime = 6800;
// Define var for double timed step - eg. direction change
const int specialStep = 6;
// Define the pin used by de mode switch button
const int buttonPin = 22;
// Define var for keeping track of the current time in milliseconds
unsigned long timeNow = 0;
// Define var for keeping track of number of loop() runs
unsigned int numLoops = 0;
// Number of intermitents
const int numIntermit = 5;
// Define var foor keeping track of active mode
// 0 - normal motion detection
// 1 - service mode
unsigned int activeMode = 0;
// Define var for keeping track of mode switch button state
unsigned int buttonState = 1;
void setup() {
Serial.begin(115200);
Serial.println(F("--------------------------------------------------------"));
Serial.println(F(" Arduino Staircase led lights"));
Serial.println(F("--------------------------------------------------------"));
Serial.println(F("Inicializando:"));
Serial.print(F("\t[] Número de escalones: "));
Serial.println(numSteps);
Serial.print(F("\t[] Delay de prender escalon: "));
Serial.print(stepOnDelay);
Serial.println("ms");
Serial.print(F("\t[] Delay de apagar escalon: "));
Serial.print(stepOffDelay);
Serial.println("ms");
Serial.print(F("\t[] Tiempo de reutilizacion: "));
Serial.print(cooldownTime);
Serial.println("ms");
Serial.print(F("\t[] Tiempo de Luz: "));
Serial.print(lightTime);
Serial.println("ms");
Serial.print(F("\t[] Tiempo de Presencia: "));
Serial.print(presenceTime);
Serial.println("ms");
// Setup sensor pins
Serial.print(F("\t[] Seteo PIR pins: "));
Serial.print(lowSensorPin);
Serial.print(F(" para subir escaleras, "));
Serial.print(highSensorPin);
Serial.println(F(" para bajar escaleras"));
pinMode(lowSensorPin, INPUT_PULLUP);
pinMode(highSensorPin, INPUT_PULLUP);
Serial.print(F("\t[] Seteo interruptor modo mantenimiento pin: "));
Serial.println(buttonPin);
pinMode(buttonPin, INPUT_PULLUP);
// Setup stair light pins
Serial.print(F("\t[] Seteo LED pins: "));
for (int i = outputsOffset; i<(numSteps + outputsOffset); i++){
pinMode(i, OUTPUT);
digitalWrite(i, HIGH);
Serial.print(i);
Serial.print(" ");
}
Serial.println("");
buttonState = digitalRead(buttonPin);
if (buttonState == LOW){
activeMode = 1; //service mode
}
//Flash stair 4 + activeMode times - test LEDs
flashStair(numIntermit + activeMode);
Serial.println(F("--------------------------------------------------------"));
Serial.print(F(" TIEMPO de DEMORA del SISTEMA: (ready) "));
Serial.print(millis());
Serial.println("ms");
Serial.println(F("--------------------------------------------------------"));
}
void loop() {
changeMode();
if (activeMode == 0){
pirMode(); //PIR mode
} else if (activeMode == 1){
serviceMode();
}
numLoops++;
if (numLoops > 499){
numLoops = 0;
Serial.print(F("\t[] Heartbeat - "));
if (activeMode == 0){
Serial.println("Sleep");
} else {
Serial.println("ServiceMode");
}
}
smartPause(10);
}
void changeMode(){
buttonState = digitalRead(buttonPin);
if (buttonState == LOW && activeMode != 1){
activeMode = 1;
flashStair(numIntermit + activeMode);
} else if (buttonState == HIGH && activeMode != 0){
activeMode = 0;
//Stop flashStair with -2 times
flashStair(numIntermit - 2);
}
}
void serviceMode() {
for (int i = outputsOffset; i<(numSteps+outputsOffset); i++){
digitalWrite(i, LOW);
}
}
void pirMode() {
// Set default value for animation direction
String direction = "NONE";
// Read PIR sensors states
int highSensor = digitalRead(highSensorPin);
int lowSensor = digitalRead(lowSensorPin);
if (highSensor == HIGH){ // If the "HIGH" sensor is triggered
direction = "DOWN";
} else if (lowSensor == HIGH) { // If the "LOW" sensor is triggered
direction = "UP";
}
if (direction != "NONE"){ // Animation ON and OFF
lightsOn(direction);
Serial.print(F("\t[] Leds encendidos "));
Serial.print(lightTime);
Serial.println("ms - con temporizador");
smartPause(lightTime); // All lights on, wait before turning off
// Refresh sensor states
highSensor = digitalRead(highSensorPin);
lowSensor = digitalRead(lowSensorPin);
// Don't run the off animation right away if someone is sitting at the top/bottom of the stairs.
while (lowSensor == HIGH || highSensor == HIGH){
Serial.print(F("\t[] Pausa por "));
Serial.print(presenceTime);
Serial.println("ms - delay de presencia");
smartPause(presenceTime);
highSensor = digitalRead(highSensorPin);
lowSensor = digitalRead(lowSensorPin);
}
lightsOff(direction);
Serial.print(F("\t[] Pausa "));
Serial.print(cooldownTime);
Serial.println("ms - Tiempo de reutilizacion leds");
smartPause(cooldownTime);
}
}
void smartPause(int pauseTimeInMillis){
timeNow = millis();
while((unsigned long)(millis() - timeNow) < pauseTimeInMillis){
/* CHILL */
}
}
void flashStair(int flashCount){
Serial.print(F("\t[] Mantenimiento / Escalera Intermitencia "));
Serial.print(flashCount);
Serial.println(F(" veces"));
// Turn off all lights and pause for 0.5s
for (int i = outputsOffset; i<(numSteps + outputsOffset); i++){
digitalWrite(i, HIGH);
}
smartPause(500);
// Flash lights on and off a number of times
for (int i = 0; i<flashCount; i++){
// Turn lights on
for (int j = outputsOffset; j<(numSteps + outputsOffset); j++){
digitalWrite(j, LOW);
}
smartPause(150); // Pause for 0.15s with lights on
// Turn lights off
for (int j = outputsOffset; j<(numSteps + outputsOffset); j++){
digitalWrite(j, HIGH);
}
smartPause(150); // Pause for 0.15s with lights off
}
smartPause(150); // Pause for 0.15s after flashing complete
}
void lightsOn(String direction){
Serial.print(F("\t[] Leds ON en dirección: "));
Serial.println(direction);
if (direction == "UP"){
// Upwards on animation
// Turn on each light from bottom to top with delay
for (int i = outputsOffset; i<(numSteps+outputsOffset); i++){
digitalWrite(i, LOW);
// Double next step timer
if (i == (outputsOffset + specialStep - 1)) {
Serial.print(F("\t[] Pausa adicion en step: "));
Serial.println(specialStep);
smartPause(stepOnDelay);
}
smartPause(stepOnDelay);
}
} else if (direction == "DOWN"){
// Downwards on animation
// Turn on each light from top to bottom with delay
for (int i = (numSteps + outputsOffset - 1); i>=outputsOffset; i--){
digitalWrite(i, LOW);
// Double next step timer
if (i == (outputsOffset + specialStep - 1)) {
Serial.print(F("\t[] Pausa adicion en step: "));
Serial.println(specialStep);
smartPause(stepOnDelay);
}
smartPause(stepOnDelay);
}
}
Serial.println(F("\t[] Saliendo de función lightsOn() "));
}
void lightsOff(String direction){
Serial.print(F("\t[] Leds OFF en dirección: "));
Serial.println(direction);
if (direction == "DOWN"){
// Upwards on animation
// Turn off each light from top to bottom with delay
for (int i = (numSteps + outputsOffset - 1); i>=outputsOffset; i--){
// Double off timer
if (i == (outputsOffset + specialStep - 1)) {
Serial.print(F("\t[] Pausa adicion en step: "));
Serial.println(specialStep);
smartPause(stepOffDelay);
}
digitalWrite(i, HIGH);
smartPause(stepOffDelay);
}
} else if (direction == "UP"){
// Downwards on animation
// Turn off each light from bottom to top with delay
for (int i = (numSteps + outputsOffset - 1); i>=outputsOffset; i--){
// Double off timer
if (i == (outputsOffset + specialStep - 1)) {
Serial.print(F("\t[] Pausa adicion en step: "));
Serial.println(specialStep);
smartPause(stepOffDelay);
}
digitalWrite(i, HIGH);
smartPause(stepOffDelay);
}
}
Serial.println(F("\t[] Saliendo de función lightsOff() "));
}Downstair Sensor
Upstair Sensor
Maintenance
Switch