Using Non blocking delay

I have a small code for controlling a lamp via a relay for illumination of my staircase during the period "Sunset to Sunrise"
Some code for LCD is also included to check the date values and sunrise and sunset times.
the code is

/*
   
   Standard LCD from www.extremeelectronics.co.in is being used.
   Connection between MCU and LCD:
   PORTB0 -> LCD D4
   PORTB1 -> LCD D5
   PORTB2 -> LCD D6
   PORTB3 -> LCD D7
   PORTD4 -> LCD RS
   PORTD6 -> LCD R/W
   PORTD7 -> LCD E

   LCD was added to aid in the debugging of the sketch
   during various changes and to observe the outcome.

*/

#include <avr/io.h>
#include <TimeLord.h>
#include <RTClib.h>
extern "C"  {         // these are c files so wrapped to work in C++ too
#include <config.h>
#include <lcd.h>
#include <myutils.h>
}

RTC_Millis rtc;
TimeLord aqua;
unsigned long period = 10000;
unsigned long time_now = 0;


void setup() {
  rtc.begin(DateTime(2019, 4, 28, 19, 38, 30)); //has to be updated  on every power outage as RTC_Millis is used for timekeeping

  // put your setup code here, to run once:
  //put your locations lat, long for sunrise/sunset timimgs

  aqua.Position(28.60598, 77.33622);
  aqua.TimeZone(5.5 * 60);

  pinMode( 15, OUTPUT);
  pinMode( 16, OUTPUT);

  digitalWrite( 15, 1);   // A relay will be used to drive a LED lamp to illuminate the staircase.
  digitalWrite( 16, 1);   // Indicator Led

  //Initialize the LCD Subsystem
  LCDInit(LS_NONE);
  //Clear the display
  LCDClear();
  LCDWriteStringXY(0, 0, "TimeLordLib Demo"); // this LCD code will be
  //taken out on the culmination of the project
  LCDWriteStringXY(5, 1, "Cheers!");
  delay (10000); // next step is to use non blocing delay
  //An attempt that did not yield the desired result
  //if ((unsigned long)(millis() - time_now) > period ) {
  // time_now = millis();


}




void loop() {
  // put your main code here, to run repeatedLy:
  DateTime now = rtc.now();
  byte sunRise[6] = { 0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)};
  byte sunSet[6] = { 0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)} ;
  byte today[6] = {0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)} ;

  aqua.SunRise(sunRise);
  aqua.SunSet(sunSet);
  /* the following LCDWrites are for checking
     the date setting and the sunrise and sunset tmes
  */
  LCDClear();
  LCDWriteStringXY(0, 0, "SR");
  LCDWriteIntXY(3, 0, sunRise[tl_hour], 2);
  LCDWriteIntXY(5, 0, sunRise[tl_minute], 2);


  {
    LCDWriteStringXY(8, 0, "SS");
    LCDWriteIntXY(11, 0, sunSet[tl_hour], 2);
    LCDWriteIntXY(13, 0, sunSet[tl_minute], 2);
  }

  {
    LCDWriteStringXY(0, 1, "Dt");
    LCDWriteIntXY(3, 1, today[tl_day], 2);
    LCDWriteIntXY(6, 1, today[tl_month], 2);
    LCDWriteIntXY(9, 1, 2000 + today[tl_year], 4);
  }

  if (now.hour() * 60 + now.minute() > sunRise[2] * 60
      + sunRise[1] && now.hour() * 60
      + now.minute() <= sunSet[2] * 60 + sunSet[1])
  {
    digitalWrite( 15, 1);
    digitalWrite( 16, 0);

  }
  else
  {
    digitalWrite( 15, 0);
    digitalWrite( 16, 1);

  }

  delay(9000);  // Also to be replaced with non blocking
  //delay after the attempt above is sucessful.
}

when I try to replace the first delay(1000)
the code compiles but the start up message goes out without a pause cant be seen.
This is what I change.

/*

   Standard LCD from www.extremeelectronics.co.in is being used.
   Connection between MCU and LCD:
   PORTB0 -> LCD D4
   PORTB1 -> LCD D5
   PORTB2 -> LCD D6
   PORTB3 -> LCD D7
   PORTD4 -> LCD RS
   PORTD6 -> LCD R/W
   PORTD7 -> LCD E

   LCD was added to aid in the debugging of the sketch
   during various changes and to observe the outcome.

*/

#include <avr/io.h>
#include <TimeLord.h>
#include <RTClib.h>
extern "C"  {         // these are c files so wrapped to work in C++ too
#include <config.h>
#include <lcd.h>
#include <myutils.h>
}

RTC_Millis rtc;
TimeLord aqua;
unsigned long period = 10000;
unsigned long time_now = 0;


void setup() {
  rtc.begin(DateTime(2019, 4, 28, 19, 38, 30)); //has to be updated  on every power outage as RTC_Millis is used for timekeeping

  // put your setup code here, to run once:
  //put your locations lat, long for sunrise/sunset timimgs

  aqua.Position(28.60598, 77.33622);
  aqua.TimeZone(5.5 * 60);

  pinMode( 15, OUTPUT);
  pinMode( 16, OUTPUT);

  digitalWrite( 15, 1);   // A relay will be used to drive a LED lamp to illuminate the staircase.
  digitalWrite( 16, 1);   // Indicator Led

//Initialize the LCD Subsystem
  LCDInit(LS_NONE);
  //Clear the display
  LCDClear();
  LCDWriteStringXY(0, 0, "TimeLordLib Demo"); // this LCD code will be
  //taken out on the culmination of the project
  LCDWriteStringXY(5, 1, "Cheers!");
  //delay (10000); // next step is to use non blocing delay
  //An attempt that did not yield the desired result
  if ((unsigned long)(millis() - time_now) > period ) {
   time_now = millis();


    }

}


