#include <IRremote.h>
#include <LiquidCrystal_I2C.h>
#include "max7219func.h"
#include <SPI.h>
#include <TimeLib.h>
#define PIN_RECEIVER 12 // Signal Pin of IR receiver
#define MAX_MESG 20
IRrecv receiver(PIN_RECEIVER);
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned char szMesg[MAX_MESG + 1] = "";
void getTime(unsigned char *psz)
{
sprintf((char*)psz, "%s%01d%s%02d%s\x9a%02d\x9a", hours < 10 ? " " : "", hours, seconds % 2 ? (numFont == Font5x8 ? "\x9c" : " ") : (numFont == Font5x8 ? "\x9b" : ":"), minutes, numFont == Font4x8 ? " " : " ", seconds);
}
void checkIR() {
if (receiver.decode()) {
translateIR();
receiver.resume(); // Receive the next value
}
}
void setup()
{
Wire.begin();
mx.begin();
mx.setFont(numeric7Seg);
mx.setShiftDataInCallback(&dataInCB);
lcd.init();
lcd.print("<press a button>");
Serial.begin(115200);
receiver.enableIRIn(); // Start the receiver
while (!Serial) // Wait for the serial connection to be establised.
delay(50);
Serial.println();
Serial.print(F("IRrecvDemo is now running and waiting for IR message on Pin "));
Serial.println(PIN_RECEIVER);
}
decode_results results;
unsigned char helyseg[] = "Várpalota:";
unsigned char temp[] = "-21.6\x90\x43";
unsigned char hum[] = "Pára:";
unsigned char humDigs[] = "25%";
char anims[] = {'P','L','U'};
enum states { Idle, InitCycle, TimeStart, ShowTime, ShowTempLoc, ShowTempDigits, ShowHumidityText, ShowHumidityDigits };
enum animTypes { Print, LR, UD } animType;
void loop() {
static enum states state = InitCycle;
static enum states prevState, nextState;
static uint32_t showTimeFor = 2000, showTempFor = 2000, idleTime = 15;
static uint32_t lastDSUpdate = 0; // Memory (ms)
static uint8_t lastSec = 5;
bool animEnd;
static byte randAnim[5];
byte tempPos;
//----------------------------------------------------------------
switch (state) {
case Idle:
yield(); //In case of ESP
if (elapsed(idleTime)) {
state = nextState;
idleTime = 15;
}
else {
if (receiver.decode()) {
translateIR();
receiver.resume(); // Receive the next value
}
}
break;
case InitCycle:
for(int i = 0; i < 5; i++){ randAnim[i] = random(3); Serial.print(anims[randAnim[i]]); }
Serial.println();
// randAnim[0] = 2;
// randAnim[1] = 2;
// randAnim[2] = 1;
// randAnim[3] = 0;
// randAnim[4] = 1;
//for(int i = 0; i < 5; i++)Serial.print(anims[randAnim[i]]);
DS1307getTime();
setTime(hours, minutes, seconds, mday, monthL, yearL);
getTime(szMesg);
case TimeStart:
switch (randAnim[0]) {
case Print: animEnd = printText(szMesg, numFont != Font5x8 ?1:4); break;
case LR: animEnd = TSLR(szMesg, numFont != Font5x8 ? 30 : 45, 0, LEFT); break;
case UD: animEnd = numFont != Font5x8 ? TSUD(szMesg, UP, 1, 32, 2) : TSUD(szMesg, UP, 3, 29, 3);
}
if (!animEnd) {
state = Idle; idleTime = 150;
nextState = TimeStart;
}
else state = ShowTime;
break;
case ShowTime:
hours = hour(), minutes = minute(), seconds = second();
if (lastSec != seconds) {
lastSec = seconds;
getTime(szMesg);
if (numFont == Font5x8) {
printText(szMesg, 3);
seconds <= 30 ? mx.setPoint(7, seconds == 0 ? 30 : 31 - seconds, true) : mx.setPoint(7, seconds == 31 ? 1 : seconds - 30, true);
if (seconds > 55) mx.setColumn(30, 4 << seconds % 5);
if (seconds > 25 && seconds < 31) mx.setColumn(1, 4 << (seconds < 30 ? seconds % 5 : 5));
} else {
printText(szMesg, 1);
}
if (elapsed(showTimeFor, 1)) {
state = ShowTempLoc;
}
} else {
state = Idle; idleTime = 50;
nextState = ShowTime;
}
break;
case ShowTempLoc:
switch (randAnim[1]) {
case Print: animEnd = printText(helyseg, 0, 32, false, true); break;
case LR: animEnd = TSLR(helyseg, -16, 7); break;
case UD: animEnd = TSUD(helyseg, DOWN, 0, 32, 3, true);
}
if (!animEnd) {
state = Idle;
nextState = ShowTempLoc;
}
else {
nextState = ShowTempDigits;
state = Idle;
idleTime = 1000;
}
break;
case ShowTempDigits:
tempPos = numFont == Font5x8?temp[0]==0x2d?0:3:temp[0]==0x2d?2:5;
switch (randAnim[2]) {
case Print: animEnd = printText(temp, tempPos); break;
case LR: animEnd = TSLR(temp, numFont == Font4x8?2:5, 10); break;
case UD: animEnd = TSUD(temp, DOWN, tempPos, 32, 3);
}
if (!animEnd) {
state = Idle;
nextState = ShowTempDigits;
}
else {
nextState = ShowHumidityText;
state = Idle;
idleTime = showTempFor;
}
break;
case ShowHumidityText:
switch (randAnim[3]) {
case Print: animEnd = printText(hum, 4); break;
case LR: animEnd = TSLR(hum, 5, 15); break;
case UD: animEnd = TSUD(hum, true, 4, 32, 2);
}
if (!animEnd) {
state = Idle;
nextState = ShowHumidityText;
} else {
nextState = ShowHumidityDigits;
state = Idle;
idleTime = 800;
}
break;
case ShowHumidityDigits:
switch (randAnim[4]) {
case Print: animEnd = printText(humDigs, 10); break;
case LR: animEnd = TSLR(humDigs, 9, 5); break;
case UD: animEnd = TSUD(humDigs, false, 10, 32, 2);
}
if (!animEnd) {
state = Idle;
nextState = ShowHumidityDigits;
} else {
nextState = InitCycle;
state = Idle;
idleTime = 2000;
}
break;
}
}
void lcdPrint(const char* text)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("button pressed:");
lcd.setCursor(0, 1);
lcd.print(text);
lcd.print(" code: ");
lcd.print(receiver.decodedIRData.command);
}
void translateIR()
{
// Takes command based on IR code received
switch (receiver.decodedIRData.command) {
case 162:
char time[2];
//lcdPrint("POWER");
DS1307getTime();
lcdPrint(itoa(seconds, time, 10));
break;
case 226:
lcdPrint("MENU");
break;
case 34:
lcdPrint("TEST");
break;
case 2:
lcdPrint("PLUS");
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");
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:
lcd.clear();
lcd.print(receiver.decodedIRData.command);
lcd.print(" other button");
}
}