#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);
utf8_t szMesg[MAX_MESG + 1] = "";
void getTime(utf8_t *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 utfStrConv(utf8_t *str)
{
uint8_t stlLen = strlen(str);
bool utfFound;
while(*str != '\0'){
switch (*str) {
case 0xC3: *str = *(str + 1) + 64; utfFound = true; break;
case 0xC5:
utfFound = true;
switch (*(str + 1)) {
case 0x90: case 0x91: *str = *(str + 1) + 5; break; // Ő ő
case 0xB0: case 0xB1: *str = *(str + 1) - 25; // Ű ű
}
default: utfFound = false;
}
str++;
if(utfFound)
for(utf8_t *tmp = str; *tmp != '\0'; tmp++)
*tmp = *(tmp + 1);
}
}
utf8_t helyseg[] = "Várpalota:";
utf8_t temp[] = "-21.6\x90\x43";
utf8_t hum[] = "Pára:";
utf8_t humDigs[] = "25%";
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);
utfStrConv(hum);
}
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;
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);Serial.println((char *)szMesg);
case TimeStart:
switch (randAnim[0]) {
case Print: animEnd = printText(szMesg, numFont != Font5x8 ?1:4); break;
case LR: animEnd = TSLR(szMesg,31); break;
case UD: animEnd = numFont != Font5x8 ? TSUD(szMesg, UP, 1, 32, 2) : TSUD(szMesg, UP, 3, 29, 3);
}
if (!animEnd) {
state = Idle; idleTime = 15;
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);
delay(100);
}
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");
}
}