I have a OLED SSD1306 & DS3231 RTC, 2 buttons to set the time & date. My project is to display a scrolling text at the top of the OLED, the RTC time in the middle, the day & date on the last line. My issue is I can't get the scrolling text & the time to run right when in the loop together, individually they work normal. When they are together, the scrolling text is fine, but the time is static, its not displaying the current RTC. Then after 1 loop cycle the time seconds text become jumbled, then after a 2nd cycle the minutes & seconds become jumbled. I have tried putting display.clearDisplay(); display.display(); at the end of the loop, doing this fixes the time from becoming jumbled by clearing the buffer before the next cycle, but does not fix the time from being static. How can I get the time to not be static anymore? Any help would be greatly appreciated. Here is my sketch:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define button1 9 // Button B1 is connected to Arduino pin 9
#define button2 8 // Button B2 is connected to Arduino pin 8
void setup(void) {
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
delay(1000);
// by default, the high voltage from the 3.3v line
display.begin(SSD1306_SWITCHCAPVCC, 0x3c); // initialize with the I2C address
// init done
// Clear the display buffer.
display.clearDisplay();
display.display();
display.setTextColor(WHITE, BLACK);
}
char Time[] = " : : ";
char Calendar[] = " / /20 ";
byte i, second, minute, hour, day, month, date, year;
void display_day(){
switch(day){
case 1: draw_text(0, 50, " SUNDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
case 2: draw_text(0, 50, " MONDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
case 3: draw_text(0, 50, " TUESDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
case 4: draw_text(0, 50, "WEDNESDAY", 1); break; //(Column,Row,Data to be displayed,Font size)
case 5: draw_text(0, 50, "THURSDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
case 6: draw_text(0, 50, " FRIDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
default: draw_text(0, 50, "SATURDAY ", 1); //(Column,Row,Data to be displayed,Font size)
}
}
void DS3231_display(){
// Convert BCD to decimal
second = (second >> 4) * 10 + (second & 0x0F);
minute = (minute >> 4) * 10 + (minute & 0x0F);
hour = (hour >> 4) * 10 + (hour & 0x0F);
month = (month >> 4) * 10 + (month & 0x0F);
date = (date >> 4) * 10 + (date & 0x0F);
year = (year >> 4) * 10 + (year & 0x0F);
// End conversion
Time[7] = second % 10 + 48;
Time[6] = second / 10 + 48;
Time[4] = minute % 10 + 48;
Time[3] = minute / 10 + 48;
Time[1] = hour % 10 + 48;
Time[0] = hour / 10 + 48;
Calendar[9] = year % 10 + 48;
Calendar[8] = year / 10 + 48;
Calendar[4] = date % 10 + 48;
Calendar[3] = date / 10 + 48;
Calendar[1] = month % 10 + 48;
Calendar[0] = month / 10 + 48;
//Print text
draw_text(60, 50, Calendar, 1); // Display the date (format: mm/dd/yyyy)
draw_text(15, 25, Time, 2); // Display the time
}
void blink_parameter(){
byte j = 0;
while(j < 10 && digitalRead(button1) && digitalRead(button2)){
j++;
delay(25);
}
}
byte edit(byte x_pos, byte y_pos, byte parameter){
char text[3];
sprintf(text,"%02u", parameter);
while(!digitalRead(button1)); // Wait until button B1 released
while(true){
while(!digitalRead(button2)){ // If button B2 is pressed
parameter++;
if(i == 0 && parameter > 12) // If month > 12 ==> month = 1
parameter = 1;
if(i == 1 && parameter > 31) // If date > 31 ==> date = 1
parameter = 1;
if(i == 2 && parameter > 99) // If year > 99 ==> year = 0
parameter = 0;
if(i == 3 && parameter > 23) // If hours > 23 ==> hours = 0
parameter = 0;
if(i == 4 && parameter > 59) // If minutes > 59 ==> minutes = 0
parameter = 0;
sprintf(text,"%02u", parameter);
draw_text(x_pos, y_pos, text, 1);
delay(200); // Wait 200ms
}
draw_text(x_pos, y_pos, " ", 1);
blink_parameter();
draw_text(x_pos, y_pos, text, 1);
blink_parameter();
if(!digitalRead(button1)){ // If button B1 is pressed
i++; // Increment 'i' for the next parameter
return parameter; // Return parameter value and exit
}
}
}
void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
display.setCursor(x_pos, y_pos);
display.setTextSize(text_size);
display.print(text);
display.display();
}
void scroll_text(){
draw_text(0, 0, "The Pumpkin Express", 1);
display.display();
display.startscrollright(0x00, 0x00);
delay(8500);
display.stopscroll();
delay(4000);
}
void loop() {
if(!digitalRead(button1)){ // If button B1 is pressed
i = 0;
while(!digitalRead(button1)); // Wait for button B1 release
while(true){
while(!digitalRead(button2)){ // While button B2 pressed
day++; // Increment day
if(day > 7) day = 1;
display_day(); // Call display_day function
delay(200); // Wait 200 ms
}
draw_text(0, 50, " ", 1);
blink_parameter(); // Call blink_parameter function
display_day(); // Call display_day function
blink_parameter(); // Call blink_parameter function
if(!digitalRead(button1)) // If button B1 is pressed
break;
}
//set position of text when editing on button press
month = edit(60, 50, month); // Edit month
date = edit(80, 50, date); // Edit date
year = edit(110,50, year); // Edit year
hour = edit(14, 25, hour); // Edit hours
minute = edit(50, 25, minute); // Edit minutes
// Convert decimal to BCD
minute = ((minute / 10) << 4) + (minute % 10);
hour = ((hour / 10) << 4) + (hour % 10);
date = ((date / 10) << 4) + (date % 10);
month = ((month / 10) << 4) + (month % 10);
year = ((year / 10) << 4) + (year % 10);
// End conversion
// Write data to DS3231 RTC
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.write(0); // Reset seconds and start oscillator
Wire.write(minute); // Write minute
Wire.write(hour); // Write hour
Wire.write(day); // Write day
Wire.write(month); // Write month
Wire.write(date); // Write date
Wire.write(year); // Write year
Wire.endTransmission(); // Stop transmission and release the I2C bus
delay(200); // Wait 200ms
}
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 7); // Request 7 bytes from DS3231 and release I2C bus at end of reading
second = Wire.read(); // Read seconds from register 0
minute = Wire.read(); // Read minutes from register 1
hour = Wire.read(); // Read hour from register 2
day = Wire.read(); // Read day from register 3
month = Wire.read(); // Read month from register 4
date = Wire.read(); // Read date from register 5
year = Wire.read(); // Read year from register 6
Wire.beginTransmission(0x68); // Start I2C protocol with DS3231 address
Wire.write(0x11); // Send register address
Wire.endTransmission(false); // I2C restart
Wire.requestFrom(0x68, 2); // Request 2 bytes from DS3231 and release I2C bus at end of reading
DS3231_display(); // Display time & calendar
display_day(); // Display date
scroll_text(); // Display scrolling text
// If i dont use the clear buffers(next 2 line codes), on the
//next loop cycle the seconds & minute text becomes jumbled
//display.clearDisplay();
//display.display();
delay(50); // Wait 50ms
}
void scrolling_text()is somehow being read as part of the whole sketch." Adelaydelays: it stops the world (except for interrupts)--nothing else will happen during adelay, it's delaying (except interrupts). If you don't want the sketch to delay in a way that stops the world then you'll need to delay differently. The Blink Without Delay may be what you're ultimately asking for. – Dave Newton Jun 16 '21 at 23:39