// MENU CODE =(20*4 I2C LCD) + (4/4 KEYPAD) + (4N-PUSH BTNS) + (IR REMOTE) + (CLOCK) + (TEMP/HMD) + (VOICE)
#include "CMBMenu.hpp" // include CMBMenu
#include <Wire.h> // include I2C MODULE
#include <LiquidCrystal_I2C.h> // include LCD
#include <IRremote.h> // include IR
#include <Keypad.h> // include Keypad
// Set up pins for pushButtons
const char STATUS_LED_RED_OP = 2;
const char STATUS_LED_BLUE_OP = 3;
const char STATUS_LED_GREEN_OP = 4;
// Set up pins for pushButtons
const char Right_Button = 5;
const char Left_Button = 6;
const char Enter_Button = 7;
const char Exit_Button = 8;
# define PIN_RECEIVER 9
IRrecv receiver(PIN_RECEIVER);
bool pressed = false;
char keypressed; // Character to hold key input
char IRKey; // Character to hold key input
// Constants for row and column sizes
const byte ROWS = 4;
const byte COLS = 4;
// Array to represent keys on keypad
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Connections to Arduino
byte rowPins[ROWS] = {A7, A6, A5, A4};
byte colPins[COLS] = {A3, A2, A1, A0};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); // Create keypad object
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
/************************************************************************************************************/
// MENU LAYERS & DISPLAY TEXT
/************************************************************************************************************/
// define text to display
const char g_MenuA_pc[] PROGMEM = {" 1.SOUND SENSOR"}; //1
const char g_MenuA_a1_pc[] PROGMEM = {" 1.1 CURRENT STATUS"}; //1.1
const char g_MenuA_b1_pc[] PROGMEM = {"1.2 PREVIOUS STATUS"}; //1.2
const char g_MenuA_c1_pc[] PROGMEM = {"1.3 CHECK TEMPERTURE"};//1.3
const char g_MenuA_d1_pc[] PROGMEM = {" 1.4 CHECK HUMIDITY"};//1.4
const char g_MenuB_pc[] PROGMEM = {" 2.LIGHT SENSOR"};//2
const char g_MenuB_a1_pc[] PROGMEM = {" 2.1 B_a1"};//2.1
const char g_MenuB_b1_pc[] PROGMEM = {" 2.2 GENERAL MODE"};//2.2
const char g_MenuB_c1_pc[] PROGMEM = {" DEACTIVATE ADMIN"};//2.3
const char g_MenuC_pc[] PROGMEM = {" 3.REMOTE CONTROL"};//3
const char g_MenuC_a1_pc[] PROGMEM = {"3.1 INTIALIZE PANEL"};//3.1
const char g_MenuC_b1_pc[] PROGMEM = {"3.2 PREVIOUS VALUES"};//3.2
const char g_MenuD_pc[] PROGMEM = {" 4.TIMER SENSOR"};//3
const char g_MenuE_pc[] PROGMEM = {"5.WATER LEVEL SENSOR"};//3
// define function IDs
enum MenuFID {
MenuDummy,
MenuA,
MenuA_a1,
MenuA_b1,
MenuA_c1,
MenuA_d1,
MenuB,
MenuB_a1,
MenuB_b1,
MenuB_c1,
MenuC,
MenuC_a1,
MenuC_b1,
MenuD,
MenuE,
};
// define key types
enum KeyType {
KeyNone, // no key is pressed
KeyLeft,
KeyRight,
KeyEnter,
KeyExit
};
// ** menu **
// create global CMBMenu instance
// (here for maximum 100 menu entries)
CMBMenu<100> g_Menu;
/************************************************************************************************************/
// CREATE CUSTOM CHARECTERS FOR MENU
/************************************************************************************************************/
byte customChar1[8] = {
0b00000,
0b01000,
0b01100,
0b01110,
0b01111,
0b01110,
0b01100,
0b01000
};
byte customChar2[8] = {
0b00000,
0b00010,
0b00110,
0b01110,
0b11110,
0b01110,
0b00110,
0b00010
};
byte customChar3[8] = {
0b00000,
0b00100,
0b01110,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000
};
byte customChar4[8] = {
0b00111,
0b00001,
0b00001,
0b00101,
0b01101,
0b11111,
0b01100,
0b00100
};
/************************************************************************************************************/
// CREATE CUSTOM CHARECTERS FOR DS3231
/************************************************************************************************************/
byte customChar5[8] = {
B00100,
B00100,
B00100,
B00100,
B00100,
B00100,
B00100,
B00100
};
byte customChar6[8] = {
0b00100,
0b00100,
0b00100,
0b11111,
0b00100,
0b00100,
0b00100,
0b00100
};
const unsigned long eventInterval = 2000;
unsigned long previousTime = 0;
/************************************************************************************************************/
// MAIN setup & PINMODES
/************************************************************************************************************/
void setup()
{
// Set up pinmode
pinMode(Left_Button, INPUT_PULLUP);
pinMode(Right_Button, INPUT_PULLUP);
pinMode(Enter_Button, INPUT_PULLUP);
pinMode(Exit_Button, INPUT_PULLUP);
pinMode(STATUS_LED_RED_OP, OUTPUT);
pinMode(STATUS_LED_GREEN_OP, OUTPUT);
pinMode(STATUS_LED_BLUE_OP, OUTPUT);
receiver.enableIRIn(); // Start the receiver
Serial.begin(9600);
lcd.begin(20,4);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("WELCOME");
lcd.setCursor(3,2);
lcd.print("INSPIRE INDIA");
lcd.setCursor(5,3);
lcd.print("INSTITUTE");
delay(1500);
lcd.clear();
lcd.setCursor(2,1);
lcd.print("INDUSTRIAL PSLC");
lcd.setCursor(1,2);
lcd.print("ECG - PSR KV 910R");
delay(2500);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("WELCOME");
lcd.setCursor(4,2);
lcd.print("SYSTEM READY");
delay(1000);
lcd.createChar(1, customChar1);
lcd.createChar(2, customChar2);
lcd.createChar(3, customChar3);
lcd.createChar(4, customChar4);
lcd.createChar(5, customChar5);
lcd.createChar(6, customChar6);
Serial.println("===========================");
Serial.println("INDUSTRIAL PSLC - PSR KV910 R");
Serial.println("===========================");
Serial.println("PSLC-AUTH SEGMENT CODE");
Serial.println("===========================");
Serial.println("Programmer: TEEGLA NARENDRA");
Serial.println("===========================");
Serial.println("Cheif PROGRAMMER @ INSPRE INDIA INSTITUTE");
Serial.println("===========================");
Serial.println("function Designer: TEEGALA YASHODA");
Serial.println("===========================");
Serial.println("CORRESPONDENT @ INSPRE INDIA INSTITUTE");
Serial.println("===========================");
// ** MENU LAYERS**
// add nodes to menu (layer, string, function ID)
g_Menu.addNode(0, g_MenuA_pc , MenuA);
g_Menu.addNode(1, g_MenuA_a1_pc , MenuA_a1);
g_Menu.addNode(1, g_MenuA_b1_pc , MenuA_b1);
g_Menu.addNode(1, g_MenuA_c1_pc, MenuA_c1);
g_Menu.addNode(1, g_MenuA_d1_pc, MenuA_d1);
g_Menu.addNode(0, g_MenuB_pc , MenuB);
g_Menu.addNode(1, g_MenuB_a1_pc, MenuB_a1);
g_Menu.addNode(1, g_MenuB_b1_pc, MenuB_b1);
g_Menu.addNode(1, g_MenuB_c1_pc, MenuB_c1);
g_Menu.addNode(0, g_MenuC_pc, MenuC);
g_Menu.addNode(1, g_MenuC_a1_pc, MenuC_a1);
g_Menu.addNode(1, g_MenuC_b1_pc, MenuC_b1);
g_Menu.addNode(0, g_MenuD_pc, MenuD);
g_Menu.addNode(0, g_MenuE_pc, MenuE);
// *****MENU*****
// build menu and print menu
// (see terminal for output)
const char* info;
g_Menu.buildMenu(info);
g_Menu.printMenu();
// ** menu **
// print current menu entry
printMenuEntry(info);
blinkLedY();
delay(100);
blinkLedY();
}
/************************************************************************************************************/
// MAIN LOOP
/************************************************************************************************************/
void loop()
{
/************************************************************************************************************/
// CURRENTSTATE - BOOL DECLARATION
/************************************************************************************************************/
/*************************************************************************************************************/
// MENU CASE'S & NAVIGATION KEY
/************************************************************************************************************/
// function ID
int fid = 0;
// info text from menu
const char* info;
// go to deeper or upper layer?
bool layerChanged=false;
// determine pressed key
KeyType key = getKey();
// ** menu **
// call menu methods regarding pressed key
switch(key) {
case KeyExit:
g_Menu.exit();
break;
case KeyEnter:
g_Menu.enter(layerChanged);
break;
case KeyRight:
g_Menu.right();
break;
case KeyLeft:
g_Menu.left();
break;
default:
break;
}
// ** menu **
// pint/update menu when key was pressed
// and get current function ID "fid"
if (KeyNone != key) {
fid = g_Menu.getInfo(info);
printMenuEntry(info);
}
// ** menu **
// do action regarding function ID "fid"
if ((0 != fid) && (KeyEnter == key) && (!layerChanged)) {
switch (fid) {
case MenuA_a1:
A_a1();
break;
case MenuA_b1:
A_b1();
break;
case MenuA_c1:
A_c1();
break;
case MenuA_d1:
A_d1();
break;
case MenuB_a1:
B_a1();
break;
case MenuB_b1:
B_b1();
break;
case MenuB_c1:
B_c1();
break;
case MenuC_a1:
C_a1();
break;
case MenuC_b1:
C_b1();
break;
default:
break;
}
}
}
/*************************************************************************************************************/
// LOOP ENDS
/*************************************************************************************************************/
/*************************************************************************************************************/
// STATUS LED BLINK FUNCTION
/*************************************************************************************************************/
void blinkLedIR(){
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
digitalWrite(STATUS_LED_BLUE_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
digitalWrite(STATUS_LED_BLUE_OP, LOW);
}
void blinkLedKey(){
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
digitalWrite(STATUS_LED_RED_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
digitalWrite(STATUS_LED_RED_OP, LOW);
}
/*************************************************************************************************************/
// STATUS LED Y-BLINK FUNCTION
/*************************************************************************************************************/
void blinkLedY(){
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
digitalWrite(STATUS_LED_RED_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
digitalWrite(STATUS_LED_RED_OP, LOW);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
digitalWrite(STATUS_LED_RED_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
digitalWrite(STATUS_LED_RED_OP, LOW);
}
/*************************************************************************************************************/
// STATUS LED G-BLINK FUNCTION
/*************************************************************************************************************/
void blinkLedG(){
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_GREEN_OP, LOW);
}
/*************************************************************************************************************/
// STATUS LED R-BLINK FUNCTION
/*************************************************************************************************************/
void blinkLedR(){
digitalWrite(STATUS_LED_RED_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_RED_OP, LOW);
delay(100);
digitalWrite(STATUS_LED_RED_OP, HIGH);
delay(100);
digitalWrite(STATUS_LED_RED_OP, LOW);
}
/*************************************************************************************************************/
// MENU PRINT & LCD MAIN PRINT
/*************************************************************************************************************/
void printMenuEntry(const char* f_Info)
{
String info_s;
MBHelper::stringFromPgm(f_Info, info_s);
// when using LCD: add/replace here code to
// display info on LCD
Serial.flush();
Serial.println("----------------");
Serial.println(info_s);
Serial.println("----------------");
// print on LCD
lcd.clear();
lcd.setCursor(6,0);
lcd.print("WELCOME");
lcd.setCursor(0,2);
lcd.print(info_s);
lcd.setCursor(9,3);
lcd.write((byte)2); // print the custom char at (3, 3)
lcd.setCursor(12,3);
lcd.write((byte)1); // print the custom char at (8, 3)
lcd.setCursor(15,3);
lcd.write((byte)3); // print the custom char at (13, 3)
lcd.setCursor(18,3);
lcd.write((byte)4); // print the custom char at (18, 3)
// you can print here additional infos into second line of LCD
// g_Lcd.setCursor(0, 1);
// g_Lcd.print("my text");
}
/*************************************************************************************************************/
// MENU NAVIGATION KEY & IR NAVIGATION
/*************************************************************************************************************/
KeyType getKey()
{
KeyType key = KeyNone;
// here for demonstration: get "pressed" key from terminal
// replace code when using push buttons 11D9609F
bool Left_currentState = digitalRead(Left_Button);
bool Right_currentState = digitalRead(Right_Button);
bool Enter_currentState = digitalRead(Enter_Button);
bool Exit_currentState = digitalRead(Exit_Button);
if (receiver.decode()) {
int res = receiver.decodedIRData.command; //IR value to res
switch (res) {
case 168:
key = KeyEnter;
blinkLedIR();
Serial.println("OK");
break;
case 224:
key = KeyLeft; // left
blinkLedIR();
Serial.println("LEFT");
break;
case 144:
key = KeyRight; // Right
blinkLedIR();
Serial.println("RIGHT");
break;
case 0x11D9708F:
key = KeyLeft; // left
blinkLedIR();
Serial.println("UP");
break;
case 0x11D950AF:
key = KeyRight; // Right
blinkLedIR();
Serial.println("DOWN");
break;
case 194:
key = KeyExit;
blinkLedIR();
Serial.println("Exit");
break;
default:
break;
}
receiver.resume(); // Receive the next value
}
if(Left_currentState == pressed){
key = KeyLeft; // left
blinkLedIR();
Serial.println("<left>");
delay(100);
while(digitalRead(Left_Button) == pressed){
}
}
else if(Right_currentState == pressed){
key = KeyRight; // Right
blinkLedIR();
Serial.println("<Right>");
delay(100);
while(digitalRead(Right_Button) == pressed){
}
}
else if(Enter_currentState == pressed){
key = KeyEnter;
blinkLedIR();
Serial.println("<Enter>");
delay(100);
while(digitalRead(Enter_Button) == pressed){
}
}
else if(Exit_currentState == pressed){
key = KeyExit;
blinkLedIR();
Serial.println("<Exit>");
delay(100);
while(digitalRead(Exit_Button) == pressed){
}
}
return key;
}
/*************************************************************************************************************/
// 1.1 PANEL CURRENT STATUS FUNCTION
/*************************************************************************************************************/
void A_a1()
{
}
/*************************************************************************************************************/
// 1.2 PANEL PREVIOUS STATUS FUNCTION
/*************************************************************************************************************/
void A_b1()
{
}
/*************************************************************************************************************/
// 1.3 CHECK TEMPERTURE function
/*************************************************************************************************************/
void A_c1()
{
}
/*************************************************************************************************************/
// 1.4 CHECK HUMIDITY function
/*************************************************************************************************************/
void A_d1()
{
}
/*************************************************************************************************************/
// 2.1 B_a1 FUNCTION
/*************************************************************************************************************/
void B_a1()
{
}
/*************************************************************************************************************/
// 2.2 GENERAL MODE function
/*************************************************************************************************************/
void B_b1()
{
}
/*************************************************************************************************************/
// 2.3 DEACTIVATE ADMIN FUNCTION
/*************************************************************************************************************/
void B_c1()
{
}
/*************************************************************************************************************/
// 3.1 INTIALIZE PANEL FUNCTION
/*************************************************************************************************************/
void C_a1()
{
}
/*************************************************************************************************************/
// 3.2 LOAD PREVIOUS VALUES FUNCTION
/*************************************************************************************************************/
void C_b1()
{
}
// ========================================================================
// naming convention
// prefix:
// g : global variayle
// f : function/method variayle
// m : private member of class
// : without prefix: public member of class
//
//
// ========================================================================