|
| 1 | +// |
| 2 | +// |
| 3 | +// |
| 4 | + |
| 5 | +#include "ButtonMgr.h" |
| 6 | +#include "LEDMatrix.h" |
| 7 | +#include "ClockDigit.h" |
| 8 | +#include "RTClock.h" |
| 9 | + |
| 10 | +// Define Arduino I/O pins for button management |
| 11 | +extern LedMatrixClass mtrx; |
| 12 | + |
| 13 | +extern int Num2Char(int, char *, int, int); |
| 14 | +extern int SelectDigit(char); |
| 15 | +extern ClockDigitClass *digitArray[]; // digit character maps |
| 16 | +extern RTClockClass clock; // Real-time clock abstrator class |
| 17 | + |
| 18 | +ButtonMgrClass::ButtonMgrClass(int mPin, int sPin, int lPin) |
| 19 | +{ |
| 20 | + modePin = mPin; |
| 21 | + setPin = sPin; |
| 22 | + ledPin = lPin; |
| 23 | + |
| 24 | + modeButtonState = setButtonState = HIGH; // Buttons not pressed |
| 25 | + |
| 26 | + currentOpMode = MODE_RUN; |
| 27 | + currentSetupMode = SETUP_NONE; |
| 28 | + milCounter = 0; |
| 29 | +} |
| 30 | + |
| 31 | +int ButtonMgrClass::getModeButtonState() |
| 32 | +{ |
| 33 | + return digitalRead(modePin); |
| 34 | +} |
| 35 | + |
| 36 | +int ButtonMgrClass::getSetupButtonState() |
| 37 | +{ |
| 38 | + return digitalRead(setPin); |
| 39 | +} |
| 40 | + |
| 41 | +// Check if mode button pressed for more than 3 seconds |
| 42 | +int ButtonMgrClass::modeBtnLongPress() |
| 43 | +{ |
| 44 | + int current = millis(); |
| 45 | + return ((current - milCounter) >= 3000); // check for 3 second delay |
| 46 | +} |
| 47 | + |
| 48 | +int ButtonMgrClass::checkClockSet() |
| 49 | +{ |
| 50 | + |
| 51 | + if ((getModeButtonState() == HIGH) && (getSetupButtonState() == HIGH)) // Neither button is pressed. |
| 52 | + { |
| 53 | + switch (getOpMode()) |
| 54 | + { |
| 55 | + case MODE_RUN: |
| 56 | + return 0; |
| 57 | + break; |
| 58 | + case MODE_PENDING: |
| 59 | + milCounter = 0; // In case we were |
| 60 | + setOpMode(MODE_RUN); |
| 61 | + return 0; |
| 62 | + break; |
| 63 | + case MODE_SETUP: |
| 64 | + break; |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + // If both buttons are pressed for 5 seconds, reset clock! |
| 69 | + if ((getModeButtonState() == LOW) && (getSetupButtonState() == LOW)) |
| 70 | + { |
| 71 | + int mtmp1 = millis(), mtmp2; |
| 72 | + |
| 73 | + while ((getModeButtonState() == LOW) && (getSetupButtonState() == LOW)) |
| 74 | + { |
| 75 | + mtmp2 = millis(); |
| 76 | + if ((mtmp2 - mtmp1) >= 5000) // Wait for 5 seconds |
| 77 | + { |
| 78 | + mtrx.fillScreen(); |
| 79 | + clock.resetClock(); |
| 80 | + setOpMode(MODE_RUN); |
| 81 | + setSetupMode(SETUP_NONE); |
| 82 | + milCounter = 0; |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + mtrx.clearScreen(); |
| 87 | + return 0; |
| 88 | + } |
| 89 | + |
| 90 | + if (getModeButtonState() == LOW) // Mode button is pressed |
| 91 | + { |
| 92 | + switch (getOpMode()) |
| 93 | + { |
| 94 | + case MODE_RUN: |
| 95 | + // Currently in normal mode - switch to pending setup mode, start long-press counter |
| 96 | + setOpMode(MODE_PENDING); |
| 97 | + milCounter = millis(); // reset long-press counter |
| 98 | + return 0; |
| 99 | + break; |
| 100 | + case MODE_PENDING: |
| 101 | + // In pending set up mode - see if the button has been pressed for a while |
| 102 | + if (modeBtnLongPress()) |
| 103 | + { |
| 104 | + setOpMode(MODE_SETUP); |
| 105 | + setSetupMode(SETUP_HOUR); |
| 106 | + milCounter = 0; |
| 107 | + digitalWrite(ledPin, HIGH); |
| 108 | + delay(250); |
| 109 | + while ((getModeButtonState() == LOW)); // Wait until button is released. Otherwise will loop through options uncontrollably |
| 110 | + mtrx.clearScreen(); |
| 111 | + } |
| 112 | + return 0; |
| 113 | + break; |
| 114 | + case MODE_SETUP: // Currently in setup mode - switch the thing you're setting |
| 115 | + mtrx.clearScreen(); |
| 116 | + if (++currentSetupMode == setupArraySize) // done with setup |
| 117 | + { |
| 118 | + setOpMode(MODE_RUN); |
| 119 | + setSetupMode(SETUP_NONE); |
| 120 | + digitalWrite(ledPin, LOW); |
| 121 | + milCounter = 0; |
| 122 | + } |
| 123 | + delay(250); |
| 124 | + while ((getModeButtonState() == LOW)); // Wait until button is released. Otherwise will loop through options uncontrollably |
| 125 | + return 0; |
| 126 | + break; |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + if (getSetupButtonState() == LOW) // Setup button is pressed |
| 131 | + { |
| 132 | + switch (getSetupMode()) |
| 133 | + { |
| 134 | + case SETUP_HOUR: |
| 135 | + clock.incrementUnit(UNIT_HOUR); |
| 136 | + break; |
| 137 | + case SETUP_MINUTE: |
| 138 | + clock.incrementUnit(UNIT_MINUTE); |
| 139 | + break; |
| 140 | + case SETUP_DAY: |
| 141 | + clock.incrementUnit(UNIT_DAY); |
| 142 | + break; |
| 143 | + case SETUP_MONTH: |
| 144 | + clock.incrementUnit(UNIT_MONTH); |
| 145 | + break; |
| 146 | + case SETUP_YEAR: |
| 147 | + clock.incrementUnit(UNIT_YEAR); |
| 148 | + break; |
| 149 | + case SETUP_NONE: |
| 150 | + break; |
| 151 | + } |
| 152 | + |
| 153 | + while ((getSetupButtonState() == LOW)) // Wait until button is released. Otherwise will loop through options uncontrollably |
| 154 | + { |
| 155 | + if (getModeButtonState() == LOW) // Mode buton pressed in the middle |
| 156 | + return 0; |
| 157 | + } |
| 158 | + |
| 159 | + } |
| 160 | + runClockSet(getOpMode()); |
| 161 | +} |
| 162 | + |
| 163 | +void ButtonMgrClass::runClockSet(int mode) |
| 164 | +{ |
| 165 | + char hexnum[5]; |
| 166 | + |
| 167 | + switch (getSetupMode()) |
| 168 | + { |
| 169 | + case SETUP_HOUR: |
| 170 | + Num2Char(clock.getUnit(UNIT_HOUR), hexnum, DEC, 2); |
| 171 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[0])], 0, 0); |
| 172 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[1])], 0, 4); |
| 173 | + mtrx.placeChar(digitArray[SelectDigit(':')], 1, 9); |
| 174 | + break; |
| 175 | + case SETUP_MINUTE: |
| 176 | + Num2Char(clock.getUnit(UNIT_MINUTE), hexnum, DEC, 2); |
| 177 | + mtrx.placeChar(digitArray[SelectDigit(':')], 1, 9); |
| 178 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[0])], 0, 12); |
| 179 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[1])], 0, 16); |
| 180 | + mtrx.placeChar(digitArray[SelectDigit(':')], 1, 21); |
| 181 | + break; |
| 182 | + case SETUP_MONTH: |
| 183 | + Num2Char(clock.getUnit(UNIT_MONTH), hexnum, DEC, 2); |
| 184 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[0])], 6, 0); |
| 185 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[1])], 6, 4); |
| 186 | + mtrx.placeChar(digitArray[SelectDigit('/')], 7, 8); |
| 187 | + break; |
| 188 | + case SETUP_DAY: |
| 189 | + Num2Char(clock.getUnit(UNIT_DAY), hexnum, DEC, 2); |
| 190 | + mtrx.placeChar(digitArray[SelectDigit('/')], 7, 8); |
| 191 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[0])], 6, 12); |
| 192 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[1])], 6, 16); |
| 193 | + mtrx.placeChar(digitArray[SelectDigit('/')], 7, 20); |
| 194 | + break; |
| 195 | + case SETUP_YEAR: |
| 196 | + Num2Char(clock.getUnit(UNIT_YEAR) % 100, hexnum, DEC, 2); |
| 197 | + mtrx.placeChar(digitArray[SelectDigit('/')], 7, 20); |
| 198 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[0])], 6, 24); |
| 199 | + mtrx.placeChar(digitArray[SelectDigit(hexnum[1])], 6, 28); |
| 200 | + break; |
| 201 | + case SETUP_NONE: |
| 202 | + break; |
| 203 | + } |
| 204 | +} |
| 205 | + |
0 commit comments