need help getting rid of delays

I have a solar lighting project using a photo-resistor to measure the amount of light, and then having the uno trigger a relay.

here is the basic sketch, It works well, but I would like to add more sensors to this project and found that during the delay i cannot pull info from the sensors.

const int relay1= 8;
const int photoSen= 0;
int lightLevel;
int r1P;

void setup() {
  // put your setup code here, to run once:
pinMode(photoSen, INPUT);
pinMode(relay1, OUTPUT);
Serial.begin(9600);
Serial.println("solar_led_control_v1");
}

void loop() {
  // put your main code here, to run repeatedly:
    lightLevel = analogRead(photoSen);
  r1P = digitalRead(relay1);
  Serial.print("light level:");
  Serial.print(lightLevel);
  Serial.print("  relay position:");
  Serial.println(r1P);
 delay(1000);
 
  if (lightLevel >= 50) {
    digitalWrite(relay1, LOW);
  }
  if (lightLevel <= 49) {
    digitalWrite(relay1, HIGH);
    delay(30000);
    digitalWrite(relay1, LOW);
    delay(10000);
  }
}

this is what i have so far. Cannot figure out how to get rid of the last delay.

//relay1 setup
const int relay1= 8;  //relay1 pin
int relayState1= LOW;   //relaystate1 used to set the relay
unsigned long prevMillisrly1 = 0;    //will store last time relay was updated
const long OnTime1 = 20000;   //20sec on-time
const long OffTime1 = 10000;   //10sec off-time

//sensor setup
const int photoSen= 0;    //photoresistor pin
const int sunny= 70;    //light val from photoresistor, can be adjusted
                        //for when light turns on
const int tempSen= 1;   //temp sensor pin
const long senInterval = 10000;
unsigned long prevMillissen1 = 0;

//int
int lightLevel; //light level
int r1P; //relay1

void setup() {
  // put your setup code here, to run once:
pinMode(photoSen, INPUT);
pinMode(tempSen, INPUT);
pinMode(relay1, OUTPUT);
Serial.begin(9600);
Serial.println("simple_millis_solar_exp3_delay");

}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();
    lightLevel = analogRead(photoSen);
  r1P = digitalRead(relay1);


//relay1 setup
if(lightLevel > sunny){
  digitalWrite(relay1, LOW);
}

if((lightLevel <= sunny) && (relayState1 == LOW)){
relayState1 = HIGH;
prevMillisrly1 = currentMillis;
digitalWrite(relay1, relayState1);
}
else if ((lightLevel <= sunny) && (relayState1 == HIGH) && (currentMillis - prevMillisrly1 >= OnTime1)){
relayState1 = LOW;
prevMillisrly1 = currentMillis;
digitalWrite(relay1, relayState1);
delay(OffTime1);
}

//serial print set up
if (currentMillis - prevMillissen1 >= senInterval){
  prevMillissen1 = currentMillis;
  Serial.print("light level:");
  Serial.print(lightLevel);
  Serial.print("  relay position:");
  Serial.println(r1P);
}
  
}

I tired this at the end and all it did is blink the led at the 20sec mark.

if ((relayState1 = LOW) && (currentMillis - prevMillisrly1 >= OffTime1)){
  relayState1 = LOW;
  prevMillisrly1 = currentMillis;
  digitalWrite(relay1, relayState1);
}

I have tried to understand the multitasking arduino walk through. Tried to apply what I learned, and so far i am at a road block. :oops:

I do want to turn this into a weather station, to use this as a plant watering device eventually.

I would change the code where you test lightlevel <= sunny to this and try it:

  if((lightLevel <= sunny) {
    if (relayState1 == LOW) && (currentMillis - prevMillisrly1 >= OffTime1)){
      relayState1 = HIGH;
      prevMillisrly1 = currentMillis;
      digitalWrite(relay1, relayState1);
      }
    if ((relayState1 == HIGH) && (currentMillis - prevMillisrly1 >= OnTime1)){
      relayState1 = LOW;
      prevMillisrly1 = currentMillis;
      digitalWrite(relay1, relayState1);
      }
    }

