Library issues: undefined reference to

Hi!
I'm trying to build a world clock (Arduino Word Clock - 3D Printable by DIY_Machines - Thingiverse). I have 3d printed and bought the parts but unfortunately, I get the following error message when I compile the code:

Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

C:\Users\moimo\AppData\Local\Temp\ccPwDp3h.ltrans0.ltrans.o: In function `checkDST':

C:\Users\moimo\Documents\Arduino\libraries\DST_RTC-master/DST_RTC.cpp:36: undefined reference to `rulesDST'

C:\Users\moimo\Documents\Arduino\libraries\DST_RTC-master/DST_RTC.cpp:36: undefined reference to `rulesDST'

C:\Users\moimo\Documents\Arduino\libraries\DST_RTC-master/DST_RTC.cpp:71: undefined reference to `rulesDST'

C:\Users\moimo\Documents\Arduino\libraries\DST_RTC-master/DST_RTC.cpp:71: undefined reference to `rulesDST'

collect2.exe: error: ld returned 1 exit status

exit status 1

Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

The Sketch code is:

// include the library code:
#include <Wire.h>
#include <RTClib.h>
#include <DST_RTC.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

// define pins
#define NEOPIN 6  // connect to DIN on NeoMatrix 8x8 via a resistor
#define RTCGND A2 // use this as  ground 
#define RTCPWR A3 // use this as  power


RTC_DS1307 RTC; // Establish clock object
DST_RTC dst_rtc; // DST object

DateTime theTime; // Holds current clock time



// configure for 8x8 neopixel matrix
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, NEOPIN,
                            NEO_MATRIX_TOP  + NEO_MATRIX_LEFT +
                            NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                            NEO_GRB         + NEO_KHZ800);
                            

//array to store if LEDs are lit or not
int ledMatrix[8][8] = {
  {1, 1, 1, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
  };

int ledCount = 64;  // the 8x8 grid of the Neomatrix

void setup() {
  // put your setup code here, to run once:


//Serial for debugging
  Serial.begin(9600);

  // set pinmodes
  pinMode(NEOPIN, OUTPUT);



  // start clock
  Wire.begin();  // Begin I2C
  RTC.begin();   // begin clock
  RTC.adjust(DateTime(__DATE__, __TIME__));



  matrix.begin();
  matrix.setBrightness(100);
  matrix.fillScreen(0); // Initialize all pixels to 'off'
  matrix.show();

  
}

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

  // get the time
  theTime = dst_rtc.calculateTime(RTC.now()); 
  // add 2.5 minutes to get better estimates
  theTime = theTime.unixtime() + 150;



//write 'it is' everytime:
ledMatrix[0][0] = 1;
ledMatrix[0][1] = 1;
ledMatrix[0][0] = 1;





if ((theTime.minute() > 4) && (theTime.minute() < 10)) {
    ledMatrix[2][0] = 1;
    ledMatrix[2][1] = 1;
    ledMatrix[2][2] = 1;
     Serial.print("mfive ");
  }
  if ((theTime.minute() > 9) && (theTime.minute() < 15)) {
    ledMatrix[0][6] = 1;
    ledMatrix[0][7] = 1;
     Serial.print("mten ");
  }
  if ((theTime.minute() > 14) && (theTime.minute() < 20)) {
    ledMatrix[1][0] = 1;
    ledMatrix[1][1] = 1;
    ledMatrix[1][2] = 1;
    ledMatrix[1][3] = 1;
     Serial.print("mquarter ");
  }
  if ((theTime.minute() > 19) && (theTime.minute() < 25)) {
    ledMatrix[1][4] = 1;
    ledMatrix[1][5] = 1;
    ledMatrix[1][6] = 1;
    ledMatrix[1][7] = 1;
     Serial.print("mtwenty ");
  }
  if ((theTime.minute() > 24) && (theTime.minute() < 30)) {
    ledMatrix[1][4] = 1;
    ledMatrix[1][5] = 1;
    ledMatrix[1][6] = 1;
    ledMatrix[1][7] = 1;
    ledMatrix[2][0] = 1;
    ledMatrix[2][1] = 1;
    ledMatrix[2][1] = 1;
     Serial.print("mtwenty five ");
  }
  if ((theTime.minute() > 29) && (theTime.minute() < 35)) {
    ledMatrix[0][3] = 1;
    ledMatrix[0][4] = 1;
    ledMatrix[0][5] = 1;
     Serial.print("mhalf ");
  }
  if ((theTime.minute() > 34) && (theTime.minute() < 40)) {
    ledMatrix[1][4] = 1;
    ledMatrix[1][5] = 1;
    ledMatrix[1][6] = 1;
    ledMatrix[1][7] = 1;
    ledMatrix[2][0] = 1;
    ledMatrix[2][1] = 1;
    ledMatrix[2][1] = 1;
     Serial.print("mtwenty five ");
  }
  if ((theTime.minute() > 39) && (theTime.minute() < 45)) {
    ledMatrix[1][4] = 1;
    ledMatrix[1][5] = 1;
    ledMatrix[1][6] = 1;
    ledMatrix[1][7] = 1;
     Serial.print("mtwenty ");
  }
  if ((theTime.minute() > 44) && (theTime.minute() < 50)) {
    ledMatrix[1][0] = 1;
    ledMatrix[1][1] = 1;
    ledMatrix[1][2] = 1;
    ledMatrix[1][3] = 1;
     Serial.print("mquarter ");
  }
  if ((theTime.minute() > 49) && (theTime.minute() < 55)) {
    ledMatrix[0][6] = 1;
    ledMatrix[0][7] = 1;
     Serial.print("mten");
  }
  if (theTime.minute() > 54) {
    ledMatrix[2][0] = 1;
    ledMatrix[2][1] = 1;
    ledMatrix[2][2] = 1;
     Serial.print("mfive ");
  }


  if ((theTime.minute() < 5))
  {
    switch (theTime.hour()) {
      case 1:
      case 13:
    ledMatrix[3][3] = 1;
    ledMatrix[3][4] = 1;
     Serial.print("hone ");
        break;
      case 2:
      case 14:
    ledMatrix[4][0] = 1;
    ledMatrix[4][1] = 1;
     Serial.print("htwo ");
        break;
      case 3:
      case 15:
    ledMatrix[3][7] = 1;
    ledMatrix[3][6] = 1;
     Serial.print("hthree ");
        break;
      case 4:
      case 16:
    ledMatrix[4][2] = 1;
    ledMatrix[4][3] = 1;
    ledMatrix[4][4] = 1;
     Serial.print("hfour ");
        break;
      case 5:
      case 17:
    ledMatrix[5][6] = 1;
    ledMatrix[5][7] = 1;
     Serial.print("hfive ");
        break;
      case 6:
      case 18:
    ledMatrix[6][6] = 1;
    ledMatrix[6][7] = 1;
     Serial.print("hsix ");
        break;
      case 7:
      case 19:
    ledMatrix[6][3] = 1;
    ledMatrix[6][4] = 1;
    ledMatrix[6][5] = 1;
     Serial.print("hseven ");
        break;
      case 8:
      case 20:
    ledMatrix[4][5] = 1;
    ledMatrix[4][6] = 1;
    ledMatrix[4][7] = 1;
     Serial.print("height ");
        break;
      case 9:
      case 21:
    ledMatrix[6][0] = 1;
    ledMatrix[6][1] = 1;
    ledMatrix[6][2] = 1;
     Serial.print("hnine ");
        break;
      case 10:
      case 22:
    ledMatrix[5][4] = 1;
    ledMatrix[5][5] = 1;
     Serial.print("hten ");
        break;
      case 11:
      case 23:
    ledMatrix[5][0] = 1;
    ledMatrix[5][1] = 1;
    ledMatrix[5][2] = 1;
    ledMatrix[5][3] = 1;
     Serial.print("heleven ");
        break;
      case 0:
      case 12:
    ledMatrix[7][0] = 1;
    ledMatrix[7][1] = 1;
    ledMatrix[7][2] = 1;
    ledMatrix[7][3] = 1;
     Serial.print("htwelve ");
        break;
    }

  }
  else if ((theTime.minute() < 35) && (theTime.minute() > 4))
  {
    ledMatrix[3][0] = 1;
    ledMatrix[3][1] = 1;
    ledMatrix[3][2] = 1;
     Serial.print("past");
   switch (theTime.hour()) {
      case 1:
      case 13:
    ledMatrix[3][3] = 1;
    ledMatrix[3][4] = 1;
     Serial.print("one ");
        break;
      case 2:
      case 14:
    ledMatrix[4][0] = 1;
    ledMatrix[4][1] = 1;
     Serial.print("two ");
        break;
      case 3:
      case 15:
    ledMatrix[3][7] = 1;
    ledMatrix[3][6] = 1;
     Serial.print("three ");
        break;
      case 4:
      case 16:
    ledMatrix[4][2] = 1;
    ledMatrix[4][3] = 1;
    ledMatrix[4][4] = 1;
     Serial.print("four ");
        break;
      case 5:
      case 17:
    ledMatrix[5][6] = 1;
    ledMatrix[5][7] = 1;
     Serial.print("five ");
        break;
      case 6:
      case 18:
    ledMatrix[6][6] = 1;
    ledMatrix[6][7] = 1;
     Serial.print("six ");
        break;
      case 7:
      case 19:
    ledMatrix[6][3] = 1;
    ledMatrix[6][4] = 1;
    ledMatrix[6][5] = 1;
     Serial.print("seven ");
        break;
      case 8:
      case 20:
    ledMatrix[4][5] = 1;
    ledMatrix[4][6] = 1;
    ledMatrix[4][7] = 1;
     Serial.print("eight ");
        break;
      case 9:
      case 21:
    ledMatrix[6][0] = 1;
    ledMatrix[6][1] = 1;
    ledMatrix[6][2] = 1;
     Serial.print("nine ");
        break;
      case 10:
      case 22:
    ledMatrix[5][4] = 1;
    ledMatrix[5][5] = 1;
     Serial.print("ten ");
        break;
      case 11:
      case 23:
    ledMatrix[5][0] = 1;
    ledMatrix[5][1] = 1;
    ledMatrix[5][2] = 1;
    ledMatrix[5][3] = 1;
     Serial.print("eleven ");
        break;
      case 0:
      case 12:
    ledMatrix[7][0] = 1;
    ledMatrix[7][1] = 1;
    ledMatrix[7][2] = 1;
    ledMatrix[7][3] = 1;
     Serial.print("twelve ");
        break;
    }
  }
  else
  {
    // if we are greater than 34 minutes past the hour then display
    // the next hour, as we will be displaying a 'to' sign
    ledMatrix[2][6] = 1;
    ledMatrix[2][7] = 1;
     Serial.print("to ");
    //Serial.print(" to ");
    switch (theTime.hour()) {
      case 1:
      case 13:
    ledMatrix[4][0] = 1;
    ledMatrix[4][1] = 1;
     Serial.print("two ");
        break;
      case 14:
      case 2:
    ledMatrix[3][7] = 1;
    ledMatrix[3][6] = 1;
     Serial.print("three ");
        break;
      case 15:
      case 3:
    ledMatrix[4][2] = 1;
    ledMatrix[4][3] = 1;
    ledMatrix[4][4] = 1;
     Serial.print("four ");
        break;
      case 4:
      case 16:
    ledMatrix[5][6] = 1;
    ledMatrix[5][7] = 1;
     Serial.print("five ");
        break;
      case 5:
      case 17:
    ledMatrix[6][6] = 1;
    ledMatrix[6][7] = 1;
     Serial.print("six ");
        break;
      case 6:
      case 18:
    ledMatrix[6][3] = 1;
    ledMatrix[6][4] = 1;
    ledMatrix[6][5] = 1;
     Serial.print("seven ");
        break;
      case 7:
      case 19:
    ledMatrix[4][5] = 1;
    ledMatrix[4][6] = 1;
    ledMatrix[4][7] = 1;
     Serial.print("eight ");
        break;
      case 8:
      case 20:
    ledMatrix[6][0] = 1;
    ledMatrix[6][1] = 1;
    ledMatrix[6][2] = 1;
     Serial.print("nine ");
        break;
      case 9:
      case 21:
    ledMatrix[5][4] = 1;
    ledMatrix[5][5] = 1;
     Serial.print("ten ");
        break;
      case 10:
      case 22:
    ledMatrix[5][0] = 1;
    ledMatrix[5][1] = 1;
    ledMatrix[5][2] = 1;
    ledMatrix[5][3] = 1;
     Serial.print("eleven ");
        break;
      case 11:
      case 23:
    ledMatrix[7][0] = 1;
    ledMatrix[7][1] = 1;
    ledMatrix[7][2] = 1;
    ledMatrix[7][3] = 1;
     Serial.print("twelve ");
        break;
      case 0:
      case 12:
    ledMatrix[3][3] = 1;
    ledMatrix[3][4] = 1;
     Serial.print("one ");
        break;
    }
  }

//=======================================================
//=======================================================


//it's show time....

for(int i = 0; i < 8; i++) {
    for(int j = 0; j < 8; j++) {
      if (ledMatrix[i][j] == 1) {
        matrix.drawPixel(i, j, matrix.Color(255, 255, 0));
      }
      else {
        matrix.drawPixel(i, j, matrix.Color(0, 0, 0));
      }

    }
    Serial.println();
  }

//====================================================


displayTime();
checkArray();
matrix.show();

delay(5000);
resetArray();

}




void checkArray(){
  //print out the array to check it:
  for(int i = 0; i < 8; i++) {
    for(int j = 0; j < 8; j++) {
      Serial.print(ledMatrix[i][j]);
      Serial.print(",");
    }
    Serial.println();
  }
  Serial.println();
}


void resetArray(){
  //set all the array values to 0 (off):
  for(int i = 0; i < 8; i++) {
    for(int j = 0; j < 8; j++) {
      ledMatrix[i][j] = 0;
    }
  }
  Serial.print("Array reset (All LEDs switched set to off)");
  Serial.println();
  Serial.println();
}

void displayTime() {

  // get time from the RTC
  DateTime theTime = RTC.now();

  // serial print current time
  
  Serial.print(theTime.year(), DEC);
  Serial.print('/');
  Serial.print(theTime.month(), DEC);
  Serial.print('/');
  Serial.print(theTime.day(), DEC);
  Serial.print(' ');
  Serial.print(theTime.hour(), DEC);
  Serial.print(':');
  Serial.print(theTime.minute(), DEC);
  Serial.print(':');
  Serial.print(theTime.second(), DEC);
  Serial.println();
}

The header DST_RTC.h:


#include <Arduino.h>
#include "RTClib.h"

extern const char rulesDST[];

class DST_RTC
{
  public:
    DST_RTC();

    boolean checkDST(DateTime RTCTime);
    DateTime calculateTime(DateTime RTCTime);
};

The code DST_RTC.ccp:

#include "Arduino.h"
#include "DST_RTC.h"

DST_RTC::DST_RTC()
{

}

boolean DST_RTC::checkDST(DateTime RTCTime)
{

  // Get the day of the week. 0 = Sunday, 6 = Saturday
  int previousSunday = RTCTime.day() - RTCTime.dayOfTheWeek();
	
  boolean dst = false; //Assume we're not in DST
  if (strcmp(rulesDST, "US") == 0) {
    // Serial.print("test of rulesDST: ");
    // Serial.println(rulesDST);
    if (RTCTime.month() > 3 && RTCTime.month() < 11) dst = true; //DST is happening in America!
    //In the USA in March we are DST if the previous Sunday was on or after the 8th (and on or before the 14th).
    if (RTCTime.month() == 3)
    {
      if (RTCTime.dayOfTheWeek() == 0) {  // if today is Sunday
        if (previousSunday >= 8    // on or after 8th
            && previousSunday <= 14     // but on or before 14th
            && RTCTime.hour() >= 2)  // and at or after 2:00 AM
          dst = true;
        else if (previousSunday >= 15)  // it is a Sunday after the second Sunday
          dst = true;
      }
      else if (previousSunday >= 8) // it is not Sunday and we are after the change to DST
        dst = true;
    }
    //In November we must be before the first Sunday to be dst for USA.
    //In this case we are changing time at 2:00 AM so since the change to the previous Sunday
    //happens at midnight the previous Sunday is actually this Sunday at 2:00 AM
    //That means the previous Sunday must be on or before the 7th.
    if (RTCTime.month() == 11)   // November for the USA
    {
      if (RTCTime.dayOfTheWeek() == 0)   // if today is Sunday
      {
        if (previousSunday <= 7  // and it is also the first Sunday
            && RTCTime.hour() <= 1)  // less than 2:00 AM
          dst = true;
      }
      else if (previousSunday <= 0)   // it is not yet the first Sunday and the previous Sunday was before Nov 1
        dst = true;
    }
  }

  if (strcmp(rulesDST, "EU") == 0) {
    // Serial.print("test of rulesDST: ");
    // Serial.println(rulesDST);
    if (RTCTime.month() > 3 && RTCTime.month() < 10) dst = true; //DST is happening in Europe!
    //In Europe in March, we are DST if the previous Sunday was on or after the 25th.
    if (RTCTime.month() == 3)
    {
      if (RTCTime.dayOfTheWeek() == 0)    // Today is Sunday
      {
        if (previousSunday >= 25  // and it is a Sunday on or after 25th (there can't be a Sunday in March after this)
            && RTCTime.hour() >= 2)  // 2:00 AM for Europe
          dst = true;
      }
      else if (previousSunday >= 25) // if not Sunday and the last Sunday has passed
        dst = true;
    }
    //In October we must be before the last Sunday to be in DST for Europe.
    //In this case we are changing time at 2:00 AM so since the change to the previous Sunday
    //happens at midnight the previous Sunday is actually this Sunday at 2:00 AM
    //That means the previous Sunday must be on or before the 31st but after the 25th.
    if (RTCTime.month() == 10) // October for Europe
    {
      if (RTCTime.dayOfTheWeek() == 0)   // if today is Sunday
      {
        if (previousSunday >= 25  // and it is also on or after 25th
            && RTCTime.hour() <= 1)  // less than 2:00 AM for Europe
          dst = true;
        else if (previousSunday < 25)   // it is not yet the last Sunday
          dst = true;
      }
      else if // it is not Sunday
      (previousSunday < 25)
        dst = true;
    }
  }
  return dst;
}

DateTime DST_RTC::calculateTime(DateTime RTCTime)
{
  if (checkDST(RTCTime) == true) {
    RTCTime = RTCTime.unixtime() + 3600; // add 1 hour or 3600 seconds to the time
  }
  return RTCTime;
}

Any help will be much appreciated!

Thank you!

You've declared 'rulesDST' here:

But, you haven't defined it anywhere ... at least not in the code you've posted. See: https://www.cprogramming.com/declare_vs_define.html

Welcome

Look at the example of that DST_RTC library : DST_RTC/DST_RTCbasicSketch.ino at master · andydoro/DST_RTC · GitHub

But I suggest to use another library : Timezone/HardwareRTC.ino at master · JChristensen/Timezone · GitHub

The readme file says:

The new version requires explicit definition of whether to use US or EU rules.

I suspect the project code you loaded pre-dates that change. You probably need to add:

// Define US or EU rules for DST comment out as required. More countries could be added with different rules in DST_RTC.cpp
const char rulesDST[] = "US"; // US DST rules
// const char rulesDST[] = "EU";   // EU DST rules

to your (the?) sketch.

1 Like

Thanks, everyone for pitching in! @westfw that did it! Great spot! Thank you!

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