I have been working on this code for a while now, and i noticed the lcd screen stopped working(stopped displaying anything) after I implimented the IR controller.
It seems to me that dynamic memory is why my lcd stopped working. If i comment out everything relating to the IR controller my program runs fine. please help, thanks<3
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <RTClib.h>
#include <DHT11.h>
#include <DIYables_IRcontroller.h>
//DESIGNATION OF VALUES-----------------------------------
//KEYPAD--------------------------------------------------
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[COLS][ROWS] = {
{ '1', '4', '7', '*' },
{ '2', '5', '8', '0' },
{ '3', '6', '9', '#' },
{ 'A', 'B', 'C', 'D' }
};
byte rowPins[ROWS] = { 7, 6, 5, 4 }; //connect to the row pinouts of the keypad
byte colPins[COLS] = { 11, 10, 9, 8 }; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
//IR CONTROLLER-------------------------------------------
#define IR_RECEIVER_PIN 3 // connect the IR Receiver to pin 3
DIYables_IRcontroller_17 irController(IR_RECEIVER_PIN, 200); //debounce time is 200ms
//LCD-----------------------------------------------------
LiquidCrystal_I2C lcd(0x27, 20, 4);
int row = 0;
byte nok[] = {
B00000,
B00000,
B00000,
B01110,
B00000,
B11000,
B01000,
B10000,
};
//RTC-----------------------------------------------------
RTC_DS3231 rtc;
String monthArray[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
int lastMinute = 60;
int todaysMonth = NULL;
int lastSecond;
//TEMPERATURE --------------------------------------------
DHT11 dht11(2);
//Expenditure --------------------------------------------
//int eachDayThisMonthArray[31] = {};
//int moneySpentEachDay[31] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int moneySpentEachDay[31] = { 198, 209, 669, 407, 240, 77, 92, 385, 1064, 437, 520, 8, 514, 594, 778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//int moneySpentEachDay[31] = {};
int daysInEachMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int avgExpensesPerDay;
int totalMoneyPerMonth = 8000;
int moneyLeftModifyer;
int moneySpentSoFar;
int daysLeftThisMonth;
int moneyLeftThisMonth;
int moneyLeftPerDay;
//MENU----------------------------------------------------
int timeoutEndTime;
int currentScreen;
int currentCursor;
int lastCursorPlacement;
//DESIGNATION OF VALUES-----------------------------------
void setup() {
//DateTime now = rtc.now();
// put your setup code here, to run once:
Serial.begin(9600);
Serial.flush();
//initialize lcd screen
lcd.init();
// turn on the backlight
lcd.backlight();
lcd.createChar(0, nok);
//IR controller settings--------------------------------------------------
irController.begin();
//RTC settings------------------------------------------------------------
if (!rtc.begin()) {
Serial.println(F("Couldn't find RTC"));
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println(F("RTC lost power, let's set the time!"));
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
DateTime now = rtc.now();
todaysMonth = now.month();
//Expenditure standard settings-------------------------------------------
//totalMoneyPerMonth = 8000;
}
void loop() {
DateTime now = rtc.now();
char customKey = customKeypad.getKey();
if (customKey) {
//Serial.println(customKey);
if (customKey == 'A') {
currentScreen = 1;
currentCursor = 1;
mainMenu();
//newMenu();
}
}
if (moneyLeftPerDay == NULL) {
//Serial.println("moneyLeftPerDay from loop is running");
for (int i = 0; i < 30; i++) {
//Adding the expenditure for today into the moneySpentForEachDay array --------------------
int x = moneySpentEachDay[i];
moneySpentSoFar = moneySpentSoFar + x;
moneyLeftThisMonth = totalMoneyPerMonth - moneySpentSoFar;
}
calculateMoneyLeftPerDay(0,0,0);
}
if (lastMinute != now.minute()) {
//Serial.println("lastMinute check from loop has activated");
printTimeDate();
}
if (todaysMonth != now.month()) {
//Serial.print(todaysMonth);
//Serial.print("|");
//Serial.print(now.month());
for (int i = 0; i < 30; i++) {
moneySpentEachDay[i] = 0;
}
todaysMonth = now.month();
}
}
//MAINMENU SCRIPTS ---------------------------------------
void mainMenu() {
int timeoutEndTime = NULL;
Serial.println(currentScreen);
displayScreen(currentScreen);
displayCursor(currentCursor, 0);
//Set a Timeout time -----------------------------------
DateTime now = rtc.now();
int currentTime = now.second();
timeoutEndTime = now.second() + 25;
if (timeoutEndTime >= 60) { //KEEP SECONDS BASE 6
timeoutEndTime = timeoutEndTime - 60;
}
//END---------------------------------------------------
//CONTROLLER LOOP---------------------------------------
while (true) {
DateTime now = rtc.now();
char customKey = customKeypad.getKey();
//DETECT CURSOR MOVEMENT, UP OR DOWN----------------------
if(customKey){
if(customKey == '1'){ //CURSOR MOVE UP
if(currentCursor >= 2 && currentCursor <= 3){ // IF PAGE ONE
currentCursor--;
//Serial.print(" up - ");
//Serial.print(currentCursor);
delay(200);
}
else if(currentCursor >= 5 && currentCursor <= 6){ // IF PAGE TWO
currentCursor--;
//Serial.print(" up - ");
//Serial.print(currentCursor);
delay(200);
}
else if(currentCursor == 4){ // IF currentCursor == 4
currentCursor--;
displayScreen(1); //DISPLAY MENU-SCREEN-ONE-------------------------
//Serial.print(" up - ");
//Serial.print(currentCursor);
delay(200);
}
}
if(customKey == '7'){ //CURSOR MOVE DOWN
if(currentCursor >= 1 && currentCursor <= 2){ // IF PAGE ONE
currentCursor++;
//Serial.print("down - ");
//Serial.print(currentCursor);
delay(200);
}
else if(currentCursor >= 4 && currentCursor <= 5){ // IF PAGE TWO
currentCursor++;
//Serial.print("down - ");
//Serial.print(currentCursor);
delay(200);
}
else if(currentCursor == 3){ // IF currentCursor == 3
currentCursor++;
displayScreen(2); //DISPLAY MENU-SCREEN-TWO ------------------------
//Serial.print("down - ");
//Serial.print(currentCursor);
delay(200);
}
}
if (customKey == '4'){ //CURSOR SELECT OPTION
lcd.clear();
selectCursor(currentCursor);
delay(200);
return;
}
}
//MOVE VISUAL CURSOR ON LCD-------------------------------
if(lastCursorPlacement != currentCursor){
displayCursor(currentCursor, lastCursorPlacement);
}
//TIMEOUT SHOWSTOPPER------------------
if(timeoutEndTime == now.second()){
returnToMain();
return;
}
if(lastSecond != now.second()) { // SERIAL.PRINT timeoutEndTime INFO
Serial.print(F("Menu timeout :"));
Serial.print(timeoutEndTime);
Serial.print(F(" | "));
Serial.print(now.second());
Serial.println(F(": currentSecond"));
lastSecond = now.second();
}
}
//END---------------------------------------------------
}
void displayScreen(int page){
switch(page) {
case 1:
lcd.clear();
lcd.setCursor(8,0);
lcd.print("MENU");
lcd.setCursor(1,1);
lcd.print("Calculator");
lcd.setCursor(1,2);
lcd.print("Todays Expense");
lcd.setCursor(1,3);
lcd.print("Edit Prev. Expense");
currentScreen = 1;
break;
case 2:
lcd.clear();
lcd.setCursor(8,0);
lcd.print("MENU");
lcd.setCursor(1,1);
lcd.print("Reset expenses");
lcd.setCursor(1,2);
lcd.print("Review Date");
lcd.setCursor(1,3);
lcd.print("Settings");
currentScreen = 2;
break;
default:
Serial.print(F("ERROR displayScreen: COULD NOT ASSERTAIN SCREEN REFERANCE NUMBER! === "));
Serial.print(page);
break;
}
}
void displayCursor(int now, int then){
if(now > 3){
now = now - 3;
}
if(then > 3){
then = then - 3;
}
lcd.setCursor(0, then);
lcd.print(" ");
lcd.setCursor(0, now);
lcd.print(">");
lastCursorPlacement = currentCursor;
return;
}
void selectCursor(int select){
delay(200);
switch (select) {
case 1:
calculator();
//Serial.println("Choose Calculator");
break;
case 2:
expenditure();
//Serial.println("Choose Expenditure");
break;
case 3:
editExpenses();
break;
case 4:
resetArray();
break;
case 5:
reviewDate();
break;
case 6:
settingsMenu();
break;
default:
Serial.print(F("ERROR selectCursor: COULD NOT ASSERTAIN SCREEN REFERANCE NUMBER! === "));
Serial.println(select);
break;
}
}
//MENU OPTIONS -------------------------------------------
void calculator() {
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Calculator");
lcd.setCursor(0, 3);
lcd.print("Return * / # Confirm");
DateTime now = rtc.now();
int numberOne = 0;
int numberTwo = 0;
int setCursorA = 0;
int answerOne = 0;
int answerTwo = 0;
while (numberTwo == 0) {
row = 0;
lcd.setCursor(0, 2);
while (numberOne == 0) {
numberOne = GetNumber(row,2);
if (numberOne == 9999) {
returnToMain();
return;
} else {
lcd.setCursor(0, 2);
lcd.print(numberOne);
lcd.print("+");
setCursorA = row + 1;
}
}
numberTwo = GetNumber(setCursorA,2);
lcd.setCursor(setCursorA, 2);
lcd.print(numberTwo);
if (numberTwo == 'end') {
returnToMain();
}
}
lcd.print("=");
delay(50);
int SUM = numberOne + numberTwo;
lcd.print(SUM);
delay(1000);
while (answerOne == 0) {
lcd.setCursor(0, 1);
lcd.print(" Finished? ");
lcd.setCursor(0, 3);
lcd.print(" No * / # Yes ");
answerOne = confirmation();
}
switch (answerOne) {
case '*': //NO---------------
lcd.clear();
calculator(); //RIGHT HERE the idea is that you'd be able to input a new number and add it to the previous sum--------------
break;
case '#': //YES.............
lcd.setCursor(2, 1);
lcd.print("Add to expenses?");
while (answerTwo == 0) {
answerTwo = confirmation();
switch (answerTwo) {
case '*': //NOO-----------------
returnToMain();
return;
case '#':
//MAKE A SCRIPT TO GO HERE THAT ADDS THIS "SUM" VALUE TO THE DAILY EXPENSES--------------------
// INT is called "SUM"---------
calculateMoneyLeftPerDay(now.day(), SUM, 0);
returnToMain();
return;
}
}
case 'D':
returnToMain();
break;
}
}
void expenditure() {
//char numbers = customKeypad.getKey();
DateTime now = rtc.now();
row = 2;
int numberOne = NULL;
int answerOne = NULL;
int checkForError = NULL;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Expenditure");
lcd.setCursor(0, 1);
lcd.print("Add todays expenses");
lcd.setCursor(0, 2);
lcd.print("->");
while (checkForError == NULL) {
while (answerOne == NULL) {
while (numberOne == NULL) {
lcd.setCursor(0, 3);
lcd.print("Return * / # Confirm");
numberOne = GetNumber(row,2);
if (numberOne == 9999) {
returnToMain();
return;
}
lcd.setCursor(2, 2);
lcd.print(numberOne);
}
lcd.setCursor(0, 1);
lcd.print(" Is this correct? ");
lcd.setCursor(0, 3);
lcd.print(" No * / # Yes ");
answerOne = confirmation();
returnToMain();
return;
}
while (answerOne == NULL) {
answerOne = confirmation();
switch (answerOne) {
case '*': //NO---------------
lcd.clear();
editExpenses();
break;
case '#': //YES.............
calculateMoneyLeftPerDay(now.day(), numberOne,0);
returnToMain();
break;
}
}
if (checkForError == 1) {
//Add numberOne to the daily expenses for today----------------------
calculateMoneyLeftPerDay(now.day(), numberOne,0);
returnToMain();
return;
} else {
returnToMain();
return;
}
}
}
void editExpenses() {
int expense = NULL;
int date = NULL;
int numberOne;
int setCursorA;
int answerOne = NULL;
char numbers = customKeypad.getKey();
DateTime now = rtc.now();
row = 2;
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Edit Expenses!");
lcd.setCursor(0, 1);
lcd.print("Choose a date");
lcd.setCursor(0, 2);
lcd.print("->");
lcd.setCursor(0, 3);
lcd.print("Return * / # Confirm");
while (expense == NULL) {
while (date == NULL) {
date = GetNumber(row,2);
if (date == 9999) {
returnToMain();
return;
}
lcd.setCursor(0, 1);
lcd.print("Input expense");
lcd.setCursor(0, 2);
lcd.print("-> ");
}
row = 2;
expense = GetNumber(row,2);
}
delay(200);
lcd.setCursor(0, 2);
lcd.print("Add ");
lcd.print(expense);
lcd.write(byte(0));
lcd.print(" to ");
lcd.print(date);
lcd.print(".");
lcd.print(monthArray[now.month() - 1]);
lcd.print("?");
lcd.setCursor(0, 3);
lcd.print(" No * / # Yes ");
while (answerOne == NULL) {
answerOne = confirmation();
switch (answerOne) {
case '*': //NO---------------
lcd.clear();
editExpenses();
break;
case '#': //YES.............
calculateMoneyLeftPerDay(date, 0, expense);
returnToMain();
break;
}
}
}
void resetArray() {
for (int i; i < 31; i++) {
moneySpentEachDay[i] = 0;
}
calculateMoneyLeftPerDay(0,0,0);
returnToMain();
}
void reviewDate() {
DateTime now = rtc.now();
int exit = NULL;
int date = NULL;
row = 5;
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Review Date");
lcd.setCursor(0,3);
lcd.print("Return * / # Confirm");
lcd.setCursor(0,1);
lcd.print("Date: ");
while(exit == NULL){
while(date == NULL){
date = GetNumber(row,1) - 1;
if (date == 9999) {
returnToMain();
return;
}
lcd.setCursor(0,1);
lcd.print("On the ");
lcd.print(date+1);
lcd.print(".");
lcd.print(monthArray[now.month()-1]);
lcd.setCursor(0,2);
lcd.print("You spent:");
lcd.print(moneySpentEachDay[date]);
lcd.write(byte(0));
lcd.setCursor(0,3);
lcd.print("Return * / # Repeat ");
}
exit = customKeypad.getKey();
if (exit == '*') {
returnToMain();
return;
} else if (exit == '#'){
reviewDate();
}
}
}
void settingsMenu() { //THIS SHIET IS NOT DONE AT ALL LOL---------
DateTime now = rtc.now();
int exit = NULL;
int newValue = NULL;
row = 5;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Settings");
}
//REGULARY USED FUNCTIONS --------------------------------
void returnToMain() {
// Serial.println("returnToMain RUNNING");
timeoutEndTime = 0;
lcd.clear();
printTimeDate();
loop();
return;
}
int GetNumber(int Row, int Coloum) {
//Serial.println("GetNumber is RUNNING");
int num = 0;
int buttonPressed = NULL;
char key = customKeypad.getKey();
Key17 command = irController.getKey();
while (key != '#' && command != Key17::KEY_SHARP) {
if(key){
switch (key) {
case NO_KEY:
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
lcd.setCursor(Row, Coloum);
lcd.print(key);
num = num * 10 + (key - '0');
Row++;
delay(200);
break;
case '*':
num = 9999;
delay(200);
break;
}
}
if(command != Key17::UNKNOWN){
switch (command) {
case Key17::KEY_0:
buttonPressed = 0;
break;
case Key17::KEY_1:
buttonPressed = 1;
break;
case Key17::KEY_2:
buttonPressed = 2;
break;
case Key17::KEY_3:
buttonPressed = 3;
break;
case Key17::KEY_4:
buttonPressed = 4;
break;
case Key17::KEY_5:
buttonPressed = 5;
break;
case Key17::KEY_6:
buttonPressed = 6;
break;
case Key17::KEY_7:
buttonPressed = 7;
break;
case Key17::KEY_8:
buttonPressed = 8;
break;
case Key17::KEY_9:
buttonPressed = 9;
break;
case Key17::KEY_STAR:
num = 9999;
break;
}
delay(200);
if(buttonPressed != NULL){ //Checks if a Switch-case: has happened;
buttonPressed = NULL;
lcd.setCursor(Row, Coloum);
lcd.print(buttonPressed);
num = num * 10 + (buttonPressed - '0');
Row++;
}
}
if (num == 9999) {
key = '#';
} else {
key = customKeypad.getKey();
}
}
row = Row;
return num;
}
int confirmation() {
int num = 0;
char key = customKeypad.getKey();
DateTime now = rtc.now();
int timeoutEndTime;
if (now.second() <= 30) {
timeoutEndTime = now.second() + 10;
}
if (now.second() > 30) {
timeoutEndTime = now.second() + 10;
if (timeoutEndTime >= 60) {
timeoutEndTime = (now.second() - 60) + 10;
}
}
while (timeoutEndTime != now.second()) {
switch (key) {
case '*':
num = key;
break;
case '#':
num = key;
break;
}
return key;
}
return;
}
void calculateMoneyLeftPerDay(int date, int expense, int addition) {
DateTime now = rtc.now();
daysLeftThisMonth = daysInEachMonth[now.month() - 1] - now.day();
avgExpensesPerDay = totalMoneyPerMonth / 31;
moneySpentSoFar = 0;
int todaysDate = date - 1;
//Calculating the moneyLeftThisMonth-----------------------------------
if (expense != 0) { //Adding the expenditure for today into the moneySpentForEachDay array
moneySpentEachDay[todaysDate] = expense;
}
//Adding expens to pre-existing value-------------------
if (addition != 0){
int prev = moneySpentEachDay[todaysDate];
moneySpentEachDay[todaysDate] = prev + addition;
}
//Counting up the money spent so far this month---------------------------------
for (int i = 0; i < 31; i++) {
moneySpentSoFar = (moneySpentSoFar + moneySpentEachDay[i]);
}
moneyLeftThisMonth = totalMoneyPerMonth - moneySpentSoFar;
moneyLeftModifyer = moneyLeftThisMonth / daysLeftThisMonth;
moneyLeftPerDay = avgExpensesPerDay + (moneyLeftModifyer - avgExpensesPerDay);
spiritTrain(date);
return;
}
void spiritTrain(int date) { //BULK SERIAL.PRINT OUTPUTS
DateTime now = rtc.now();
//moneySpentSoFar = 0;
int todaysDate = date - 1;
for (int i = 0; i < 31; i++) {
Serial.print(F("Date:"));
if (i < 9) {
Serial.print(F(" "));
Serial.print(i + 1);
} else {
Serial.print(F(" "));
Serial.print(i + 1);
}
Serial.print(F(" | "));
Serial.print(F("Money spent:"));
if (moneySpentEachDay[i] < 10) {
Serial.print(F(" "));
Serial.print(moneySpentEachDay[i]);
} else if (moneySpentEachDay[i] < 100) {
Serial.print(F(" "));
Serial.print(moneySpentEachDay[i]);
} else if (moneySpentEachDay[i] < 1000) {
Serial.print(F(" "));
Serial.print(moneySpentEachDay[i]);
} else {
Serial.print(F(" "));
Serial.print(moneySpentEachDay[i]);
}
Serial.print(F(" | "));
Serial.print(F("moneySpentSoFar : "));
Serial.println(moneySpentSoFar);
}
Serial.println(F("---------STATS---------"));
Serial.print(F("daysLeftThisMonth = "));
Serial.println(daysLeftThisMonth);
Serial.print(F("avgExpensesPerDay = "));
Serial.println(avgExpensesPerDay);
Serial.print(F("moneyLeftModifyer = "));
Serial.println(moneyLeftModifyer);
Serial.print(F("totalMoneyPerMonth = "));
Serial.println(totalMoneyPerMonth);
Serial.print(F("moneySpentSoFar = "));
Serial.println(moneySpentSoFar);
Serial.print(F("moneyLeftThisMonth = "));
Serial.println(moneyLeftThisMonth);
Serial.print(F("moneyLeftPerDay = "));
Serial.println(moneyLeftPerDay);
Serial.println(F("---------------------"));
return;
}
void printTimeDate() {
DateTime now = rtc.now();
int temperature = dht11.readTemperature();
lcd.clear();
lcd.setCursor(0, 0);
if (now.day() < 10) {
lcd.print("0");
lcd.print(now.day());
} else {
lcd.print(now.day());
}
lcd.print(".");
lcd.print(monthArray[now.month() - 1]);
lcd.print(".");
lcd.print(now.year());
lcd.setCursor(15, 0);
if (now.hour() < 10) {
lcd.print("0");
lcd.print(now.hour());
} else {
lcd.print(now.hour());
}
lcd.print(":");
if (now.minute() < 10) {
lcd.print("0");
lcd.print(now.minute());
} else {
lcd.print(now.minute());
}
lcd.setCursor(14, 1);
lcd.print(temperature, 1);
lcd.print(char(223));
lcd.print("C");
lcd.setCursor(0, 3);
lcd.print("Money p/Day = ");
lcd.print(moneyLeftPerDay);
lcd.write(byte(0));
lastMinute = now.minute();
}