aboutsummaryrefslogtreecommitdiff
path: root/Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2020-07-04 22:55:07 +0300
committerSyndamia <kamen.d.mladenov@protonmail.com>2020-07-04 22:55:07 +0300
commit3c929ca6a764f6096f50201ed601126f067780d0 (patch)
tree132e8dbda44f2fc7d66e7e1fda719f2b1d41f349 /Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino
parent7305043f78bdc9bf87c9971f80ee55dc4964d6ea (diff)
downloadRemiHap-3c929ca6a764f6096f50201ed601126f067780d0.tar
RemiHap-3c929ca6a764f6096f50201ed601126f067780d0.tar.gz
RemiHap-3c929ca6a764f6096f50201ed601126f067780d0.zip
Added code from menus for editing alarms.
Diffstat (limited to 'Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino')
-rw-r--r--Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino367
1 files changed, 367 insertions, 0 deletions
diff --git a/Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino b/Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino
new file mode 100644
index 0000000..29c480a
--- /dev/null
+++ b/Code from circuits/AlarmsEditMenu/AlarmsEditMenu.ino
@@ -0,0 +1,367 @@
+#include <Keypad.h>
+#include <LiquidCrystal.h>
+
+// LCD
+
+#define LCD_ROWS 2
+#define LCD_COLS 16
+
+#define MSG_ERR_R1 " Error! "
+#define ERROR_VISIBILITY_TIMEOUT 2000
+
+/* Alarm menu */
+
+#define MSG_ALRM_R2 "a C D B"
+#define MSG_NO_ALRM_R1 " No alarms "
+#define MSG_NO_ALRM_R2 " #: Create new "
+
+#define MSG_EDIT_TOOLS "# A B C D "
+#define MSG_HOUR " Hour(0-23) #"
+#define MSG_MINUTES " Minutes(0-59) #"
+#define MSG_DISPENSER " Dispenser #"
+#define MSG_CONFIRM "Sure? Yes:# No:C"
+
+/* Week menu */
+
+#define MSG_DAY_NUM "Day number(1-7) "
+#define MSG_WEEK_TOGGLE " A - toggle "
+
+/* Main menu */
+
+#define MSG_MAIN_R1 " A: Week days "
+#define MSG_MAIN_R2 " B: Alarms "
+
+// Keypad
+
+#define KEYPAD_ROWS 4
+#define KEYPAD_COLS 4
+
+// Alarms
+
+#define ALARMS_PER_DAY 10
+#define WEEK_LENGTH 7
+
+int i, j; //variables for loops
+
+/*
+ * ---------------------------------------------
+*/
+
+//
+// LCD
+//
+
+LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
+
+void printToLCD(int rowID, char message[])
+{
+ lcd.setCursor(0, rowID);
+
+ for(i = 0; i < LCD_COLS; i++)
+ {
+ lcd.write(message[i]);
+ delay(1); //TinkerCad optimization
+ }
+}
+
+void printErrorToLCD(char message[])
+{
+ printToLCD(0, MSG_ERR_R1);
+ printToLCD(1, message);
+
+ delay(ERROR_VISIBILITY_TIMEOUT);
+}
+
+//
+// Keypad
+//
+
+char keys[KEYPAD_ROWS][KEYPAD_COLS] =
+{
+ {'1','2','3','A'},
+ {'4','5','6','B'},
+ {'7','8','9','C'},
+ {'*','0','#','D'}
+};
+byte rowPins[KEYPAD_ROWS] = {9, 8, 7, 6};
+byte colPins[KEYPAD_COLS] = {5, 4, 3, 2};
+
+Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
+
+//
+// Days of week
+//
+
+char weekLetters[] = {'M', 'T', 'W', 'H', 'F', 'S', 'U'};
+
+int toggleDayIndex;
+
+void toggleWeekDayEnable()
+{
+ weekLetters[toggleDayIndex] = (isupper(weekLetters[toggleDayIndex]))
+ ? tolower(weekLetters[toggleDayIndex])
+ : toupper(weekLetters[toggleDayIndex]);
+}
+
+//
+// Alarms
+//
+
+class TAlarm
+{
+ public:
+ char *day, hour, minutes, dispenserId = -1;
+};
+
+TAlarm alarms[WEEK_LENGTH * ALARMS_PER_DAY];
+
+bool alarmExists(int index)
+{
+ return alarms[index].dispenserId != -1;
+}
+
+int firstFreeAlarmIndex()
+{
+ for(i = 0; i < sizeof(alarms)/sizeof(*alarms); i++)
+ {
+ if (alarms[i].dispenserId == -1) break;
+ }
+ return (i == sizeof(alarms)/sizeof(*alarms)) ? -1 : --i;
+}
+
+//
+// Menus
+//
+
+void (*menu)(char);
+bool confirm;
+
+/* Alarm menu */
+
+char formatted[LCD_COLS + 1];
+int alarmIndex;
+bool editing;
+
+bool awaitingHour;
+int tmpHour = -1;
+bool awaitingMinutes;
+int tmpMin = -1;
+bool awaitingDispenser;
+int tmpDis = -1;
+bool deletion;
+
+void resetEditingValues(bool skipValues) {
+ if (!skipValues) {
+ tmpHour = -1, tmpMin = -1, tmpDis = -1;
+ }
+ awaitingHour = false, awaitingMinutes = false, awaitingDispenser = false, deletion = false, confirm = false;
+}
+
+void setEditingNum(int *buffer, char key, int row) {
+ if (*buffer > -1) {
+ *buffer *= 10;
+ *buffer += key - '0';
+ editingSubMenu('#', row);
+ }
+ else {
+ *buffer = key - '0';
+ }
+}
+
+void editingSubMenu(char key, int row) {
+ switch(key) {
+ case 'A': menu = weekMenu; menu('~');
+ break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ case '0':
+ if (awaitingHour)
+ {
+ setEditingNum(&tmpHour, key, row);
+ }
+ else if (awaitingMinutes) {
+ setEditingNum(&tmpMin, key, row);
+ }
+ else if (awaitingDispenser) {
+ setEditingNum(&tmpDis, key, row);
+ }
+
+ break;
+ case 'B': awaitingHour = true; printToLCD(row, MSG_HOUR); break;
+ case 'C':
+ if (confirm) {
+ editingSubMenu('*');
+ }
+ else {
+ awaitingMinutes = true;
+ printToLCD(row, MSG_MINUTES);
+ }
+
+ break;
+ case 'D': awaitingDispenser = true; printToLCD(row, MSG_DISPENSER); break;
+ case '#':
+ if (!awaitingHour && !awaitingMinutes && !awaitingDispenser && !deletion) {
+ resetEditingValues(false);
+ deletion = true;
+ printToLCD(row, MSG_CONFIRM);
+ break;
+ }
+
+ if (deletion) {
+ alarms[alarmIndex].dispenserId = -1;
+ resetEditingValues(false);
+ alarmIndex = firstFreeAlarmIndex();
+ editingSubMenu('*', row);
+ }
+ else if (confirm) {
+ if(tmpHour != -1) alarms[alarmIndex].hour = tmpHour;
+ if(tmpMin != -1) alarms[alarmIndex].minutes = tmpMin;
+ if(tmpDis != -1) alarms[alarmIndex].dispenserId = tmpDis;
+
+ resetEditingValues(false);
+ alarmMenu('~');
+ editingSubMenu('~');
+ }
+ else {
+ resetEditingValues(true);
+ confirm = true;
+ printToLCD(row, MSG_CONFIRM);
+ }
+
+ break;
+ case '*': resetEditingValues(false); menu = alarmMenu; menu('~'); break;
+ case '~': printToLCD(row, MSG_EDIT_TOOLS); break;
+ }
+}
+
+void editingSubMenu(char key) {
+ editingSubMenu(key, 1);
+}
+
+void printAlarmMenu() {
+ if (firstFreeAlarmIndex() < 0)
+ {
+ printToLCD(0, MSG_NO_ALRM_R1);
+ printToLCD(1, MSG_NO_ALRM_R2);
+ }
+ else
+ {
+ snprintf(formatted, LCD_COLS + 1, "%02i %c %02i:%02i %i ", alarmIndex, *alarms[alarmIndex].day, alarms[alarmIndex].hour, alarms[alarmIndex].minutes, alarms[alarmIndex].dispenserId);
+ printToLCD(0, formatted);
+
+ if (!editing) {
+ snprintf(formatted, LCD_COLS + 1, "%c C %c", (alarmIndex > 0) ? 'A' : 'a' , (alarmIndex < firstFreeAlarmIndex()) ? 'B' : 'b');
+ printToLCD(1, formatted);
+ }
+ }
+}
+
+void alarmMenu(char key) {
+ switch(key) {
+ case 'A':
+ if (alarmIndex > 0) {
+ alarmIndex--;
+ printAlarmMenu();
+ }
+
+ break;
+ case 'B':
+ if (alarmIndex < firstFreeAlarmIndex()) {
+ alarmIndex++;
+ printAlarmMenu();
+ }
+
+ break;
+ case 'C': menu = editingSubMenu; menu('~'); break;
+ case '#':
+ //menu = editingSubMenu;
+ break;
+ case '*': menu = mainMenu; menu('~'); break;
+ case '~': alarmIndex = firstFreeAlarmIndex(); printAlarmMenu(); break;
+ }
+}
+
+/* Week menu */
+
+bool waitForDayNum;
+
+void printWeekMenu()
+{
+ sprintf(formatted," %c %c %c %c %c %c %c ", weekLetters[0], weekLetters[1], weekLetters[2], weekLetters[3], weekLetters[4], weekLetters[5], weekLetters[6], weekLetters[7]);
+ printToLCD(0, formatted);
+
+ if (waitForDayNum) printToLCD(1, MSG_DAY_NUM);
+ else if (confirm) printToLCD(1, MSG_CONFIRM);
+ else printToLCD(1, MSG_WEEK_TOGGLE);
+}
+
+
+
+void weekMenu(char key)
+{
+ switch(key)
+ {
+ case 'A': waitForDayNum = true; weekMenu('~'); break;
+ case 'C': confirm = false; weekMenu('~'); break;
+ case '#':
+ if (confirm)
+ {
+ toggleWeekDayEnable();
+ confirm = false;
+ }
+ weekMenu('~');
+
+ break;
+ case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7':
+ if (waitForDayNum)
+ {
+ toggleDayIndex = (key - '0') - 1;
+ waitForDayNum = false; confirm = true;
+ }
+ weekMenu('~');
+
+ break;
+ case '*': menu = mainMenu; menu('~'); break;
+ case '~': printWeekMenu(); break;
+ }
+}
+
+/* Main menu */
+
+void mainMenu(char key)
+{
+ switch(key)
+ {
+ case 'A': menu = weekMenu; weekMenu('~'); break;
+ case 'B': menu = alarmMenu; alarmMenu('~'); break;
+ default: printToLCD(0, MSG_MAIN_R1); printToLCD(1, MSG_MAIN_R2); break;
+ }
+}
+
+//
+// Main logic
+//
+
+void setup()
+{
+ lcd.begin(LCD_COLS, LCD_ROWS);
+ alarms[0].dispenserId = 3;
+ alarms[0].day = &weekLetters[1];
+ alarms[1].dispenserId = 4;
+ alarms[1].day = &weekLetters[6];
+
+ menu = mainMenu;
+ mainMenu('~');
+}
+
+char key;
+void loop()
+{
+ key = keypad.getKey(); // getKey function is too quick, once you get the key, the second time you get it it will return null
+ if (key != '\0')
+ {
+ menu(key);
+ }
+ delay(1); //TinkerCad optimization
+}