#include <Arduino.h>
const int rs = 13, en = 12, d0 = 11, d1 = 10, d2 = 9, d3 = 8, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Config Start
int Joystick_Pressed_Max = 50; // How long can you press the button until it doesnt Count
int Joystick_Pressed_Min = 20; // How long you have to press the button until it Counts
// Config End
float Button_Currend_Pressed_Time = 0;
float Button_Pressed_Time = 0;
short Joystick_X = 0;
short Joystick_Y = 0;
volatile unsigned int menu = 0;
unsigned int Selection = 0;
bool SelectionLock = false;
bool SelectionSLock = false;
bool Selectitemlist = false;
int Scroll = 0;
int Message = 0;
int JoystickTimer_X = 0;
int JoystickTimer_Y = 0;
bool JoystickTimer_Ins = false;
String Input = "";
int SelectLockN = 0;
uint8_t Back[8] = {
0b00100,
0b01100,
0b11111,
0b01101,
0b00101,
0b10001,
0b11111,
0b00000
};
uint8_t AlarmSymbol[8] = {
0b00100,
0b01110,
0b01110,
0b01110,
0b01110,
0b11111,
0b00100,
0b00000
};
//P1:
//P2:
bool Alarmen = false;
volatile bool Door1En = true;
volatile bool Door2En = true;
float AlarmStartT = 0;
int AlarmStopT = 0;
int AlarmStatus1 = 0;
bool AlarmAlarm = false;
bool AlarmLR = false;
int AlarmDelaySec = 10;
//TEMP
bool TSW1 = false;
bool EV1 = false;
bool EV2 = false;
bool EV3 = false;
bool EV4 = false;
bool EV5 = false;
int newval = 0b00000;
int T = 0;
//EEPROM only saves the data in the simulator for the next start if you press the restart button on arduino
void SaveDataEEPROM() {
EEPROM.update(0x00, 0b01010);
newval = 0b0;
newval |= EV1 ? 0b00001 : 0b00000;
newval |= EV2 ? 0b00010 : 0b00000;
newval |= EV3 ? 0b00100 : 0b00000;
newval |= EV4 ? 0b01000 : 0b00000;
newval |= EV5 ? 0b10000 : 0b00000;
Serial.print(newval);
EEPROM.update(0x01, newval);
EEPROM.update(0x02, AlarmDelaySec);
EEPROM.update(0x03, (( Door1En ? 0x01 : 0x00 )|( Door2En ? 0x02 : 0x00 )));
Serial.println("Save EEPROM");
};
void LoadDataEEPROM() {
if (EEPROM.read(0x00) != 0b01010) {
Serial.println("Create new EEPROM");
return;
};
newval = EEPROM.read(0x01);
AlarmDelaySec = EEPROM.read(0x02);
Serial.print(newval);
EV1 = newval & 0b00001;
EV2 = newval & 0b00010;
EV3 = newval & 0b00100;
EV4 = newval & 0b01000;
EV5 = newval & 0b10000;
Serial.println("Load EEPROM");
Door1En = (EEPROM.read(0x03) & 0x01) == 1;
Door2En = (EEPROM.read(0x03) & 0x02) == 2;
};
void ClearDisplay () {
lcd.clear();
lcd.setCursor(0, 0);
}
void UpdateScrollM();
void SetMenu (int MENU, int SELECTION);
class Button {
private:
int Pos[3] = {0, 0, 0};
int NextButtons[4] = {0, 0, 0, 0};
int ID = 0;
bool Select = false;
int Textsize = 4;
char Text[20];
bool En = true;
public:
Button(const int XPos, const int YPos, const int len, const String Texti, const int NextButton[4], const int IDi = 0, bool fEn = true) {
Pos[0] = XPos;
Pos[1] = YPos;
Pos[2] = len;
for (int i = 0; i < 4; i++) {
NextButtons[i] = (int)NextButton[i];
};
Textsize = Texti.length();
for (int i = -1; i <= Textsize; i++) {
Text[i] = Texti[i];
};
Text[Textsize + 1] = '\0';
ID = IDi;
En = fEn;
};
int GetPos(int WP) {
return Pos[WP];
};
void IsSelected() {
Select = ID == Selection;
};
void SetText(String NEWTEXT) {
for (int i = 0; i < NEWTEXT.length() ; i++) {
Text[i] = NEWTEXT[i];
};
Text[NEWTEXT.length()] = "\0";
Textsize = NEWTEXT.length();
};
String GetText () {
return Text;
};
void Enable() {
En = true;
};
void Disable() {
En = false;
};
void ShowButton() {
if ((Pos[1] < Scroll) or (Pos[1] > Scroll + 1)) {
return;
}
if (!En) {return;};
IsSelected();
lcd.setCursor(Pos[0], Pos[1] - Scroll);
lcd.write(Select ? (Selectitemlist ? "[" : ">") : " ");
for (int i = Pos[0]; i < min((Pos[0] + Pos[2] - 1), (Pos[0] + Textsize)); i++) {
lcd.setCursor(i + 1, Pos[1] - Scroll);
lcd.print(Text[i - Pos[0]]);
};
lcd.setCursor(Pos[0] + Pos[2], Pos[1] - Scroll);
lcd.write(Select ? (Selectitemlist ? "]" : "<") : " ");
};
void Move(int Direction) {
if (SelectionLock == false) {
int NextB = NextButtons[Direction];
if (NextB != -1) {
Selection = NextB;
UpdateScrollM();
};
};
};
};
void Update_Joystick () {
//Joystick_X = 1023 - analogRead(A0);
Joystick_X = analogRead(A0);
Joystick_Y = analogRead(A1);
if (digitalRead(3) == false) {
Button_Currend_Pressed_Time++;
} else {
if (Button_Currend_Pressed_Time > 0) {
Button_Pressed_Time = Button_Currend_Pressed_Time;
Button_Currend_Pressed_Time = 0;
}
}
}
class Menupar {
private:
int ButtonCount = 0;
public:
Button* ButtonList[16];
void AddButton(int X, int Y, int Len, String Text, int Nextbuttons[4]) {
Button* TempB = new Button(X, Y, Len, Text, Nextbuttons, ButtonCount);
ButtonList[ButtonCount] = TempB;
ButtonCount++;
};
void ShowButtons() {
for (int i = 0; i < ButtonCount; i++) {
ButtonList[i]->ShowButton();
};
};
Menupar() {
//...
};
};
class MenuSys {
private:
int MenuCount = 0;
public:
Menupar* MenuList[16];
void addMenu() {
Menupar* TempM = new Menupar();
MenuList[MenuCount] = TempM;
MenuCount++;
};
void Movenext(int Direction) {
MenuList[menu]->ButtonList[Selection]->Move(Direction);
};
};
MenuSys MenuSysteam;
int AlarmTriggerCheck12 () {
if (!Alarmen) {return 0;};
if (AlarmStartT > 0) {return 0;};
if (digitalRead(23) == 0) {if (Door1En) {return 23;} else {return 0;};};//(Door1En ? 18 : 0 )};
if (digitalRead(25) == 0) {if (Door2En) {return 25;} else {return 0;};};//(Door2En ? 19 : 0 )};
return 0;
};
void AlarmTriggerCounter() {
AlarmStartT -= 0.01;
}
void ActivateAlarmTimer () {
AlarmLR = true;
AlarmStartT = AlarmDelaySec;
SetMenu(6,0);
MenuSysteam.MenuList[6]->ButtonList[1]->Disable();
SelectionLock = true;
};
void LoopAlarm () {
if (Alarmen) {
if (!AlarmLR) {
AlarmStatus1 = AlarmTriggerCheck12();
if (AlarmStatus1 != 0) { Serial.print("Alarm on pin ");Serial.println(AlarmStatus1);if (!AlarmAlarm) {ActivateAlarmTimer();} };
} else {
if (AlarmStartT <= 0) {
Serial.println("ALARM TRIGGER");
lcd.setCursor(0,1);
lcd.print("ALARM TRIGGERED ");
AlarmAlarm = true;
} else {
AlarmTriggerCounter();
lcd.setCursor(0,1);
lcd.print("ENABLE IN: ");lcd.print(AlarmStartT);lcd.print("s");
}
}
}
};
void UpdateScrollM() {
int US_X = MenuSysteam.MenuList[menu]->ButtonList[Selection]->GetPos(1);
if (US_X > Scroll + 1) {
Scroll = US_X - 1;
ClearDisplay();
} else if (US_X < Scroll) {
Scroll = US_X;
ClearDisplay();
};
};
void SetMenu (int MENU, int SELECTION) {
menu = MENU;
Selection = SELECTION;
UpdateScrollM();
ClearDisplay();
};
void VMenu() {
if (true) {
MenuSysteam.MenuList[menu]->ShowButtons();
} else {
switch (menu) {
case 1:
{
MenuSysteam.MenuList[1]->ShowButtons();
break;
}
case 2:
{
MenuSysteam.MenuList[2]->ShowButtons();
break;
}
};
};
};
void SMenu0 () {
switch (Selection) {
case 0:
{
Serial.println("Select an Programm");
break;
};
case 1:
{
SetMenu(1, 0);
break;
};
case 2:
{
SetMenu(3, 0);
break;
};
case 3:
{
SetMenu(6, 0);
digitalWrite(14, HIGH);
break;
};
}
};
void SMenu1 () {
switch (Selection) {
case 3:
{
MenuSysteam.MenuList[1]->ButtonList[3]->SetText((String) "Something:" + (TSW1 ? "On" : "Off"));
TSW1 = not(TSW1);
break;
};
case 4:
{
SetMenu(2, 0);
break;
}
default:
Serial.println("This Button doesnt do anything yet");
};
};
void SMenu2 () {
switch (Selection) {
case 0:
{
SetMenu(1, 4);
break;
}
case 1:
{
EV1 = !EV1;
MenuSysteam.MenuList[2]->ButtonList[1]->SetText((String) "Value 1:" + (EV1 ? "On" : "Off"));
break;
}
case 2:
{
EV2 = !EV2;
MenuSysteam.MenuList[2]->ButtonList[2]->SetText((String) "Value 2:" + (EV2 ? "On" : "Off"));
break;
}
case 3:
{
EV3 = !EV3;
MenuSysteam.MenuList[2]->ButtonList[3]->SetText((String) "Value 3:" + (EV3 ? "On" : "Off"));
break;
}
case 4:
{
EV4 = !EV4;
MenuSysteam.MenuList[2]->ButtonList[4]->SetText((String) "Value 4:" + (EV4 ? "On" : "Off"));
break;
}
case 5:
{
EV5 = !EV5;
MenuSysteam.MenuList[2]->ButtonList[5]->SetText((String) "Value 5:" + (EV5 ? "On" : "Off"));
break;
}
case 6:
{
SaveDataEEPROM();
break;
}
default:
Serial.println("Not Defined");
};
};
void SMenu3 () {
switch (Selection) {
case 0:
{
SetMenu(4, 0);
break;
};
case 1:
{
SetMenu(5, 0);
break;
};
};
};
void SMenu4 () {
switch (Selection) {
case 0:
{
SetMenu(3, 0);
break;
};
};
};
void SMenu5 () {
switch (Selection) {
case 0:
{
SetMenu(3, 1);
break;
};
};
};
void SMenu6 () {
switch (Selection) {
case 0:
{
Alarmen = !Alarmen;
MenuSysteam.MenuList[6]->ButtonList[0]->SetText((String) "Status:" + (Alarmen ? "ON " : "OFF"));
if (Alarmen) {
digitalWrite(14, LOW);
digitalWrite(15, HIGH);
} else {
digitalWrite(15, LOW);
digitalWrite(14, HIGH);
SelectionLock = false;
AlarmStartT = 0;
AlarmLR = false;
AlarmAlarm = false;
MenuSysteam.MenuList[6]->ButtonList[1]->Enable();
};
break;
};
case 1:
{
SetMenu(7, 0);
break;
};
};
};
void SMenu7 () {
switch (Selection) {
case 0:
{
SetMenu(6, 1);
break;
};
case 1:
{
if (Selectitemlist) {
SelectionLock = false;
Selectitemlist = false;
SelectLockN = 0;
} else {
SelectionLock = true;
Selectitemlist = true;
SelectLockN = 1;
};
break;
};
case 2:
{
SetMenu(8, 0);
break;
};
case 3:
{
SetMenu(9, 0);
break;
};
case 4:
{
SaveDataEEPROM();
break;
}
};
};
void SMenu8 () {
switch (Selection) {
case 0:
{
SetMenu(7, 2);
break;
};
case 1:
{
Door1En = !Door1En;
MenuSysteam.MenuList[8]->ButtonList[1]->SetText((String) "Status:" + (Door1En ? "ON " : "OFF"));
};
};
};
void SMenu9 () {
switch (Selection) {
case 0:
{
SetMenu(7, 3);
break;
};
case 1:
{
Door2En = !Door2En;
MenuSysteam.MenuList[9]->ButtonList[1]->SetText((String) "Status:" + (Door2En ? "ON " : "OFF"));
};
};
};
/*
void SMenu () {
switch (Selection) {
case 0:
{
break;
};
};
};
*/
void SMenutr () {
switch (menu) {
case 0:
{
SMenu0();
break;
}
case 1:
{
SMenu1();
break;
}
case 2:
{
SMenu2();
break;
}
case 3:
{
SMenu3();
break;
}
case 4:
{
SMenu4();
break;
}
case 5:
{
SMenu5();
break;
}
case 6:
{
SMenu6();
break;
}
case 7:
{
SMenu7();
break;
}
case 8:
{
SMenu8();
break;
}
case 9:
{
SMenu9();
break;
}
case 10:
{
break;
}
};
Button_Pressed_Time = 0;
};
void SelectLockFun (int Dir) {
if (SelectLockN == 0) {return;};
switch (SelectLockN) {
case 1:
{
if (Dir == 0) {++AlarmDelaySec;};
if (Dir == 1) {--AlarmDelaySec;};
MenuSysteam.MenuList[7]->ButtonList[1]->SetText((String) "Delay:" + AlarmDelaySec + " ");
break;
}
}
};
void InitText() { //Define all Menus Buttons Position Text Nextbutton
MenuSysteam.addMenu();
MenuSysteam.MenuList[0]->AddButton(0, 0, 10, "Programm:", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[0]->AddButton(0, 1, 5, "Test", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[0]->AddButton(0, 2, 4, "LED", (const int[4]) { 1, 3, -1, -1 });
MenuSysteam.MenuList[0]->AddButton(0, 3, 7, "ALARM\x2", (const int[4]) { 2, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[1]->AddButton(0, 0, 10, "Manuel Modus", (const int[4]) { -1, 1, -1, 2 });
MenuSysteam.MenuList[1]->AddButton(0, 1, 11, "Function 1", (const int[4]) { 0, 3, -1, 2 });
MenuSysteam.MenuList[1]->AddButton(12, 1, 3, "B2", (const int[4]) { 0, 3, 1, -1 });
MenuSysteam.MenuList[1]->AddButton(0, 2, 15, "ToggelButton", (const int[4]) { 1, 4, -1, -1 });
MenuSysteam.MenuList[1]->AddButton(0, 3, 13, "Randome Menu", (const int[4]) { 3, 5, -1, -1 });
MenuSysteam.MenuList[1]->AddButton(0, 4, 11, "Function 5", (const int[4]) { 4, 6, -1, -1 });
MenuSysteam.MenuList[1]->AddButton(0, 5, 11, "Function 6", (const int[4]) { 5, 7, -1, -1 });
MenuSysteam.MenuList[1]->AddButton(0, 6, 11, "Function 7", (const int[4]) { 6, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[2]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 1, 12, "Loading", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 2, 12, "Loading", (const int[4]) { 1, 3, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 3, 12, "Loading", (const int[4]) { 2, 4, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 4, 12, "Loading", (const int[4]) { 3, 5, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 5, 12, "Loading", (const int[4]) { 4, 6, -1, -1 });
MenuSysteam.MenuList[2]->AddButton(0, 6, 11, "SaveTes", (const int[4]) { 5, -1, -1, -1 });
MenuSysteam.MenuList[2]->ButtonList[1]->SetText((String) "Value 1:" + (EV1 ? "On" : "Off"));
MenuSysteam.MenuList[2]->ButtonList[2]->SetText((String) "Value 2:" + (EV2 ? "On" : "Off"));
MenuSysteam.MenuList[2]->ButtonList[3]->SetText((String) "Value 3:" + (EV3 ? "On" : "Off"));
MenuSysteam.MenuList[2]->ButtonList[4]->SetText((String) "Value 4:" + (EV4 ? "On" : "Off"));
MenuSysteam.MenuList[2]->ButtonList[5]->SetText((String) "Value 5:" + (EV5 ? "On" : "Off"));
MenuSysteam.addMenu();
MenuSysteam.MenuList[3]->AddButton(0, 0, 6, "LED1R", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[3]->AddButton(0, 1, 6, "LED2G", (const int[4]) { 0, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[4]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[4]->AddButton(0, 1, 11, "Frequency:", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[4]->AddButton(0, 2, 9, "LEN:", (const int[4]) { 1, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[5]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[5]->AddButton(0, 1, 11, "Frequency:", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[5]->AddButton(0, 2, 9, "LEN:", (const int[4]) { 1, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[6]->AddButton(0, 0, 11, "Loading", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[6]->AddButton(0, 1, 9, "Settings", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[6]->AddButton(0, 2, 8, "LOG WIP", (const int[4]) { 1, -1, -1, -1 });
MenuSysteam.MenuList[6]->ButtonList[0]->SetText((String) "Status:" + (Alarmen ? "ON " : "OFF"));
MenuSysteam.addMenu();
MenuSysteam.MenuList[7]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[7]->AddButton(0, 1, 10, "Delay:", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[7]->ButtonList[1]->SetText((String) "Delay:" + AlarmDelaySec + + " ");
MenuSysteam.MenuList[7]->AddButton(0, 2, 6, "Door1", (const int[4]) { 1, 3, -1, -1 });
MenuSysteam.MenuList[7]->AddButton(0, 3, 6, "Door2", (const int[4]) { 2, 4, -1, -1 });
MenuSysteam.MenuList[7]->AddButton(0, 4, 13, "Save Setting", (const int[4]) { 3, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[8]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[8]->AddButton(0, 1, 11, "Loading", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[8]->ButtonList[1]->SetText((String) "Status:" + (Door1En ? "ON " : "OFF"));
MenuSysteam.MenuList[8]->AddButton(0, 2, 9, "Trigger:", (const int[4]) { 1, -1, -1, -1 });
MenuSysteam.addMenu();
MenuSysteam.MenuList[9]->AddButton(0, 0, 6, "Back\x3", (const int[4]) { -1, 1, -1, -1 });
MenuSysteam.MenuList[9]->AddButton(0, 1, 11, "Loading", (const int[4]) { 0, 2, -1, -1 });
MenuSysteam.MenuList[9]->ButtonList[1]->SetText((String) "Status:" + (Door2En ? "ON " : "OFF"));
MenuSysteam.MenuList[9]->AddButton(0, 2, 9, "Trigger:", (const int[4]) { 1, -1, -1, -1 });
};
void ConsoleInfo () {
if (Serial.available() > 0) {
Input = Serial.readString();
if (Input.indexOf("=") != -1) {
if (Input.substring(0,Input.indexOf("="))=="menu") {
menu = (Input.substring(Input.indexOf("=")+1)).toInt();
};
if (Input.substring(0,Input.indexOf("="))=="Select") {
Selection = (Input.substring(Input.indexOf("=")+1)).toInt();
};
};
};
};
void loop() {
//ConsoleInfo();
LoopAlarm();
PCICR |= 0b100;
PCMSK2 |= 0b100;
VMenu();
Update_Joystick();
ConsoleInfo();
if (Button_Pressed_Time > 1) {
SMenutr();
};
if (Joystick_X < 300) {
if (JoystickTimer_Ins and (JoystickTimer_X > 50)) {
MenuSysteam.Movenext(1);
SelectLockFun(1);
JoystickTimer_Ins = false;
};
JoystickTimer_X += (Joystick_X - 512) / (-20);
} else if (Joystick_X > 800) {
if (JoystickTimer_Ins and (JoystickTimer_X < -50)) {
MenuSysteam.Movenext(0);
SelectLockFun(0);
JoystickTimer_Ins = false;
};
JoystickTimer_X += (Joystick_X - 512) / (-20);
} else if (Joystick_Y > 800) {
if (JoystickTimer_Ins and (JoystickTimer_Y < -50)) {
MenuSysteam.Movenext(2);
SelectLockFun(2);
JoystickTimer_Ins = false;
};
JoystickTimer_Y += (Joystick_Y - 512) / (-20);
} else if (Joystick_Y < 300) {
if (JoystickTimer_Ins and (JoystickTimer_Y > 50)) {
MenuSysteam.Movenext(3);
SelectLockFun(3);
JoystickTimer_Ins = false;
};
JoystickTimer_Y += (Joystick_Y - 512) / (-20);
} else {
JoystickTimer_X /= 2;
JoystickTimer_Y /= 2;
JoystickTimer_Ins = true;
};
if (JoystickTimer_X >= 300) {
MenuSysteam.Movenext(1);
JoystickTimer_X = 0;
} else if (JoystickTimer_X <= -300) {
MenuSysteam.Movenext(0);
SelectLockFun(0);
JoystickTimer_X = 0;
} else {
Joystick_X *= 0.9;
};
if (JoystickTimer_Y >= 300) {
MenuSysteam.Movenext(3);
JoystickTimer_Y = 0;
} else if (JoystickTimer_Y <= -300) {
MenuSysteam.Movenext(2);
SelectLockFun(2);
JoystickTimer_Y = 0;
} else {
Joystick_Y *= 0.9;
};
}
ISR (PCINT2_vect) {
menu = 0;
};
void setup() {
Serial.begin(9600);
lcd.begin(2, 16);
pinMode(3, INPUT_PULLUP);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(23, INPUT_PULLUP);
pinMode(25, INPUT_PULLUP);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
Serial.println(digitalPinToInterrupt(23));
Serial.println(digitalPinToInterrupt(25));
lcd.createChar(3, Back);
lcd.createChar(2, AlarmSymbol);
LoadDataEEPROM();
InitText();
//PCICR |= 0b100;
//PCMSK2 |= 0b100;
}