1

I am trying to write a part of a program that prints time and allows the user to move a cursor across it. I have the following code, but there are a few issues with it.

#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <Time.h>
#include <TimeLib.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {
  lcd.begin(16,2);
  setTime(12,30,15,0,0,0);
}
int col = 0;

void loop() {
  uint8_t buttons = lcd.readButtons(); //create readable buttons
  char time_out[16];
  lcd.setCursor(0,0);
  sprintf(time_out, "%02u:%02u:%02u",hour(),minute(),second());
  lcd.print(time_out);
  lcd.setCursor(col,0);
  lcd.blink();
  delay(100);
  if (buttons) {
    lcd.clear();
    if (buttons & BUTTON_RIGHT) { 
      col += 1;
    }   
    if (buttons & BUTTON_LEFT) {
      col -= 1; 
    } 
  } //buttons 
}

If you upload this to your board, you can tell that the blinking is highly irregular, not at all aesthetically pleasing.

You'll also notice that sometimes, when pressing left/right, the input isn't registered.

I suspect this has to do something with the delay() function used, which pauses the entire program.

I looked into the following method, but this does not work when needing to print something in a loop (as the time library requires).

Any idea how I could make this work better (regular blinking times and no miss of user input)?

Thanks a lot!

dda
  • 1,595
  • 1
  • 12
  • 17
Jon Goe
  • 89
  • 3
  • 8

1 Answers1

1

I don't have the hardware to test but, it should be more or less like this; (I have also normalized the code into several functions for better readability.)

#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <Time.h>
#include <TimeLib.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

unsigned long timerBlink; //Required for periodic blinking
int intervalBlink = 100;

void setup() {
    lcd.begin(16, 2);
    setTime(12, 30, 15, 0, 0, 0);
    timerBlink = 0;
}
int col = 0;

void loop() {
    readButtons();
    printDate();
    if (millis() - timerBlink > intervalBlink) {
        blink();
    }
}

void readButtons() {
    uint8_t buttons = lcd.readButtons(); //create readable buttons
    if (buttons) {
        lcd.clear();
        if (buttons & BUTTON_RIGHT) {
            col += 1;
        }
        if (buttons & BUTTON_LEFT) {
            col -= 1;
        }
    } //buttons 
}

void blink() {
    lcd.setCursor(col, 0);
    lcd.blink();
    timerBlink = millis();//Start timer for intervalBlink
}

void printDate() {
    char time_out[16];
    lcd.setCursor(0, 0);
    sprintf(time_out, "%02u:%02u:%02u", hour(), minute(), second());
    lcd.print(time_out);
}

Instead of blocking delay function, using timeout with timestamp is a better practice.

Sener
  • 394
  • 2
  • 12