/* Number of stairs */
#define numberOfStairs 32
/* Speeds */
int speedUp = 500;
int speedDown = 500;
/* Number of used registers */
int numOfRegisters = numberOfStairs / 8;
/* Variables */
int upflag = 0;
int dwnflag = 0;
int SwithFlag = 0;
int dataPin = 0; /* pin 32 */
int latchPin = 1; /* pin 11 */
int clockPin = 2; /* pin 12 */
int Switch = 4;
/* Motion sensors upstairs and downstairs */
int sensorDownstairs = 5; /* pin 10 */
int sensorUpstairs = 3; /* pin 2 */
/* Lights turn on for some time in milliseconds */
int lightsOnDelay = 100;
byte *registerState;
/* When move is captured then do the action */
bool hasMoved = false;
bool wasDownToUp = false;
bool wasUpToDown = false;
void setup()
{
registerState = new byte[numOfRegisters];
for (size_t i = 0; i < numOfRegisters; i++)
registerState[i] = 0;
pinMode(sensorDownstairs, INPUT);
pinMode(sensorUpstairs, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(Switch, INPUT_PULLUP);
}
void loop()
{
int motionUp = digitalRead(sensorUpstairs);
int motionDown = digitalRead(sensorDownstairs);
if (motionUp || motionDown)
hasMoved = true;
if (hasMoved)
{
if (motionUp && upflag == 0)
{
turnOnFromDownstairs(speedUp);
upflag = 1;
if (dwnflag == 1)
{
wasUpToDown = true;
upflag = 0;
}
}
if (motionDown && dwnflag == 0)
{
turnOnFromUpstairs(speedUp);
dwnflag = 1;
if (upflag == 1)
{
wasDownToUp = true;
dwnflag = 0;
}
}
hasMoved = false;
delay(lightsOnDelay);
}
else
{
if (wasDownToUp && upflag == 1)
{
turnOffFromDownstairs(speedDown);
wasDownToUp = false;
upflag = 0;
}
if (wasUpToDown && dwnflag == 1)
{
turnOffFromUpstairs(speedDown);
wasUpToDown = false;
dwnflag = 0;
}
}
if (digitalRead(Switch) == LOW)
{
turnOnFromDownstairs(speedUp);
SwithFlag = 1;
}
if (digitalRead(Switch) == HIGH && SwithFlag == 1)
{
turnOffFromDownstairs(speedUp);
SwithFlag = 0;
}
}
void turnOffFromUpstairs(int effectSpeed) { changeState(effectSpeed, LOW, false); }
void turnOnFromUpstairs(int effectSpeed) { changeState(effectSpeed, HIGH, false); }
void turnOffFromDownstairs(int effectSpeed) { changeState(effectSpeed, LOW, true); }
void turnOnFromDownstairs(int effectSpeed) { changeState(effectSpeed, HIGH, true); }
void changeState(int effectSpeed, bool state, bool directionUp)
{
if (directionUp)
{
for (int i = 0; i < numberOfStairs; i++)
{
regWrite(i, state);
delay(effectSpeed);
}
}
else
{
for (int i = numberOfStairs - 1; i >= 0; i--)
{
regWrite(i, state);
delay(effectSpeed);
}
}
}
void regWrite(int pin, bool state)
{
int reg = pin / 8;
int actualPin = pin - (8 * reg);
digitalWrite(latchPin, LOW);
for (int i = numOfRegisters - 1; i >= 0; i--)
{
byte *states = ®isterState[i];
if (i == reg)
bitWrite(*states, actualPin, state);
shiftOut(dataPin, clockPin, MSBFIRST, *states);
}
digitalWrite(latchPin, HIGH);
}