Help with RTCLib please

Hi folks, I cannot remember the name of this sort of code, it's kind of like a table in assembly but not called so...

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

So I just want to know what the second bracket containing 12 does?

Only I have tried similar with months but it is giving me day of the week instead lol

...
char mOnth[12][13] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
...

Thanks.

It is a 2 dimensional array with 7 rows of 12 values

Each row is a day of the week from 0 to 6 and each column is a letter in the string of the day name

What exactly gives you the day of the week instead of the month ?

Please post your sketch

1 Like

That 12 represents the maximum allowed length of each character string, including one character for the null terminator. See here for more info on character strings: https://www.tutorialspoint.com/cprogramming/c_strings.htm
I don't know why it is a 12, though. You should be able to change that 12 to a 10, and it should still work, because no day of the week has more than 9 letters.

It is impossible to figure out what is going wrong without seeing the rest of your code. Please post your code.

1 Like

Thanks folks, Array, that's the one! ok the 12 makes sense now lol, I could not see any other reason than some sort of wraparound or similar which is why I put 13 for my mOnth code.

Now I have changed the second number to 9 to represent September..

Getting a new error "initializer-string for array of chars is too long [-fpermissive]"

I best read up on arrays I guess lol...

Now here is the code with the change I made...

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][9] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

char mOnth[12][9] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

void setup () {
  Serial.begin(57600);

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2021, 12, 27, 12, 25, 00));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(mOnth[now.month()]);
    Serial.print(" ");
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.dayOfTheWeek(), DEC);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");

    // calculate a date which is 7 days, 12 hours, 30 minutes, 6 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 12h + 30m + 6s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.print("Temperature: ");
    Serial.print(rtc.getTemperature());
    Serial.println(" C");

    Serial.println();
    delay(3000);
}

How many letters are there in the word September ?
You have forgotten to allow for the terminating '\0' character that turns the array of chars into C-string

1 Like

So would that be 11 or 13? :-/

ok error sorted, but still getting a day of the week instead of mOnth!? I just cannot see why...?

It would be at least 1 more than the number of visible characters in the longest string

Note that the possibility of getting the second dimension wrong can be eliminated by using an array of pointers instead and you don't even need to tell the compiler how many entries there are in the array because it will work it out for you

const char * daysOfTheWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup()
{
  Serial.begin(115200);
  for (int day = 0; day < 7; day++)
  {
    Serial.println(daysOfTheWeek[day]);
  }
}

void loop()
{
}
1 Like

Good to know, thank you. Just need to work out what is happening with month and all will be good. I suppose you could add to same array and add + 7 to the answer to get past weekdays?

Yes, if you were determined to confuse yourself and everybody else and what would be the advantage ?

Have you posted the sketch that gives you problems with months ?

1 Like

Yeah just above mate. Fair enough regards confusing lol...

I have removed the later part of the code so for clarity I will post here with the print screen I am getting...

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

char mOnth[12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

void setup () {
  Serial.begin(57600);

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2021, 12, 27, 12, 25, 00));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(mOnth[now.month()]);
    Serial.print(" ");
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.dayOfTheWeek(), DEC);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    delay(3000);
}

"2021/12/Sunday 27 (Monday) 1) 21:52:59"

Sunday in Bold should be December

  Serial.print(mOnth[now.month()]);

My guess would be that now.month() returns a number between 1 and 12 but the array index is a number between 0 and 11, so when you get a 12 for December you are not reading from the month array at all but beyond it in memory

Try printing now.month(). What do you see ?

1 Like

Thanks that appears to be the case. What confuses me is that it works for days of week.

Anyway I have added a spurious character and increased the number to 13 for now, Is there a better way to deal with this issue, and why do I not see this for day of week, which apparently behaves the same (i.e. 1 to 7 out, 7 declared characters!).

Confused!

The 12 is a carry-over from the demo code of one of the RTC libraries, that gets blindly copied into sketches without anyone noticing that it is the wrong size. Why it is wrong in the demo code is anyone's guess.

1 Like

You can just subtract 1 from now.month()

  Serial.print(mOnth[now.month() - 1]);

Day of the week does not have the problem because the library function dayOfTheWeek returns a number from 0 through 6, not 1 through 7.

1 Like

Ah thank you for that David. I am struggling with C a bit. unlike assembly, things are easily confusing me, although I can see why people use C lol...

I will persist and get there in the end!

BTW can anyone please recommend a good 3231 library compatible with esp32?

thanks

The 3231 uses I2C to communicate with the MPU so any library will work

Take a look at RTClib - Arduino Reference

The ESP32 has an internal RTC, but it is not as accurate as the DS3231, and lacks a backup battery.

I like the DS3232RTC and Time libraries by Paul Stoffregen, because the TIme library has the ability to sync an internal software RTC with the hardware RTC, greatly decreasing the amount of data needing to be sent over the I2C bus. Never tried those with the ESP32, so I'm not sure if there are any conflicts with the internal RTC.

Oh I didn't think about that! Yes I guess the DS3223 is perfect for accuracy and backup, ESP32 for everyday timestamps, timekeeping etc... :slight_smile: