Turning Lights on and Off with Photocell after Exposure to Light of 30s

So I have some basic experience with coding and need some help. My project is to turn lights on and off with the light exposure. I have the basic code to drive the lights already done. I am using a arduino uno, a simple photon resistor and an LED. The schematic is shown below as well as the code.
<
const int PHOTON = A3;
const int LED = 5;
const float VCC = 4.98;
const float R_DIV = 4684;
const float DARK_MIN = 8000;

void setup() {

Serial.begin(9600);
pinMode(PHOTON, INPUT);
pinMode(LED, OUTPUT);
}

void loop() {
int lightADC = analogRead(PHOTON);
if (lightADC > 0)
{

float lightV = lightADC * VCC / 1023;
float lightR = R_DIV * (VCC / lightV - 1.0);
Serial.println("Voltage: " + String(lightV) + " V");
Serial.println("Resistance: " + String(lightR) + " ohms");

if (lightR >= DARK_MIN)
digitalWrite(LED, HIGH);
else
digitalWrite(LED, LOW);

}

}

My project board has an LED attached to digital pin 5 already. I don't want the system to turn the lights off though if they are exposed quickly to a flashlight for a few seconds. I know that millis() would be how to use it but dont know how to implement it into my code already. I want the system to wait 30 seconds and if a light is still on the photon sensor, turn the lights off. I appreciate any help.

As is usually the case with me when looking at problems like this, I'd suggest a finite state machine. Here's some "pseudocode" you can have a look at:

void loop() 
{
    static uint32_t
        timeLDR;
    static uint8_t
        stateLDR = ST_IDLE;
    uint32_t timeNow = millis();

    switch( stateLDR )
    {
        case    ST_IDLE:
            //if LDR shows some level of brightness...
            if( LDR reads at or above turn-off threshold )
            {
                //get the time now and move to time the exposure
                timeLDR = timeNow;
                state = ST_TIME_EXPOSURE;                
                
            }//if
        break;

        case    ST_TIME_EXPOSURE:
            //if the LDR shows below the threshold, go back to idle
            if( LDR reads below turn-off threshold )
                stateLDR = ST_IDLE;               
            else if( timeNow - timeLDR >= 30000ul )  //time 30-sec or more?
            {
                //if exposure has been there for 30-sec turn off lights
                turn lights off
                timeLDR = timeNow;
                //wait until it's "dark" again before turning lights on and going back to idle
                stateLDR = ST_WAIT_DARK;              
                
            }//if
        break;

        case    ST_WAIT_DARK:
            //wait for LDR to show "dark" for more than 30-sec
            if( LDR reads at or above dark threshold )  //if LDR shows brightness, reset the timer
                timeLDR = timeNow;
            else
            {
                //still dark; been dark for 30-sec?
                if( timeNow - timeLDR >=30000ul )
                {
                    //yes; turn on lights and return to idle state
                    turn lights on
                    stateLDR = ST_IDLE;
                }//if
            }
        break;
        
    }//switch

}//loop

You won't need everything shown if all that's needed is a timer controlled light but this timer counter state change toggle FSM tutorial illustrates the concepts to control your lights.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.