// Constants for light sensor const int LIGHT_SENSOR_PIN = 5; const uint32_t DARK_DISCHARGE_THRESHOLD = 300; // Constants for buzzer const int BUZZER_PIN = 1; const int OPEN_WARNING_TONE = 500; const int OPEN_WARNING_DURATION_MS = 1000; const int TEMP_WARNING_TONE = 800; const int TEMP_WARNING_DURATION_MS = 500; const int TEMP_WARNING_REPEAT = 3; // Constants for warning thresholds and repeat intervals const uint32_t OPEN_WARNING_TIME_SEC = 60; const uint32_t OPEN_WARNING_INTERVAL_SEC = 15; // Global variables for time tracking uint32_t nLoopStart = 0; uint32_t nApproxRunTime = 0; // Global variables for warning tracking boolean bLightOn = false; uint32_t nLightOnStart = 0; uint32_t nLastLightOnWarning = 0; void setup() { // Initialize Serial comms Serial.begin(); // Init Bean LED to off Bean.setLed(0,0,0); // Set light sensor pin mode pinMode(LIGHT_SENSOR_PIN, INPUT_PULLUP); } void loop() { // For time tracking we need to know when the loop() started nLoopStart = millis(); // Check the light condition, if LIGHT ... if (lightCheck() == "LIGHT") { // ... if it was not light last time through loop ... if (!bLightOn) { // ... set light on flag and reset light on duration. bLightOn = true; nLightOnStart = approxRunTime(); } else { // If it was light before and the light has been on longer than our warning threshold ... if ( (approxRunTime() - nLightOnStart) >= (OPEN_WARNING_TIME_SEC * 1000) ) { // ... and if our last light on warning was longer ago than our interval ... if ( (approxRunTime() - nLastLightOnWarning) >= (OPEN_WARNING_INTERVAL_SEC * 1000) ) { // ... then reset our last warning time ... nLastLightOnWarning = approxRunTime(); // ... and play warning tone. warningTone( OPEN_WARNING_TONE, OPEN_WARNING_DURATION_MS, 1 ); } } } } else { // If not LIGHT, ensure light on flag is false. bLightOn = false; } // Determine our loop sleep time based on conditions uint32_t nSleepTime = 15000; // 15 seconds standard sleep time if (bLightOn) { nSleepTime = min(nSleepTime,(OPEN_WARNING_INTERVAL_SEC * 1000)); } // Before sleep, update approximate run time updateApproxRunTimeForSleep( nSleepTime ); // Sleep Bean.sleep(nSleepTime); } uint32_t approxRunTime() { return (nApproxRunTime + (millis() - nLoopStart)); } void updateApproxRunTimeForSleep( uint32_t nSleepTime ) { nApproxRunTime += (millis() - nLoopStart) + nSleepTime; nLoopStart = millis(); // Reset loop start since we have added loop time to total } void warningTone( uint16_t nFreq, uint16_t nDuration, uint8_t nCount) { // Setup a loop counter int n = 0; // While the loop counter is less than the specified count ... while (n++ < nCount) { // ... play the specified tone. playTone(BUZZER_PIN, nFreq, nDuration); // if we will repeat, pause briefly so the tones don't run together. if (n < nCount) { delay(250); } } } void playTone(uint8_t nPin, uint16_t nFreq, uint16_t nDuration) { // If frequency or duration is zero, stop any tones if ( (nFreq == 0) || (nDuration == 0) ) { noTone(nPin); } else { // Output the specified tone for the specified duration tone(nPin, nFreq, nDuration); // Since we need the tone to occur synchronously we wait for it to finish delay(nDuration); } } String lightCheck() { String strOut = "LIGHT"; if ( qtTime( LIGHT_SENSOR_PIN, DARK_DISCHARGE_THRESHOLD) >= DARK_DISCHARGE_THRESHOLD ) { strOut = "DARK"; } // Return LIGHT or DARK return strOut; } uint32_t qtTime(int nQTPin, uint32_t nMaxWait) { // Charge the capacitor digitalWrite(nQTPin, HIGH); delay(5); // Stop charging digitalWrite(nQTPin, LOW); // Start discharge cycle uint32_t nStart = millis(); uint32_t nDuration = 0; // As capacitor discharges through phototransistor sensor // pin will transition from HIGH to LOW while(digitalRead(nQTPin) == HIGH) { // Wait for discharge // In case millis() has rolled over if ( millis() < nStart ) { nStart = millis(); } // Has duration exceeded the DARK threshold time? nDuration = millis() - nStart; if ( nDuration > nMaxWait ) { break; } } // For determining threshold or degugging, output duration // String strDuration = ""; // strDuration += String(nDuration); // strDuration += " ms"; // Serial.println( strDuration ); // Above section can be removed or commented once lightCheck() // is working as desired. return nDuration; }