Hello,
I am using a RTC (the DS1307) and an Arduino nano ESP32. The problem is that the RTC isn't confident in date and time. Or in my program, it gives the error message 1R6 on the OLED display all the time.
I don't have a battery, it is powered by a power supply, and that works. Because if I use the standard program from the RTC library by Makuna, it works fine. I have basically copied and pasted the whole example to fit in my program.
This is my program:
/*
* CONNECTIONS:
* - DS1337:
* - SDA (D2)
* - SCL (D5)
* - +3V (+ BATTERY)
* - GND (- BATTERY)
* - X1 (CRYSTAL)
* - X2 (CRYSTAL)
*
* - OT811:
* - SDA (A4)
* - SCK (A5)
* - Vcc (+3.3V)
* - GND (GND)
*
*
* ERRORS:
* - ERROR 1Dx
* - ERROR 1D1
* - The internal voltage of the OLED-display is not +3.3V. The arduino will continue looping. Try (dis)connection the power or replace the OLED-display.
*
* - ERROR 1Rx
* - ERROR 1R1
* - The battery of the RTC is low or missing. Or the RTC wasn't running yet. Restart the program, else, replace the battery.
* - ERROR 1R2
* - The RTC wasn't running, please reset the arduino.
* - ERROR 1R3
* - The RTC time is older than the real time. Nothing has to be done, the arduino will set it right.
* - ERROR 1R4
* - There is an error message but no error, please reset the arduino.
* - ERROR 1R5
* - There are too much messages waiting on the RTC, please reset the arduino.
* - ERROR 1R6
* - There is no device responding to the arduino, please check the RTC battery and the RTC itself.
* - ERROR 1R7
* - The RTC has a wrong chip, place replace the RTC with a DS1337.
* - ERROR 1R8
* - The communication with the RTC takes to long, please check the battery of the RTC, the RTC itself and if the RTC is connected with the arduino.
* - ERROR 1R9
* - There is an error message but it isn't further specified.
*
*
*
*
*/
#include <Wire.h> //library to establish I²C connection
#include <Adafruit_GFX.h> //library to print and draw on the OLED-display
#include <Adafruit_SSD1306.h> //library to establish connection with the OLED-display
#include <RtcDS1307.h> //library to convert incoming data from the RTC
#include <ThreeWire.h>
#define RTC_SDA 2 //define the SDA port of the RTC
#define RTC_SCL 5 //define the SCL port of the RTC
#define ALL_SDA 4 //define the SDA port of the ATtiny85's and the OLED-display
#define ALL_SCL 5 //define the SCL port of the ATtiny85's and the OLED-display
#define SCREEN_WIDTH 128 //OLED display width, in pixels
#define SCREEN_HEIGHT 32 //OLED display height, in pixels
#define OLED_RESET -1 //variable to connect the screen with the reset of the arduino (needs to be -1 to share the reset)
#define SCREEN_ADDRESS 0x3C //adress of the OLED-display
#define error_time 5000 //the time an error will be displayed
RtcDS1307<TwoWire> Rtc(Wire); //configure the RTC
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //configure the OLED-display
bool true_error = false; //this boolean will be set true if there is an error
void print_error(String error_code){ //void to display an error
if(error_code == "START-UP"){
display.clearDisplay(); //clear the display
display.setTextSize(2); //set the text size to 2
display.setCursor(2, 2); //set the cursor on the display on pixel 2, 2
display.print("START-UP"); //write the error
display.display(); //display the error
true_error = false; //set the error boolean false
delay(1500); //wait some time before the main program will start
}
else{
display.clearDisplay(); //clear the display
display.setTextSize(2); //set the text size to 2
display.setCursor(2, 2); //set the cursor on the display on pixel 2, 2
display.print("ERROR: "); //write "ERROR: "
display.setCursor(70, 2); //set the cursor on the display on pixel 32, 2
display.print(error_code); //write the error code
display.display(); //display the error
true_error = true; //set the error boolean true
}
}
bool wasError(const char* errorTopic = ""){ //function to determine the right error
uint8_t error = Rtc.LastError(); //set the variable "error" to the last error that isn't processed
if (error != 0){ //if the error variable isn't empty, so there is an error
switch (error){ //compare the error to different kinds of errors to determine the right error message
case Rtc_Wire_Error_None: //if the error message is nothing
print_error("1R4"); //start the void print_error with the error message 1R4
break; //exit the switch case
case Rtc_Wire_Error_TxBufferOverflow: //if there are too much messages waiting for the RTC
print_error("1R5"); //start the void print_error with the error message 1R5
break; //exit the switch case
case Rtc_Wire_Error_NoAddressableDevice: //if there isn't a device responding to the messages of the arduino
print_error("1R6"); //start the void print_error with the error message 1R6
break; //exit the switch case
case Rtc_Wire_Error_UnsupportedRequest: //if there is a wrong RTC connected
print_error("1R7"); //start the void print_error with the error message 1R7
break; //exit the switch case
case Rtc_Wire_Error_CommunicationTimeout: //if the communication takes to long
print_error("1R8"); //start the void print_error with the error message 1R8
break; //exit the switch case
case Rtc_Wire_Error_Unspecific: //if there is an error but it isn't further specified
if(!true_error){ //only if there is no other error message, this one can be displayed
print_error("1R9"); //start the void print_error with the error message 1R9
}
break; //exit the switch case
}
return true; //return the value true
}
return false; //return the value false
}
void setup() {
Wire.begin(); //start the I²C communication
Serial.begin(115200); //start the serial communication
Rtc.Begin(2, 5); //set the RTC to the dedicated pins.
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
Rtc.Begin(); //start the RTC
#if defined(WIRE_HAS_TIMEOUT) //if the I²C communication has a time-out
Wire.setWireTimeout(3000 /* us */, true /* reset_on_timeout */); //reset on time-out
#endif //close the if statement
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); //set the RTC time to the real time
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)){ //if the internal OLED display voltage isn't 3.3V, don't stop the loop protect the OLED display
Serial.println(F("ERROR: 1D1")); //print the error on the serial monitor
true_error = true; //set the error bool true
for(;;); //go in an infinite loop
}
display.setTextSize(1); //set the standard text size to 1
display.setTextColor(WHITE); //set the standard text color to white
display.clearDisplay(); //clear the display
if (!Rtc.IsDateTimeValid()){ //if there is an error in the communication with the RTC
if (!wasError("setup IsDateTimeValid")){ //if the time obtained from the RTC isn't valid
print_error("1R1"); //start the void print_error with the error message 1R1
Rtc.SetDateTime(compiled); //set the RTC time as an atempt to regain the right connection and communication
}
}
if (!Rtc.GetIsRunning()){ //if the RTC isn't running
if (!wasError("setup GetIsRunning")){ //if the message "setup GetIsRunning" hasn't appeared internally
print_error("1R2"); //start the void print_error with the error message 1R2
Rtc.SetIsRunning(true); //start the RTC
}
}
RtcDateTime now = Rtc.GetDateTime(); //get the RTC time to compare with the real time
if (!wasError("setup GetDateTime")){ //there wasn't an error where the RTC wasn't running
if (now < compiled){ //if the RTC time is older than the real time
print_error("1R3"); //start the void print_error with the error message 1R3
Rtc.SetDateTime(compiled); //set the RTC time to the time the program was compiled
}
else if (now > compiled){ //if the RTC time is newer than the real time
print_error("START-UP"); //start the void print_error with the start message START-UP
}
else if (now == compiled){ //if the RTC time is the same as the real time
print_error("START-UP"); //start the void print_error with the start message START-UP
}
}
Rtc.SetSquareWavePin(DS1307SquareWaveOut_Low); //clear the RTC to the needed state
wasError("setup SetSquareWavePin"); //set RTC message to "setup SetSquareWavePin"
}
void loop() {
if (!Rtc.IsDateTimeValid())
{
if (!wasError("loop IsDateTimeValid"))
{
// Common Causes:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}
}
RtcDateTime now = Rtc.GetDateTime();
if (!wasError("loop GetDateTime"))
{
printDateTime(now);
Serial.println();
}
delay(1000); // ten seconds
}
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime& dt){ //void to print the time on the OLED-display
display.setTextSize(1); //set the text size to 1
display.clearDisplay(); //clear the display
if(dt.Day() >= 10){ //if the day is a duble digit number
display.setCursor(3,2); //set the cursor to position 3, 2
display.print(dt.Day()); //print the day
}
else{
display.setCursor(3, 2); //set the cursor to position 3, 2
display.print("0"); //print 0
display.setCursor(15,2); //set the cursor to position 11, 2
display.print(dt.Day()); //print the day
}
display.setCursor(17, 2); //set the cursor to position 17, 2
display.print("/"); //print /
if(dt.Month() >= 10){
display.setCursor(24, 2); //set the cursor to position 24, 2
display.print(dt.Month()); //print the month
}
else{
display.setCursor(24, 2); //set the cursor to position 24, 2
display.print("0"); //print 0
display.setCursor(36, 2); //set the cursor to position 32, 2
display.print(dt.Month()); //print the month
}
display.setCursor(38, 2); //set the cursor to position 37, 2
display.print("/"); //print /
display.setCursor(44, 2); //set the cursor to position 45, 2
display.print(dt.Year()); //print the year
display.setTextSize(2); //set the text size to 2
if(dt.Hour() >= 10){ //if the hour has 2 digits
display.setCursor(3, 15); //set the cursor to position 3, 15
display.print(dt.Hour()); //print the hour
}
else{
display.setCursor(3, 15); //set the cursor to position 3, 15
display.print("0"); //print 0
display.setCursor(15, 15); //set the cursor to position 11, 15
display.print(dt.Hour()); //print the hour
}
display.setCursor(25, 15); //set the cursor to position 25, 15
display.print(":"); //print :
if(dt.Minute() >= 10){
display.setCursor(35, 15); //set the cursor to position 37, 15
display.print(dt.Minute()); //print the minute
}
else{
display.setCursor(35, 15); //set the cursor to position 3, 15
display.print("0"); //print 0
display.setCursor(49, 15); //set the cursor to position 11, 15
display.print(dt.Minute()); //print the hour
}
display.display(); //display the prepared text
delay(10); //wait 10 milliseconds to cool the processor off
}
So does anybody know what the solution is for this problem?
Thank you.