Hello fine people,
I'm using an Arduino Uno R3
128x64 oled display
DS3231 RTC
2 buttons
2 x 330 ohm resistors
Can anyone tell me why the clock time isn't changing automatically on my display?
When I press the button connected to pinMode(9, INPUT); it updates the time on the display but otherwise it sits at

until the button is pressed again.
Also, I'm trying to delete the alarm function completely. I've taken out everything referencing an alarm but when I take out the remaining few alarm related lines I get slammed with errors, so far mostly about exit status 1 'printDay' was not declared in this scope in line 125 or 127:7: error: 'printMonth' was not declared in this scope in line 127 among several others.
For expamle, deleting anything between lines 337 and 354.
(Sorry, googling now how to display line numbers on this post)
#include <SPI.h> //Library for Adafruit communication to OLED display
#include <Wire.h> //I2C communication library
#include "ds3231.h" //Real Time Clock library
#include <Adafruit_GFX.h> //Graphics library
#include <Adafruit_SSD1306.h> //OLED display library
#include <EEPROM.h> //This library allows reading and writing to the EEPROM
//Uncomment following line to enable display dimming between 10 PM and 5 AM
#define dimming
int framecount2 = 0; //Counter for number of display update periods
//uint8_t secset = 0; //Index for second RTC setting
uint8_t minset = 1; //Index for minute RTC setting
uint8_t hourset = 2; //Index for hour RTC setting
uint8_t wdayset = 3; //Index for weekday RTC setting
uint8_t mdayset = 4; //Index for date RTC setting
uint8_t monset = 5; //Index for month RTC setting
uint8_t yearset = 6; //Index for year RTC setting
//Alarm time variables
uint8_t wake_HOUR = 0;
uint8_t wake_MINUTE = 0;
uint8_t wake_SECOND = 0;
uint8_t wake_SET = 0; //Default alarm to ON in case of power failure or reset
#define OLED_RESET 4 //Define reset for OLED display
Adafruit_SSD1306 display(OLED_RESET); //Reset OLED display
//Check for proper display size - required
#if (SSD1306_LCDHEIGHT != 64)
#endif
unsigned long prev, interval = 100; //Variables for display/clock update rate
byte flash = 0; //Flag for display flashing - toggle once per update interval
byte mode = 0; //Mode for time and date setting
int tempset; //Temporary variable for setting time/date
int beepcount = 0; //Variable for number of 100ms intervals since alarm started sounding
const int alarmEE = 0; //EEPROM alarm status storage location
void setup()
{
Serial.begin(9600); //Initialize serial port, if needed (not used)
Wire.begin(); //Initialize I2C communication library
pinMode(8, INPUT); //Set pin for time/date mode button to input
digitalWrite(8, HIGH); //Turn on pullup resistors
pinMode(9, INPUT); //Set pin for time/date set button to input
digitalWrite(9, HIGH); //Turn on pullup resistors
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64 OLED display)
display.setTextSize(1); //Set default font size to the smalles
display.setTextColor(WHITE); //Set font to display color on black background
display.dim(0); //Set display to full brightness
display.invertDisplay(0); //Set display to normal video
// init done
}
void loop()
{
//char tempF[6]; //Local variable to store converted temperature reading from Real Time Clock module
//float temperature; //Intermediate temperature variable to convert Celsius to Farenheit
unsigned long now = millis(); //Local variable set to current value of Arduino internal millisecond run-time timer
struct ts t; //Structure for retrieving and storing time and date data from real time clock
//Draw and update display every refresh period (100ms)
if ((now - prev > interval)) { //Determine whether to start a time and screen update
framecount2 = framecount2 + 1; //Update counter of refresh periods
if (framecount2 > 300) {
framecount2 = 0; //Wrap the refresh period counter to 0 after 300 updates,
mode = 0; //Reset mode to normal every cycle unless setting buttons pressed to reset cycle counter
}
if (flash == 0) {
flash = 1; //Toggle flash flag for cursor blinking later
} else {
flash = 0;
}
DS3231_get(&t); //Get time and date and save in t structure
#if defined(dimming)
if (t.hour >= 18 || t.hour < 5) {
display.dim(1); //Dim the display between 7 PM and 5 AM
}
else {
display.dim(0); //Otherwise set display to full brightness
}
#endif
display.clearDisplay(); //Clear display buffer from last refresh
//NOTE: Alarm indicators are overwritten in display buffer if full-screen animation is displayed, so no check for that
if (mode <= 7) { //Alarm indicators and actions in normal and time set display mode only
if (wake_SET) { //Display alarm on indicator if alarm turned on
display.setCursor(80, 8); //Position text cursor for alarm on indicator
display.print("*"); //Print character between time and temperature if alarm on
}
}
if (wake_SET && DS3231_triggered_a1()) { //Display/sound alarm if enabled and triggered
if (beepcount <= 600) { //Sound alarm for 60 seconds
if (!flash) { //Flash display and sound interrupted beeper
}
}
}
if (mode <= 7) {
//DO NOT CHANGE CURSOR POSITIONING OF TIME AND DATE TEXT FIELDS OR TIME/DATE SET CURSOR WON'T MATCH!!!
display.setCursor(0, 0); //Position cursor for day-of-week display
printDay(t.wday); //Lookup day of week string from retrieved RTC data and write to display buffer
printMonth(t.mon); //Lookup month string from retrieved RTC data and write to display buffer
if (t.mday < 10) {
display.print("0"); //Add leading zero to date display if date is single-digit
}
display.print(t.mday); //Write date to display buffer
display.print(", "); //Write spaces and comma between date and year
display.print(t.year); //Write year to display buffer
display.setCursor(0, 8); //Position text cursor for time display
//RTC is operated in 24-hour mode and conversion to 12-hour mode done here, in software
if (t.hour == 0) {
display.print("12"); //Convert zero hour for 12-hour display
}
else if (t.hour < 13 && t.hour >= 10) {
display.print(t.hour); //Just display hour if double digit hour
}
else if (t.hour < 10) {
display.print(" "); //If single digit hour, add leading space
display.print(t.hour);
}
else if (t.hour >= 13 && t.hour >= 22) {
display.print(t.hour - 12); //If double digit and PM, convert 24 to 12 hour
}
else {
display.print(" "); //If single digit and PM, convert to 12 hour and add leading space
display.print(t.hour - 12);
}
display.print(":"); //Display hour-minute separator
if (t.min < 10) {
display.print("0"); //Add leading zero if single-digit minute
}
display.print(t.min); //Display retrieved minutes
display.print(":"); //Display minute-seconds separator
if (t.sec < 10) {
display.print("0"); //Add leading zero for single-digit seconds
}
display.print(t.sec); //Display retrieved seconds
if (t.hour < 12) {
display.print(" AM"); //Display AM indicator, as needed
}
else {
display.print(" PM"); //Display PM indicator, as needed
}
//Position and draw hour tick marks
for ( int z = 0; z < 360; z = z + 30 ) {
}
}
if (mode > 7) {
display.setCursor(0, 0); //Position text cursor
// display.print("Alarm Set: ");
// if(wake_SET){display.print("ON");}else{display.print("OFF");}
display.setCursor(0, 8); //Position text cursor for time display
//RTC is operated in 24-hour mode and conversion to 12-hour mode done here, in software
if (wake_HOUR == 0) {
display.print("12"); //Convert zero hour for 12-hour display
}
else if (wake_HOUR < 13 && wake_HOUR >= 10) {
display.print(wake_HOUR); //Just display hour if double digit hour
}
else if (wake_HOUR < 10) {
display.print(" "); //If single digit hour, add leading space
display.print(wake_HOUR);
}
else if (wake_HOUR >= 13 && wake_HOUR >= 22) {
display.print(wake_HOUR - 12); //If double digit and PM, convert 24 to 12 hour
}
else {
display.print(" "); //If single digit and PM, convert to 12 hour and add leading space
display.print(wake_HOUR - 12);
}
display.print(":"); //Display hour-minute separator
if (wake_MINUTE < 10) {
display.print("0"); //Add leading zero if single-digit minute
}
display.print(wake_MINUTE); //Display retrieved minutes
display.print(":"); //Display minute-seconds separator
if (wake_SECOND < 10) {
display.print("0"); //Add leading zero for single-digit seconds
}
display.print(wake_SECOND); //Display retrieved seconds
if (wake_HOUR < 12) {
display.print(" AM"); //Display AM indicator, as needed
}
else {
display.print(" PM"); //Display PM indicator, as needed
}
}
//Time/Date setting button processing and cursor flashing
//CURSOR COORDINATES ARE SET TO MATCH TIME/DATE FIELD - DO NOT CHANGE!!
//Digital and analog time/date display updates with new settings at 5Hz as settings are changed
switch (mode)
{
case 0: break;
case 1: //Day-of-week setting
if (flash) {
display.drawRect(0, 0, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.wday; //Get the current weekday and save in temporary variable
tempset = tempset + 1; //Increment the day at 5Hz rate
if (tempset > 7) {
tempset = 1; //Roll over after 7 days
}
t.wday = tempset; //After each update, write the day back to the time structure
set_rtc_field(t, wdayset); //Write the set field only back to the real time clock module after each update
}
break;
case 2: //Month setting
if (flash) {
display.drawRect(24, 0, 18, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.mon; //Get the current month and save in temporary variable
tempset = tempset + 1; //Increment the month at 5Hz rate
if (tempset > 12) {
tempset = 1; //Roll over after 12 months
}
t.mon = tempset; //After each update, write the month back to the time structure
set_rtc_field(t, monset); //Write the set field only back to the real time clock module after each update
}
break;
case 3: //Date setting
if (flash) {
display.drawRect(48, 0, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.mday; //Get the current date and save in temporary variable
tempset = tempset + 1; //Increment the date at 5Hz rate
//(RTC allows incorrect date setting for months < 31 days, but will use correct date rollover for subsequent months.
if (tempset > 31) {
tempset = 1; //Roll over after 31 days
}
t.mday = tempset; //After each update, write the date back to the time structure
set_rtc_field(t, mdayset); //Write the set field only back to the real time clock module after each update
}
break;
case 4: //Year setting
if (flash) {
display.drawRect(72, 0, 24, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.year; //Get the current year and save in temporary variable
tempset = tempset + 1; //Increment the year at 5Hz rate
//RTC allows setting from 1900, but range limited here to 2000 to 2099
if (tempset > 2099) {
tempset = 2000; //Roll over after 2099 to 2000
}
t.year = tempset; //After each update, write the year back to the time structure
set_rtc_field(t, yearset); //Write the set field only back to the real time clock module after each update
}
break;
case 5: //Hour setting
if (flash) {
display.drawRect(0, 8, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.hour; //Get the current hour and save in temporary variable
tempset = tempset + 1; //Increment the hour at 5Hz rate
if (tempset > 23) {
tempset = 0; //Roll over hour after 23rd hour (setting done in 24-hour mode)
}
t.hour = tempset; //After each update, write the hour back to the time structure
set_rtc_field(t, hourset); //Write the set field only back to the real time clock module after each update
}
break;
case 6: //Minute setting
if (flash) {
display.drawRect(18, 8, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
tempset = t.min; //Get the current minute and save in temporary variable
tempset = tempset + 1; //Increment the minute at 5Hz rate
if (tempset > 59) {
tempset = 0; //Roll over minute to zero after 59th minute
}
t.min = tempset; //After each update, write the minute back to the time structure
set_rtc_field(t, minset); //Write the set field only back to the real time clock module after each update
}
break;
//Set clock + 1 minute, then press and hold to freeze second setting.
//Release button at 00 seconds to synchronize clock to external time source.
case 7: //Second synchronization
if (flash) {
display.drawRect(36, 8, 12, 8, WHITE); //Display rectangle cursor every other display update (5Hz blink)
}
if (!digitalRead(9) && (!flash)) { //Reset second to zero at 5Hz rate if button held down
t.sec = 0; //After each update, write the zeroed second back to the time structure
// set_rtc_field(t, secset); //Write the set field only back to the real time clock module after each update
}
break;
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
}
break;
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
}
break;
if (!digitalRead(9) && (!flash)) { //Update setting at 5Hz rate if button held down
}
break;
}
prev = now; //Reset variable for display and time update rate
display.display(); //Display the constructed frame buffer for this framecount
}
//Clock setting mode set - outside time/display update processing for faster button response
if (!digitalRead(8)) { //Read setting mode button
delay(25); //100ms debounce time
if (!digitalRead(8)) { //Activate setting mode change after 100ms button press
mode = mode + 1; //Increment the time setting mode on each button press
framecount2 = 0; //Reset cycle counter if button pressed to delay auto return to normal mode
if (mode > 10) {
mode = 0; //Roll the mode setting after 7th mode
}
while (!digitalRead(8)) {} //Wait for button release (freezes all display processing and time updates while button held, but RTC continues to keep time)
}
}
if (!digitalRead(9)) { //Reset alarm flag if set button pressed
delay(25); //25ms debounce time
if (!digitalRead(9)) {
DS3231_clear_a1f(); //Reset cycle counter if button pressed to delay auto return to normal mode
framecount2 = 0;
}
}
}
//Function to display month string from numerical month argument
void printMonth(int month)
{
switch (month)
{
case 1: display.print("Jan "); break;
case 2: display.print("Feb "); break;
case 3: display.print("Mar "); break;
case 4: display.print("Apr "); break;
case 5: display.print("May "); break;
case 6: display.print("Jun "); break;
case 7: display.print("Jul "); break;
case 8: display.print("Aug "); break;
case 9: display.print("Sep "); break;
case 10: display.print("Oct "); break;
case 11: display.print("Nov "); break;
case 12: display.print("Dec "); break;
default: display.print("--- "); break; //Display dashes if error - avoids scrambling display
}
}
//Function to display day-of-week string from numerical day-of-week argument
void printDay(int day)
{
switch (day)
{
case 1: display.print("Mon "); break;
case 2: display.print("Tue "); break;
case 3: display.print("Wed "); break;
case 4: display.print("Thu "); break;
case 5: display.print("Fri "); break;
case 6: display.print("Sat "); break;
case 7: display.print("Sun "); break;
default: display.print("--- "); break; //Display dashes if error - avoids scrambling display
}
}
//Subroutine to adjust a single date/time field in the RTC
void set_rtc_field(struct ts t, uint8_t index)
{
uint8_t century;
if (t.year > 2000) {
century = 0x80;
t.year_s = t.year - 2000;
} else {
century = 0;
t.year_s = t.year - 1900;
}
uint8_t TimeDate[7] = { t.sec, t.min, t.hour, t.wday, t.mday, t.mon, t.year_s };
Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(index);
TimeDate[index] = dectobcd(TimeDate[index]);
if (index == 5) {
TimeDate[5] += century;
}
Wire.write(TimeDate[index]);
Wire.endTransmission();
//Adjust the month setting, per data sheet, if the year is changed
if (index == 6) {
Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(5);
TimeDate[5] = dectobcd(TimeDate[5]);
TimeDate[5] += century;
Wire.write(TimeDate[5]);
Wire.endTransmission();
}
}
Also, the tutorial I'm following didn't use resistors but I still had some connected to the buttons from a previous tutorial and this doesn't seem to work without them. It constantly changes the digits on the screen.
I've got this sketch to compile with no errors so now I'm trying to edit it closer to what I'm looking for. In my deleting however, I'm wondering if I've gotten rid of some things I need for regular function. I can upload a version of the sketch I'm using with the deleted lines commented instead of deleted if that would be more helpful to see.
Please forgive my limited understanding of not only what's going on here but also with any feedback you're able to contribute. But as always, thanks so much for your help, reading this far, and for existing. I never would've made it this far without the help of this forum!


