Astronomical-clock SunMoon.h with LCD

Hi,

I am working on LDR based sun tracking project and I want to add Astronomical-clock with RTC DS3231.
I get the idea of Astronomical-clock from link below

every think is working fine I need help regarding SunMoon.h library to display the sunrise and sunset time on LCD.

#include <Time.h>
#include <TimeLib.h>
#include <DS3232RTC.h>
#include <sunMoon.h>

#define OUR_latitude    55.751244               // Moscow cordinates
#define OUR_longtitude  37.618423
#define OUR_timezone    180                     // localtime with UTC difference in minutes

sunMoon  sm;

void printDate(time_t date) {
  char buff[20];
  sprintf(buff, "%2d-%02d-%4d %02d:%02d:%02d",
  day(date), month(date), year(date), hour(date), minute(date), second(date));
  Serial.print(buff);
}

void setup() {
  tmElements_t  tm;                             // specific time

  tm.Second = 0;
  tm.Minute = 12;
  tm.Hour   = 12;
  tm.Day    = 3;
  tm.Month  = 8;
  tm.Year   = 2016 - 1970;
  time_t s_date = makeTime(tm);
  
 
  Serial.begin(9600);
  setSyncProvider(RTC.get);                     // the function to get the time from the RTC
  if (timeStatus() != timeSet) 
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");
  sm.init(OUR_timezone, OUR_latitude, OUR_longtitude);

  Serial.print("Today is ");
  printDate(RTC.get()); Serial.println("");
  
  uint32_t jDay = sm.julianDay();               // Optional call
  byte mDay = sm.moonDay();
  time_t sRise = sm.sunRise();
  time_t sSet  = sm.sunSet();
  Serial.print("Today is "); Serial.print(jDay); Serial.println(" Julian day");
  Serial.print("Moon age is "); Serial.print(mDay); Serial.println("day(s)");
  Serial.print("Today sunrise and sunset: ");
  printDate(sRise); Serial.print("; ");
  printDate(sSet);  Serial.println("");


  Serial.print("Specific date was ");
  printDate(s_date); Serial.println("");
  jDay = sm.julianDay(s_date);
  mDay = sm.moonDay(s_date);
  sRise = sm.sunRise(s_date);
  sSet  = sm.sunSet(s_date);
  Serial.print("Specific date sunrise and sunset was: ");
  Serial.print("Julian day of specific date was "); Serial.println(jDay);
  Serial.print("Moon age was "); Serial.print(mDay); Serial.println("day(s)");
  printDate(sRise); Serial.print("; ");
  printDate(sSet);  Serial.println("");

}

void loop() {
  // put your main code here, to run repeatedly:

}

Thanks

What LCD?

If you are happy with a 2 line character display, these are one of the easiest to use and well supported with libraries :

lcd 1602 with I2C backpack

Check the voltage matches your Arduino model.

i2c 20*4

When I used "sRise" and "sSet" it display only numbers without ":". So I believe I make mistake to understand the library.

Regarding connections and setting its fine my concern is only with correct Syntax. Like I write

lcd.setCursor(0, 0);
lcd.print(sRise);

// Out put of this in 22032018 like this

I need help in this area

printDate(sRise); Serial.print("; "); printDate(sSet); Serial.println(""); // on serial print it is working fine

Create a copy of printDate() called say printLcdDate() and modify it to write to the the LCD.

Then call printLcdDate(sRise); etc to print the date to the lcd screen. That way you get the same formatting as printing to the serial console.

6v6gt: Create a copy of printDate() called say printLcdDate() and modify it to write to the the LCD.

Then call printLcdDate(sRise); etc to print the date to the lcd screen. That way you get the same formatting as printing to the serial console.

Thanks for your time. I will try this and mean time have a look of this link https://github.com/sfrwmaker/sunMoon/issues/3#issuecomment-349429147

6v6gt: Create a copy of printDate() called say printLcdDate() and modify it to write to the the LCD.

Then call printLcdDate(sRise); etc to print the date to the lcd screen. That way you get the same formatting as printing to the serial console.

Compiling error 'printlcdDate' was not declared in this scope

Here is the comment of library owner if any one can write it

"First, you should initialize the class instane by bool init(int Timezone, float Latitude, float Longitude);

then you can use

time_t sunRise(time_t date = 0); and time_t sunSet(time_t date = 0); to get the UNIX format sunrise and sunset time. If you call these functions without argument, they return the times for the current day. Make sure that now() returns the correct data. OR you can use your own UNIX time argument to get sunrise and sunset times for that date.

