/*
Project: Daily Affirmation
Description: Stores strings in program memory and
displays one at random on button press.
See link below, this many chars won't
fit in an Uno's sram memory.
Creation date: 12/15/23
Author: AnonEngineering
License: Beerware
https://www.e-tinkers.com/2020/05/do-you-know-arduino-progmem-demystified/
*/
#include <LiquidCrystal_I2C.h>
#include "affirmations.h"
const unsigned long shutoffDelay = 10000; // 30 seconds shutoff delay
const int NUM_STRINGS = 51;
const int STRING_SIZE = 60; // max chars for 3 lines
const int BTN_PIN = 2;
const int I2C_ADDR = 0x27;
const int NUM_COLS = 20;
const int NUM_ROWS = 4;
PGM_P const affirmations[NUM_STRINGS] PROGMEM =
{
afStr0, afStr1, afStr2, afStr3, afStr4, afStr5, afStr6, afStr7, afStr8, afStr9,
afStr10, afStr11, afStr12, afStr13, afStr14, afStr15, afStr16, afStr17, afStr18, afStr19,
afStr20, afStr21, afStr22, afStr23, afStr24, afStr25, afStr26, afStr27, afStr28, afStr29,
afStr30, afStr31, afStr32, afStr33, afStr34, afStr35, afStr36, afStr37, afStr38, afStr39,
afStr40, afStr41, afStr42, afStr43, afStr44, afStr45, afStr46, afStr47, afStr48, afStr49,
afStr50
};
bool isRunning = false;
unsigned long shutOffTimer = 0;
LiquidCrystal_I2C lcd(I2C_ADDR, NUM_COLS, NUM_ROWS);
bool checkButton() {
static int oldBtnState = HIGH;
bool isButtonPressed = false;
int btnState = digitalRead(BTN_PIN);
if (btnState != oldBtnState) {
oldBtnState = btnState;
if (btnState == LOW) {
isButtonPressed = true;
// if not running show splash
if (!isRunning) {
showSplash();
delay(1000);
}
Serial.println("Get new affirmation");
isRunning = true;
// Reset the shutoff timer when the button is pressed
shutOffTimer = millis();
} else {
Serial.println("Button released\n");
isRunning = true;
}
delay(20); // for debounce
}
return isButtonPressed;
}
void displayRandomAffirmation() {
char buffer[60];
lcd.clear();
int lineNumber = 1;
int index = random(NUM_STRINGS);
Serial.print("Random index: ");
Serial.println(index);
// Get random string from affirmations
strcpy_P(buffer, (PGM_P)pgm_read_word(&affirmations[index]));
//Serial.print("Buffer length: ");
//const int buf_len = strlen_P(affirmations[index]);
//Serial.println(buf_len);
Serial.println(buffer);
char * pch;
pch = strtok (buffer, ";-");
while (pch != NULL) {
lcd.setCursor(0, lineNumber);
lcd.print(pch);
Serial.println (pch);
lineNumber++;
if (lineNumber > 3) lineNumber = 1;
pch = strtok (NULL, ";-");
}
}
void showSplash() {
lcd.clear();
lcd.backlight();
lcd.setCursor(2, 1);
lcd.print("Here is your");
lcd.setCursor(6, 2);
lcd.print("affirmation!");
isRunning = true;
}
void shutOffDisplay() {
if (isRunning && (millis() - shutOffTimer >= shutoffDelay)) {
lcd.clear();
lcd.noBacklight();
isRunning = false;
Serial.println("Display and backlight shutoff");
}
}
void setup() {
Serial.begin(115200);
lcd.begin(20, 4);
pinMode(BTN_PIN, INPUT_PULLUP);
randomSeed(analogRead(0));
showSplash();
}
void loop() {
if (checkButton()) {
displayRandomAffirmation();
}
shutOffDisplay();
}