I'm trying to create a simple digital clock, at first I thought all is working until I noticed that the time isn't really refreshing/updating. I used the "toString" because I thought it could save weird bugs I was having when using too much of the "now.year" , "now.month", ""now.day", etc. Can someone please tell how to write the code properly
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
#define i2c_Address 0x3c
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
Wire.beginTransmission(0x68); // address DS3231
Wire.write(0x0E); // select register
Wire.write(0b00011100);
Wire.endTransmission();
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
display.begin(i2c_Address, true);
display.clearDisplay();
}
void loop() {
DateTime now = rtc.now();
//date
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(4,4);
display.println(now.toString("MMM DD, YYYY"));
//day
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(4,15);
display.println(daysOfTheWeek[now.dayOfTheWeek()]);
//time
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(4,25);
display.print(now.toString("hh:mm:ss ap"));
//??This part is updating but the the other parts aren't
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(80,25);
display.println(now.second());
display.display();
display.clearDisplay();
}
Hi @LuXian.
You are using the display.clearDisplay() function; every round of the loop().
Each round of the loop() is very fast and is probably crashing your display).
Just for testing, put a delay of 500mSeg (delay(500); ) before the function display.clearDisplay(); and see if it refreshes the screen,
Do not use a string literal with the toString function, the function replaces the format text with the output text. Declare a char array and initialize it to the format text prior to the toString function, that way it gets recreated every time loop is executed.
The main point is that this code will only work once:
display.print(now.toString("hh:mm:ss ap"));
The compiler initializes the text literal "hh:mm:ss ap" at the start of the sketch, and expects that it will remain unchanged forever. When you call the now.toString function, the text is replaced with the current time in the format you have specified, and then returns a pointer to that text so that it can be printed. The next time you call now.toString, it does not see "hh:mm:ss ap", but say "11:30:15 am", which does not match any of its formatting code, so it remains unchanged and you end up printing the same time over and over again.
You should have gotten at least a compiler warning for passing it a string literal. Check your warning level setting in the IDE under "File --> Preferences --> Compiler warnings".
thanks a lot, I inserted the code and it did work.
Altho the
doesn't really affect the code. There's no warning, but I added it for safekeeping. The only thing I want to add now is to make it editable with push buttons.
I wasn't saying that you should add that prototype to your code. Look in RTClib.h and you'll find the prototype:
char *toString(char *buffer);
That explains why you can't pass it a pointer to a string literal. And, if your IDE setting are correct, you will definitely get at least a warning (if not an error) for trying to do so.