// https://wokwi.com/projects/361178687373989889
// https://forum.arduino.cc/t/number-of-events-over-an-interval-of-time-question/1110643
const unsigned long ltsMinute = 30000; // milliseconds per "life too short" minute
int LED2 = 6;
int SPEAKER = 7;
int PWMA = 2;
int PWMB = 3;
const int MaxRandomNunber = 120; // minutes
const int MinRandomNumber = 30; // minutes
const unsigned int shortLife = 4000; // milliseconds
const unsigned int longLife = 7000; // milliseconds
const unsigned long intervalPeriod = 10000; // milliseconds (> short and long lifes)
unsigned long LockTimer; // LockTime in Milliseconds
int MinuteTimer; // LockTime in Minutes
bool lockedQ = false; // we locked? or not.
// Relay2 Status Set to OFF
int MinutesRemaining = 0;
void setup() {
Serial.begin(115200); // Enable 21st century serial logging
// MinuteTimer = getRandom(MinRandomNumber, MaxRandomNunber); // Generate Random Number based on MIN/MAX Assigned
MinuteTimer = 8; // just testing ma'am.
LockTimer = MinuteTimer * ltsMinute; // Set the duration from of lock from Minutes to Milliseconds
Serial.print("Timer Amount:");
Serial.println(MinuteTimer);
digitalWrite(LED2, HIGH); // Set Locked LED Signal OFF
lock(); // Ater all settings, Start the Lock process
}
void loop() {
// delay(222); // just for now
MinutesRemaining = ((LockTimer - millis())/ltsMinute+1); // Calculate and store thre Minutes locked remaining
if (lockedQ) {
static int reported;
if (MinutesRemaining != reported) {
reported = MinutesRemaining;
Serial.print("LOCKED, wait ");
Serial.println(MinutesRemaining);
}
}
if (!eventHandler(0)) // servic kick some life into it.
eventHandler(1); //
if ((MinutesRemaining == 1) && lockedQ)
FlashLED(300);
if ((MinutesRemaining <= 5) && (MinutesRemaining > 1) && lockedQ)
FlashLED(1000);
if ((millis() >= LockTimer) && lockedQ) {
unLock();
}
}
void lock() { // FUNCTION to engage the lock(s)
lockedQ = true; // Set Locked Status to TRUE (1)
Serial.println("LOCKED it ");
return;
}
void unLock() { // FUNCTION to unlock the lock(s)
lockedQ = false; // Set Locked Status to FALSE (0)
Serial.println("UNLOCKED it");
return;
}
void FlashLED(int x) {
digitalWrite(LED2, (millis() / x ) % 2);
if (MinutesRemaining <= 1) {
if (((millis() / x ) % 2) == 0) {
tone(SPEAKER, 349);
} else noTone(SPEAKER);
}
// flash reporting
unsigned long now = millis();
static unsigned long lastReport;
if (now - lastReport > 1000) {
lastReport = now;
Serial.print(" yeah, LED is flashing ");
Serial.print(x);
if (MinutesRemaining <= 1)
Serial.print(" and BEEPING");
Serial.println();
}
}
enum {IDLE, StART, ACTIVE, PASSIVE, WAITING,};
// call with true to launch an event.
// call with false to move an event along its timeline
// returns true if the machine is busy with a previously launched event
unsigned char eventHandler(unsigned char command)
{
static unsigned char state;
static unsigned long eventStartTime;
static unsigned int eventLivePeriod;
unsigned long now = millis();
// newly event?
if (command) {
state = StART;
return 1; // we busy
}
switch (state) {
case IDLE :
break;
case StART :
eventStartTime = now;
eventLivePeriod = random(shortLife, longLife);
state = random(1000) > 500 ? ACTIVE : PASSIVE;
Serial.print(millis());
Serial.print(" launching a ");
Serial.print(state == ACTIVE ? "ACTIVE" : "PASSIVE");
Serial.print(" event ");
if (state == ACTIVE) {
Serial.print(eventLivePeriod / 1000);
Serial.print(" seconds ON");
}
Serial.println();
break;
case ACTIVE :
if (now - eventStartTime > eventLivePeriod) {
Serial.print(millis());
Serial.println(" done with active period of the active event.");
state = WAITING;
}
break;
case PASSIVE :
if (now - eventStartTime > intervalPeriod) {
Serial.print(millis());
Serial.println(" done with passive event.");
state = IDLE;
}
break;
case WAITING :
if (now - eventStartTime > intervalPeriod) {
Serial.print(millis());
Serial.println(" all done with active event.");
state = IDLE;
}
break;
}
return state != IDLE; // we busy?
}