Please, check the source code: time_t sunMoon::sunTime(bool sunRise, time_t date) { if (date == 0) date = now();"

Please post your latest code including the attempt to use printLcdDate(). Did the Serial.print() statements did put the data out in the required format (but of course to the serial console) ?

In my first post code is attached and link of the sunMoon.h library also. My main code is sun tracker which is different from that. Initially I am stuck with this library how to call the sunset and sunrise function in loop which is UNIX format and I cannot understand.

The output on serial is like this

"Today sunrise and sunset: 22-03-2018 05:42:43; 22-03-2018 17:53:55"

I need only sunrise and sunset time.

MorganS: What LCD?

// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // Set the LCD I2C address

Try this:

//additional function
void printLcdDate(time_t date) {
  char buff[20];
  sprintf(buff, "%2d-%02d-%4d %02d:%02d:%02d",
  day(date), month(date), year(date), hour(date), minute(date), second(date));
  lcd.print(buff);
}



// code near the end of setup()
lcd.setCursor(0, 0);
printLcdDate(sRise);
lcd.setCursor(0, 1);
printLcdDate(sSet);

6v6gt:
Try this:

//additional function

void printLcdDate(time_t date) {
 char buff[20];
 sprintf(buff, “%2d-%02d-%4d %02d:%02d:%02d”,
 day(date), month(date), year(date), hour(date), minute(date), second(date));
 lcd.print(buff);
}

// code near the end of setup()
lcd.setCursor(0, 0);
printLcdDate(sRise);
lcd.setCursor(0, 1);
printLcdDate(sSet);

Great now working fine.

// code near the end of setup() here it was getting Specific date was so I put it in front of “sRise” and “sSet” now okay

also edit in this section for display the date only

 char buff[20];
  sprintf(buff, "%02d:%02d:%02d",
  hour(date), minute(date), second(date));
  lcd.print(buff);

Inside the loop still big issue to call function specially date and time seperately.

After some changing. Now it is working in loop also with if else statement. I believe the way of handling the functions can be improve because all data is available there.

#include <Time.h>
#include <TimeLib.h>
#include <DS3232RTC.h>
#include <sunMoon.h>
#include <LiquidCrystal_I2C.h>

//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address

#define OUR_latitude    27.0133              // Moscow cordinates
#define OUR_longtitude  49.6641
#define OUR_timezone    180                     // localtime with UTC difference in minutes

sunMoon  sm;

void printDate(time_t date) {
  char buff[20];
  sprintf(buff, "%2d-%02d-%4d %02d:%02d:%02d",
          day(date), month(date), year(date), hour(date), minute(date), second(date));
  Serial.print(buff);
}

void Time(time_t date) {
  char buff[20];
  sprintf(buff, "%02d:%02d:%02d",
          hour(date), minute(date), second(date));
  Serial.print(buff);
  (buff);
}

//additional function
void printLcdDate(time_t date) {
  char buff[20];
  sprintf(buff, "%02d:%02d:%02d",
          hour(date), minute(date), second(date));
  lcd.print(buff);
}
//additional function
void printLcdDate1(time_t date) {
  char buff[20];
  sprintf(buff, "%2d-%02d-%4d",
          day(date), month(date), year(date));
  lcd.print(buff);
}

void setup() {
  lcd.begin(20, 4);
  tmElements_t  tm;                             // specific time

  tm.Second = 0;
  tm.Minute = 12;
  tm.Hour   = 12;
  tm.Day    = 3;
  tm.Month  = 8;
  tm.Year   = 2016 - 1970;
  time_t s_date = makeTime(tm);

  Serial.begin(9600);
  setSyncProvider(RTC.get);                     // the function to get the time from the RTC
  if (timeStatus() != timeSet)
  Serial.println("Unable to sync with the RTC");
  else
  Serial.println("RTC has set the system time");
  sm.init(OUR_timezone, OUR_latitude, OUR_longtitude);
  Serial.print("Today is ");
  printDate(RTC.get()); Serial.println("");
  uint32_t jDay = sm.julianDay();               // Optional call
  byte mDay = sm.moonDay();
  time_t sRise = sm.sunRise();
  time_t sSet  = sm.sunSet();
  Serial.print("Today is "); Serial.print(jDay); Serial.println(" Julian day");
  Serial.print("Moon age is "); Serial.print(mDay); Serial.println("day(s)");
  Serial.print("Today sunrise and sunset: ");
  printDate(sRise); Serial.print("; ");
  printDate(sSet);  Serial.println("\t");

  Time(sRise); Serial.print("; ");
  Time(sSet);  Serial.println("");

  lcd.setCursor(0, 0);
  printLcdDate1(RTC.get());
  lcd.setCursor(12, 0);
  printLcdDate(RTC.get());
  lcd.setCursor(2, 3);
  printLcdDate(sRise);
  lcd.setCursor(12, 3);
  printLcdDate(sSet);


  Serial.print("Specific date was ");
  printDate(s_date); Serial.println("");
  jDay = sm.julianDay(s_date);
  mDay = sm.moonDay(s_date);
  sRise = sm.sunRise(s_date);
  sSet  = sm.sunSet(s_date);
  Serial.print("Specific date sunrise and sunset was: ");
  Serial.print("Julian day of specific date was "); Serial.println(jDay);
  Serial.print("Moon age was "); Serial.print(mDay); Serial.println("day(s)");
  printDate(sRise); Serial.print("; ");
  printDate(sSet);  Serial.println("");

}

void loop() {

  time_t sRise = sm.sunRise();
  time_t sSet  = sm.sunSet();
  time_t sunRise(time_t date = 0);
  time_t sunSet(time_t date = 0);
  
  printDate(RTC.get()); Serial.print("\t");
  Time(sRise); Serial.print("\t ");
  Time(sSet);  Serial.println("");


   if (RTC.get() >=sRise && RTC.get() <=sSet )
  {
    Serial.println("Day");
    lcd.setCursor(10, 1);
    lcd.print("Day");  
  }
  else if (RTC.get()>=sSet && RTC.get() <=sRise )
  {
    Serial.print("Night ");
    lcd.setCursor(10, 1);
    lcd.print("Night");
  }
  else
  {
  }                                   
    lcd.setCursor(0, 0);
    printLcdDate1(RTC.get());
    lcd.setCursor(12, 0);
    printLcdDate(RTC.get());
    lcd.setCursor(2, 3);
    printLcdDate(sRise);
    lcd.setCursor(12, 3);
    printLcdDate(sSet);
                                     
    delay(1000);
}

If someone can help display / extract date and time separately from this function instead of additional function as I did or comment if it is the right way.

void printDate(time_t date) {
  char buff[20];
  sprintf(buff, "%2d-%02d-%4d %02d:%02d:%02d",
  day(date), month(date), year(date), hour(date), minute(date), second(date));
  Serial.print(buff);
}
  lcd.setCursor(0, 0);
  printLcdDate1(RTC.get());
  lcd.setCursor(12, 0);
  printLcdDate(RTC.get());
  lcd.setCursor(2, 3);
  printLcdDate(sRise);
  lcd.setCursor(12, 3);
  printLcdDate(sSet);

Does this print as you would like to the LCD screen ? I don't understand why you have two copies of the essentially the same function: printLcdDate() and printLcdDate1(). Can you not simply use printLcdDate() where you have used printLcdDate1() ? It appears that you are you printing RTC.get() twice on the same line. ?

because I want to display current time, sunrise and sunset only and location of these time is different on lcd.

If I will use same format as you send before its printing the current time with both of sunrise and sunset time like

Current time 23-03-2018 16:56:43

Sunrise 23-03-2018 05:41:36

Sunset 23-03-2018 17:54:25

I want to display like

23-03-2018 16:56:43

05:41:36 17:54:25

If you will see the function definition I delete Date and give the different name.

Ok. I see. You might be able to combine the two LCD date functions into one like this (untested) :

. . . 

void printLcdDatePart(char format, time_t date) {
  // format: 't' is time , 'd' is date
  char buff[20];
  if ( format == 't' ) {
     sprintf(buff, "%02d:%02d:%02d",
          hour(date), minute(date), second(date));
  }
  else {
      sprintf(buff, "%2d-%02d-%4d",
          day(date), month(date), year(date));
  }
  lcd.print(buff);
}

. . .

  lcd.setCursor(0, 0);
  printLcdDatePart('d' ,RTC.get());
  lcd.setCursor(12, 0);
  printLcdDatePart('t', RTC.get());
  lcd.setCursor(2, 3);
  printLcdDatePart('d', sRise);
  lcd.setCursor(12, 3);
  printLcdDatePart('d', sSet);

Exactly the same result :slight_smile: only change in last 02 lines “t” instead of “d”

inside the loop I am getting the results as suspected from below code can we modify the night definition
because after 24:00 hr it will be false.

Thanks again

   if (RTC.get() > sRise && RTC.get() < sSet )
  {
    Serial.print("Day");
    lcd.setCursor(10, 1);
    lcd.print("Day");  
  }
  else if (RTC.get() > sSet )
  {
    Serial.print("Night ");
    lcd.setCursor(10, 1);
    lcd.print("Night");
  }
  else
  {
  }