I've read a few posts on this topic, but I'm getting nowhere:
I want to make my code more readable using object oriented structures. However, I haven't gotten far and am failing at the basics. I now have three tabs, the main program, a header tab and a CPP tab. The three are neatly stored as separate files.
#ifndef my_RD40_H
#define my_RD40_H
#include <Arduino.h>
class my_RD40 {
private:
int _Sec; // Sekunden (0-59)
int _Min; // Minuten (0-59)
int _Hour; // Stunden (0-23)
int _Mday; // Tag des Monats (1-31)
int _Mon; // Monat (0-11)
int _Year; // Jahr - 1900
int _Wday; // Tag der Woche (0-6, Sonntag = 0)
public:
my_RD40(); // Constructor
void setTime();
void getTime();
int Sec();
int Min();
int Hour();
int Mday();
int Mon();
int Year();
int Wday();
};
#endif
my_RD40.cpp
#include "my_RD40.h"
#include <Wire.h>
#include <TimeLib.h>
#define SDA 2
#define SCL 0
#define LOCATION TZ_Europe_Berlin // replace with your location
#define NTP "pool.ntp.org"
my_RD40::my_RD40() {
// Setup I2C
Wire.begin(SDA,SCL); // SDA=GPIO2 / SCL=GPIO0 ==> registers the controller as I2C Master
Wire.setClock(200000L);
}
void my_RD40::setTime() {
configTime(LOCATION, NTP);
while (!time(nullptr)) { // Wait until time is initialized
delay(1000);
}
setTime(hour(), minute(), second(), day(), month(), year()); // Set internal clock
}
void my_RD40::getTime() {
time_t now = time(nullptr); // recall time from internal clock
_Hour = hour(now);
_Min = minute(now);
_Sec = second(now);
_Mday = day(now);
_Mon = month(now);
_Year = year(now);
_Wday = weekday(now);
}
int my_RD40::Sec() {
return _Sec;
}
int my_RD40::Min() {
return _Min;
}
int my_RD40::Hour() {
return _Hour;
}
int my_RD40::Mday() {
return _Mday;
}
int my_RD40::Mon() {
return _Mon;
}
int my_RD40::Year() {
return _Year;
}
int my_RD40::Wday() {
return _Wday;
}
I get several "undefined reference" errors when compiling. It looks like they are pointing to the main tab.
fair enough. I have deleted some path information though:
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o:(.text.setup+0xc): undefined reference to `_ZN7my_RD407setTimeEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o:(.text.setup+0x10): undefined reference to `_ZN7my_RD407getTimeEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o:(.text.setup+0x14): undefined reference to `_ZN7my_RD404HourEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o:(.text.setup+0x18): undefined reference to `_ZN7my_RD403MinEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o:(.text.setup+0x1c): undefined reference to `_ZN7my_RD403SecEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o: in function `setup':
C:\Users\.....\RD40/RD40.ino:23: undefined reference to `_ZN7my_RD407setTimeEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\.....\RD40/RD40.ino:28: undefined reference to `_ZN7my_RD407getTimeEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\.....\RD40/RD40.ino:28: undefined reference to `_ZN7my_RD404HourEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\.....\RD40/RD40.ino:29: undefined reference to `_ZN7my_RD403MinEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\.....\RD40/RD40.ino:30: undefined reference to `_ZN7my_RD403SecEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o: in function `loop':
C:\Users\.....\RD40/RD40.ino:31: undefined reference to `_ZN7my_RD407getTimeEv'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\.....\RD40/RD40.ino:40: undefined reference to `_ZN7my_RD40C1Ev'
c:/users/...../appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\RD40.ino.cpp.o: in function `_GLOBAL__sub_I_RD40':
C:\Users\.....\RD40/RD40.ino:40: undefined reference to `_ZN7my_RD40C1Ev'
collect2.exe: error: ld returned 1 exit status
Mehrere Bibliotheken wurden für "SD.h" gefunden
Benutzt: C:\Users\.....\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\SD
Nicht benutzt: C:\Program Files (x86)\Arduino\libraries\SD
exit status 1
Fehler beim Kompilieren für das Board Generic ESP8285 Module.
I mention this because the error message posted points in this direction. Thanks for posting the error message.
I see that GPIO_NUM_2 of the ESP32 developer module is being used for the SDA line to transmit I2C data.
Most ESP32 developer boards have the onboard LED at GPIO_2. I have found that the circuit required to run the LED may cause issues when transmitting data via GPIO_NUM_2.
The natural I2C pins for the ESP32 under the Arduino IDE should be used for I2C; see your developers board pinout.
The error message also points to an issue in loop() and setup(), I'd comment all the code in loop(). Comment out all
void setup()
{
// Serial port for debugging purposes
Serial.begin(115200);
RD40.setTime();
//RD40.getTime();
//Serial.printf("Zeit: %d:%d:%d\n", RD40.Hour(), RD40.Min(), RD40.Sec());
}
I should have mentioned, that I am using an ESP8266-01s. As you know, this tiny board only has two IO pins available.
I2C
I do have running (and very comprehensive) C code for the controller, which I just would like to restructure. I found that it actually is possible to use the two I/O lines on the ESP-01s as I2C pins.
ESP32Time
Thank you for the hint. However, as I run the code on an ESP8266, this might not work. I have been struggling with the various time libraries (time.h, tineLib.h, etc.) for long. I just do not understand why such a base function is so cumbersome to deal with.
The thought behind the my_RD40 class is to create a class that manages the hardware layer (i2C, Wifi, and time). However, I failed with the class structure already.
Unfortunately, I am traveling now and can only continue to work on the code next weekend. I will let you know, what I find out.
the error was in the method my_RD40::setTime(). Inside this method I had used the function setTime(hour(), minute(), second(), day(), month(), year()). This is a function of TimeLib.h. However, I had used the same name (namely setTime()) also for my own method. Thus there was the name twice - that was then too much of a good thing.
Just for the eternal files of the forum the corrected and working code:
RD40
#include "my_RD40.h"
my_RD40 RD40; // generate RD40 object
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
RD40.setMyTime();
RD40.getMyTime();
Serial.printf("Zeit: %d:%d:%d\n", RD40.Hour(), RD40.Min(), RD40.Sec());
}
void loop() {
RD40.getMyTime();
}
my_RD40.h
#ifndef my_RD40_H
#define my_RD40_H
#include <Arduino.h>
class my_RD40 {
private:
int _Sec; // Sekunden (0-59)
int _Min; // Minuten (0-59)
int _Hour; // Stunden (0-23)
int _Mday; // Tag des Monats (1-31)
int _Mon; // Monat (0-11)
int _Year; // Jahr - 1900
int _Wday; // Tag der Woche (0-6, Sonntag = 0)
public:
my_RD40(); // Constructor
void setMyTime();
void getMyTime();
int Sec();
int Min();
int Hour();
int Mday();
int Mon();
int Year();
int Wday();
};
#endif
my_RD40.cpp
#include "my_RD40.h"
#include <TimeLib.h>
#include <TZ.h>
#include <Wire.h>
#define _SDA 2
#define _SCL 0
#define LOCATION TZ_Europe_Berlin // replace with your location
#define NTP "pool.ntp.org"
my_RD40::my_RD40() {
// Setup I2C
Wire.begin(_SDA,_SCL); // SDA=GPIO2 / SCL=GPIO0 ==> registers the controller as I2C Master
Wire.setClock(200000L);
}
void my_RD40::setMyTime() {
configTime(LOCATION, NTP);
while (!time(nullptr)) { // Wait until time is initialized
delay(1000);
}
setTime(hour(), minute(), second(), day(), month(), year()); // Set internal clock
}
void my_RD40::getMyTime() {
time_t now = time(nullptr); // recall time from internal clock
_Hour = hour(now);
_Min = minute(now);
_Sec = second(now);
_Mday = day(now);
_Mon = month(now);
_Year = year(now);
_Wday = weekday(now);
}
int my_RD40::Sec() {
return _Sec;
}
int my_RD40::Min() {
return _Min;
}
int my_RD40::Hour() {
return _Hour;
}
int my_RD40::Mday() {
return _Mday;
}
int my_RD40::Mon() {
return _Mon;
}
int my_RD40::Year() {
return _Year;
}
int my_RD40::Wday() {
return _Wday;
}