wow…will give it a try. I did not know that you can do if statements inside of other if statements.

DanV:
I would change the code where you test lightlevel <= sunny to this and try it:

  if((lightLevel <= sunny) {
if (relayState1 == LOW) && (currentMillis - prevMillisrly1 >= OffTime1)){
  relayState1 = HIGH;
  prevMillisrly1 = currentMillis;
  digitalWrite(relay1, relayState1);
  }
if ((relayState1 == HIGH) && (currentMillis - prevMillisrly1 >= OnTime1)){
  relayState1 = LOW;
  prevMillisrly1 = currentMillis;
  digitalWrite(relay1, relayState1);
  }
}

I did this, it sorta worked. Realistically when used, OffTime will be 10 hours, on time will be 3 hours. I want the led to turn on once lightLevel <= sunny. I did more work on the code to try to correct it, and realized something with my set up. First the code: (StTime is one second, this will stay one second)

if(lightLevel > sunny){
  digitalWrite(relay1, LOW);
}

if(lightLevel <= sunny) {
    if ((relayState1 == LOW) && (currentMillis - prevMillisrly1 >= StTime1)){
      relayState1 = HIGH;
      prevMillisrly1 = currentMillis;
      digitalWrite(relay1, relayState1);
    }
        if ((relayState1 == HIGH) && (currentMillis - prevMillisrly1 >= OnTime1)){
              relayState1 = LOW;
              prevMillisrly1 = currentMillis;
          digitalWrite(relay1, relayState1);
        if ((relayState1 == LOW) && (currentMillis - prevMillisrly1 >= OffTime1)){
              relayState1 = HIGH;
              prevMillisrly1 = currentMillis;
              digitalWrite(relay1, relayState1);
    }}
}

The problem i see from this set up is there is 2 if(relayState == LOW) statements. So after the OnTime1 timer runs out, it skips the second if(relayState1 == LOW) and goes to the first. Is there anyway to get it to see the second if(relayState1 == LOW)?

You can test :

if relayState1 == LOW

as many times as you want.

Not sure why you nested a test for relayState1 == LOW under the test for relayState1 == HIGH …

If you wanted an initial delay of 1 second and then ignore it forever you would need to set a Boolean flag to indicate that it had been serviced:

  if ((relayState1 == LOW) && (currentMillis - prevMillisrly1 >= StTime1) && (b_ONCE == FALSE)){
    b_ONCE = TRUE;
    relayState1 = HIGH;
    prevMillisrly1 = currentMillis;
    digitalWrite(relay1, relayState1);
    }

Then you want to simply toggle the LED on and off? The whole thing would look like this:

if(lightLevel <= sunny) {
  if ((relayState1 == LOW) && (currentMillis - prevMillisrly1 >= StTime1) && (!b_ONCE)){
    b_ONCE = TRUE;
    relayState1 = HIGH;
    prevMillisrly1 = currentMillis;
    digitalWrite(relay1, relayState1);
    }
  if ((relayState1 == HIGH) && (currentMillis - prevMillisrly1 >= OnTime1)){
    relayState1 = LOW;
    prevMillisrly1 = currentMillis;
    digitalWrite(relay1, relayState1);
    }
  if ((relayState1 == LOW) && (currentMillis - prevMillisrly1 >= OffTime1)){
    relayState1 = HIGH;
    prevMillisrly1 = currentMillis;
    digitalWrite(relay1, relayState1);
    }
  }

But I’m not really sure since you introduced the new delay StTime1 …

when i add the code in and hit compile it says "b_ONCE has not been declared " what do i declare it as

Declare it as a bool

bool b_ONCE;

thanks man…ill give it a try

It works the way in want it now! Thank you very much DanV!

Yes, you’re welcome. Glad it’s working for you.