// https://programmersqtcpp.blogspot.com/2022/01/arduinolcd-testo-scorrevoleadvanced.html
#include <IRremote.h>
#include <LiquidCrystal.h>
#include "RTClib.h"
RTC_DS1307 rtc;
DateTime dateTime;
#define PIN_RECEIVER 2 // Signal Pin of IR receiver
IRrecv receiver(PIN_RECEIVER);
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
uint32_t oldTime = 0;
char *p_daysOfTheWeek[7] = {"Lun", "Mar", "Mer"
, "Gio", "Ven", "Sab", "Dom"
};
char *p_month[12] = {"Gen", "Feb", "Mar", "Apr", "Mag"
, "Giu", "Lug", "Ago", "Set", "Ott"
, "Nov", "Dic"
};
String strTime; // buffer
String strDate; // buffer
String strScrollText; // buffer
String strDayOfTheMonth; // buffer
String hourBuff;
String minuteBuff;
String secondBuff;
uint8_t speedScroll = 50; // un carattere ogni 50ms
// ROW_LEN può avere un valore minoere di 16
// ad esempio se provate con 10 scoprirete che
// si impegnano solo 10 colonne del display
#define ROW_LEN 16
// scorre da destra verso sinistra
void scrollText(char *s, char *sd) {
uint8_t sIdx = 0;
static uint8_t S_sdIdx = ROW_LEN;
static uint8_t S_sIdx = 0;
if (S_sdIdx > 0) {
S_sdIdx--;
} else {
sIdx = S_sIdx;
}
uint8_t sdIdx = S_sdIdx;
int len_s = strlen(s); // 23
memset(sd, ' ', ROW_LEN);
sd[ROW_LEN] = '\0';
while (sdIdx < ROW_LEN) {
sd[sdIdx] = s[sIdx];
sdIdx++;
sIdx++;
sIdx = sIdx % len_s;
}
if (S_sdIdx == 0) {
S_sIdx++;
S_sIdx = S_sIdx % len_s;
}
} // end void scrollText(char *s, char *sd)
void setup()
{
Serial.begin(115200);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
lcd.begin(16, 2);
receiver.enableIRIn(); // Start the receiver
oldTime = millis();
strDayOfTheMonth.reserve(2);
strTime.reserve(10);
strDate.reserve(20);
strScrollText.reserve(64);
hourBuff.reserve(2);
minuteBuff.reserve(2);
secondBuff.reserve(2);
} // end void setup()
char *timeToStr() {
uint8_t h = dateTime.hour();
uint8_t m = dateTime.minute();
uint8_t s = dateTime.second();
if (h < 10) {
hourBuff = "0" + String(h);
} else {
hourBuff = String(h);
}
if (m < 10) {
minuteBuff = "0" + String(m);
} else {
minuteBuff = String(m);
}
if (s < 10) {
secondBuff = "0" + String(s);
} else {
secondBuff = String(s);
}
strTime = " " + hourBuff + ":" + minuteBuff + ":" + secondBuff;
return strTime.c_str();
} // end char *timeToStr()
char *dateToStr() {
uint8_t dayOfTheMonth = dateTime.day();
uint8_t dayOfTheWeek = dateTime.dayOfTheWeek();
uint8_t month = dateTime.month();
uint16_t year = dateTime.year();
// visualizza 08 anziché 8, al fine di mantenere la stringa di
// lunghezza costante. Tuttavia non è necessario, poiché
// sia la lunghezza cbe il contenuto possono essere
// modificati a run-time senza effetti negativi (sembra).
if (dayOfTheMonth < 10) {
strDayOfTheMonth = "0" + String(dayOfTheMonth);
} else {
strDayOfTheMonth = String(dayOfTheMonth);
}
strDate = " " + String( p_daysOfTheWeek[ dayOfTheWeek - 1 ] ) + " " + strDayOfTheMonth
+ " " + String( p_month[ month - 1 ] ) + " " + String(year);
return strDate.c_str();
} // end char *dateToStr()
char scrollBuffer[ ROW_LEN + 1 ] = {0}; // buffer per il testo scorrevole
void loop()
{
dateTime = rtc.now();
// La rapidità di scorrimento può essere controllata
// tramite i tasti + e - del telecomando.
if (millis() - oldTime >= speedScroll) {
dateToStr();
timeToStr();
oldTime = millis();
// combina data e ora in unica variabile
strScrollText = " MauroTec Software" + strDate + strTime + " Wokwi Simulator";
scrollText(strScrollText.c_str(), scrollBuffer);
lcd.setCursor(0, 1);
lcd.print(scrollBuffer);
}
// Checks received an IR signal
if (receiver.decode()) {
translateIR();
receiver.resume(); // Receive the next value
}
} // end void loop()
void clsRow0() {
lcd.setCursor(0, 0);
lcd.print(" "); // 16 spazi
}
void lcdPrint(char* text)
{
clsRow0();
lcd.setCursor(0, 0);
lcd.print(text);
lcd.print(" (");
lcd.print(receiver.decodedIRData.command);
lcd.print(")");
}
void translateIR()
{
// Takes command based on IR code received
switch (receiver.decodedIRData.command) {
case 162:
lcdPrint("POWER");
break;
case 226:
lcdPrint("MENU");
break;
case 34:
lcdPrint("TEST");
break;
case 2:
lcdPrint("PLUS");
if (speedScroll > 10)
speedScroll -= 2;
lcd.setCursor(14, 0);
lcd.print(speedScroll);
//Serial.println(speedScroll);
break;
case 194:
lcdPrint("BACK");
break;
case 224:
lcdPrint("PREV.");
break;
case 168:
lcdPrint("PLAY");
break;
case 144:
lcdPrint("NEXT");
break;
case 104:
lcdPrint("num: 0");
break;
case 152:
lcdPrint("MINUS");
if (speedScroll < 100)
speedScroll += 2;
lcd.setCursor(14, 0);
lcd.print(speedScroll);
//Serial.println(speedScroll);
break;
case 176:
lcdPrint("key: C");
break;
case 48:
lcdPrint("num: 1");
break;
case 24:
lcdPrint("num: 2");
break;
case 122:
lcdPrint("num: 3");
break;
case 16:
lcdPrint("num: 4");
break;
case 56:
lcdPrint("num: 5");
break;
case 90:
lcdPrint("num: 6");
break;
case 66:
lcdPrint("num: 7");
break;
case 74:
lcdPrint("num: 8");
break;
case 82:
lcdPrint("num: 9");
break;
default:
clsRow0();
lcd.setCursor(0, 0);
lcd.print(receiver.decodedIRData.command);
lcd.print(" other button");
}
}