/*
8/5/25 - garden light controller
R. Parnell
Inputs:
*duress alarm (from siren or alarm strobe?)
*light beam sensor
*mains detector (from existing mains light circuit)
*GPS clock?
*Test button (set DARK or DAY)
Outputs:
*Light string A - driveway
*Light string B - front and side garden
*Letterbox lights
*Mains light relay controller
*Night or day LED indicator
*heartbeat - indicator
*/
int duress=A0; // pin A0
int beam=A1; // A1
int mains=A2; // A2 mains voltage detection
int ambient=A3; // ambient light detection
int test=A4;
bool dark = false; // day/night flag
int relayON = LOW; // swap high/low to suit relay modules
int relayOFF = HIGH;// swap high/low to suit relay modules
int stringA=5; // pin D2
int stringB=6; // pin D3
int stringC=7; // pin D4
int houselights=5; // pin D5. (turn house lights ON from this module)
int HB=8; // pin D6 heartbeat indicator
unsigned long HBstartMillis; // for heartbeat timer
unsigned long HBcurrentMillis; // what will be the current value to compare countdown to
unsigned long HBtimer = 500; // heartbeat timer
boolean HBtoggle = false; // HB LED toggle
/* Conditions:
1. Light beam triggered - pulse
2. Light beam triggered - continuously (car parked across it)
3. House lights ON
4. Duress alarm triggered
5. sunrise and sunset times for each month
When it is dark:
1. For light beam pulse - turn garden lights and house lights ON for set duration
If lights are already on when another pulse is detected, restart time ON period.
2. If beam is triggered continuously (still on beyond ON time, then consider it blocked and turn all lights OFF. Ignore the beam until the state changes)
3. House lights ON detected - if the house lights are turned ON, turn on the garden lights, irrespective of beam trigger.
If house light switch is turned OFF, turn off all lights.
If the beam is triggered when the house lights are already on, leave the garden lights ONLY on, until the time period runs out.
4. Duress alarm triggered
At all times of the day, flash garden lights on/off alternatively during the active duress. Flash letterbox number at a different rate.
If house lights are ON with duress active, flash one set of garden lights and house number - leave driveway garden lights on steady.
*/
#include <TM1637Display.h>
// Define the connections pins
#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO); // Create an instance of the TM1637Display
//uint8_t dots = 1;
// ############# initialisation complete ##############
void setup() {
display.setBrightness(5); // Set the display brightness (0-7)
pinMode(stringA, OUTPUT);
pinMode(stringB, OUTPUT);
pinMode(stringC, OUTPUT);
pinMode(houselights, OUTPUT);
pinMode(HB, OUTPUT);
pinMode(duress, INPUT);
pinMode(mains, INPUT);
pinMode(beam, INPUT);
//pinMode(ambient, INPUT);
digitalWrite(stringA,relayON);
digitalWrite(stringB,relayON);
digitalWrite(stringC,relayON);
digitalWrite(houselights,relayON);
delay (8000);
digitalWrite(houselights,relayOFF);
delay (2000);
digitalWrite(stringC,relayOFF);
delay (2000);
digitalWrite(stringB,relayOFF);
delay (2000);
digitalWrite(stringA,relayOFF);
HBstartMillis = millis(); //start timing code for heartbeat
} // end of setup() #########################
void loop() {
HBcurrentMillis = millis();
if (HBcurrentMillis - HBstartMillis >= HBtimer){
HBtoggle = !HBtoggle; // invert the status from true/false to false/true
digitalWrite(HB,HBtoggle); // turn HB on/off
HBstartMillis = HBcurrentMillis;
} // end of heartbeat indicator
display.clear(); // Clear the display
uint8_t test[] = {
SEG_G | SEG_B | SEG_C, // T
SEG_A | SEG_F | SEG_G | SEG_E | SEG_D, // E
SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, // S
SEG_G | SEG_B | SEG_C // T
};
uint8_t day[] = {
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d
SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G, // A
SEG_B | SEG_C | SEG_D | SEG_F | SEG_G, // y
SEG_G // -
};
uint8_t nigh[] = {
SEG_E | SEG_C | SEG_G, // n
SEG_B | SEG_C, // i
SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G, // g
SEG_C | SEG_E | SEG_F | SEG_G // H
};
uint8_t RP74[] = {
SEG_E | SEG_G, // r
SEG_A | SEG_B | SEG_E | SEG_F | SEG_G, // P
//SEG_DP, // :
SEG_A | SEG_B | SEG_C, // 7
SEG_B | SEG_C | SEG_F | SEG_G // 4
};
display.setSegments(RP74); // Display the data
delay(1500);
display.showNumberDecEx(1234, 0b01000000, false, 4, 0); // Example with the number 1234 and the colon on
delay(1500);
////// Display Number
display.clear(); // Clear the display
long randNumber = random(0, 9999); // Generate a random number between 0 and 9999
display.showNumberDecEx(randNumber, 0b01000000, false); // Display decimal number with DP
//showNumberDecEx shows number with colon
delay(1500);
display.showNumberDecEx(randNumber, false); // Display decimal number without DP
//showNumberDecEx shows number with colon
delay(1500);
} // end of loop() ##############
void override(){
// turn garden lights on steady if either house switch is on
}// end of override() ##################
void duressactive() {
// flash garden lights and also letterbox number
} // end of duressactive()############
void beamactive(){
// turn all garden lights & external house lights on sequentially if beam tripped and it's dark
}// end of beamactive()##################
void readinputs(){
} // end of readinputs()#################
void nightday(){
// use the GPS clock to work out if it is day or night time, based upon sunrise and sunset times
//display UTC on 7 segment display
// bool dark = false; // day/night flag
} // end of nightday determination