void loop() {
  // put your main code here, to run repeatedLy:
  DateTime now = rtc.now();
  byte sunRise[6] = { 0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)};
  byte sunSet[6] = { 0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)} ;
  byte today[6] = {0, 0, 0, now.day(), now.month(), (byte)(now.year() - 2000)} ;

  aqua.SunRise(sunRise);
  aqua.SunSet(sunSet);
  /* the following LCDWrites are for checking
     the date setting and the sunrise and sunset tmes
  */
  LCDClear();
  LCDWriteStringXY(0, 0, "SR");
  LCDWriteIntXY(3, 0, sunRise[tl_hour], 2);
  LCDWriteIntXY(5, 0, sunRise[tl_minute], 2);


  {
    LCDWriteStringXY(8, 0, "SS");
    LCDWriteIntXY(11, 0, sunSet[tl_hour], 2);
    LCDWriteIntXY(13, 0, sunSet[tl_minute], 2);
  }

  {
    LCDWriteStringXY(0, 1, "Dt");
    LCDWriteIntXY(3, 1, today[tl_day], 2);
    LCDWriteIntXY(6, 1, today[tl_month], 2);
    LCDWriteIntXY(9, 1, 2000 + today[tl_year], 4);
  }

  if (now.hour() * 60 + now.minute() > sunRise[2] * 60
      + sunRise[1] && now.hour() * 60
      + now.minute() <= sunSet[2] * 60 + sunSet[1])
  {
    digitalWrite( 15, 1);
    digitalWrite( 16, 0);

  }
  else
  {
    digitalWrite( 15, 0);
    digitalWrite( 16, 1);

  }

  delay(9000);  // Also to be replaced with non blocking
  //delay after the attempt above is sucessful.
}

I am definitely missing something not able to grasp it.
Looking up to you friends for guidance.
Regards.

The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

Why do you want to use a non blocking delay? As a learning exercise?

The way your code looks so far, there's really no point to making it non blocking. The usual reason to do so is so that the system will react quickly to inputs, but since you don't have any you might just as well use delay.

If you want to do it to get accustomed to using millis, here's how to fix your problem in setup, although bear in mind that it's exactly the same as using delay:

void setup() {
  rtc.begin(DateTime(2019, 4, 28, 19, 38, 30)); //has to be updated  on every power outage as RTC_Millis is used for timekeeping

  // put your setup code here, to run once:
  //put your locations lat, long for sunrise/sunset timimgs

  aqua.Position(28.60598, 77.33622);
  aqua.TimeZone(5.5 * 60);

  pinMode( 15, OUTPUT);
  pinMode( 16, OUTPUT);

  digitalWrite( 15, 1);   // A relay will be used to drive a LED lamp to illuminate the staircase.
  digitalWrite( 16, 1);   // Indicator Led

//Initialize the LCD Subsystem
  LCDInit(LS_NONE);
  //Clear the display
  LCDClear();
  LCDWriteStringXY(0, 0, "TimeLordLib Demo"); // this LCD code will be
  //taken out on the culmination of the project
  LCDWriteStringXY(5, 1, "Cheers!");
  while ((millis() - time_now) < period )
   {
  // do nothing
    }

}

Not tested. Not even compiled.

wildbill:
Why do you want to use a non blocking delay? As a learning exercise?

Not tested. Not even compiled.

Thanks wildbill.
Learning exercise yes,
The code compiled and gives the desired result.

Robin2:
The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

Thanks Robin2. I deliberated on the BWoD example, couldn't get hold of it. Will follow your link too.

There is little point in not using delay() in setup() because you are almost never trying to do more than one thing at a time.

However - in loop and any functions called from it you should avoid using it.

If for example you need to look for a button being pushed while you doing the splash screen then you simply move the code for the splash screen for setup() in to loop() and use mills() as per blink without delay()

So == pseudo warning

setup(){
   show splash 1
   delay (5000);
   show splash 2;
   delay (5000);
};

loop (){

  loop stuff



};

becomes something like

setup(){

};

loop (){

  if ( doing splash){
  case ( splash step){
    0: show splash 1
        splash step = 1
    break;
    1: if 5 second delay is up (using mills)
        splash step = 2
    break;
    2: show splash 2
        splash step = 3
    break;
    3:if 5 second delay is up (using mills)
        doing splash = false
    break;
    } // end of case
  } else {
    if (button to stop splash is pressed)
        doing splash = false;

    loop stuff

  }

};

holmes4:
There is little point in not using delay() in setup() because you are almost never trying to do more than one thing at a time.

However - in loop and any functions called from it you should avoid using it.

Hi Holmes, thanks. I am sorry to respond to your post in time. Different time zones.
I will keep in mind that in setup delay can be used.
I have a 90 sec delay in loop. And I Intend to add another delay of 3 hours after which the state of output will be dependent on output from a set of PIR sensors till sunrise. After sunrise no action till sunset ans so on.
Let me work out as suggested by you.