-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from aaronze/add-morse-code-input-on-single-bu…
…tton Added morse code input module and integrated it into the menu system
- Loading branch information
Showing
6 changed files
with
269 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
lib/ProtoTracer/ExternalDevices/InputDevices/SingleButtonMorseHandler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
|
||
#include <Arduino.h> | ||
#include <EEPROM.h> | ||
|
||
template <uint8_t menuCount> | ||
class MenuHandler { | ||
private: | ||
static bool previousState; | ||
static long previousMillis; | ||
static uint8_t inputCount; | ||
static uint16_t inputStream[4]; | ||
static uint8_t currentMenu; | ||
static uint8_t currentValue[menuCount]; | ||
static uint8_t maxValue[menuCount]; | ||
static uint8_t pin; | ||
|
||
static uint8_t ReadEEPROM(uint16_t index); | ||
static void WriteEEPROM(uint16_t index, uint8_t value); | ||
|
||
public: | ||
static void Begin(); | ||
static bool Initialize(uint8_t pin, uint16_t holdingTime); | ||
static void SetDefaultValue(uint16_t menu, uint8_t value); | ||
static void SetInitialized(); | ||
static void SetMenuMax(uint8_t menu, uint8_t maxValue); | ||
static void Update(); | ||
static uint8_t GetMenuValue(uint8_t menu); | ||
static uint8_t GetCurrentMenu(); | ||
}; | ||
|
||
#include "SingleButtonMorseHandler.tpp" |
183 changes: 183 additions & 0 deletions
183
lib/ProtoTracer/ExternalDevices/InputDevices/SingleButtonMorseHandler.tpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
#pragma once | ||
|
||
template <uint8_t menuCount> | ||
bool MenuHandler<menuCount>::previousState; | ||
|
||
template <uint8_t menuCount> | ||
long MenuHandler<menuCount>::previousMillis; | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::inputCount; | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::currentMenu; | ||
|
||
template <uint8_t menuCount> | ||
uint16_t MenuHandler<menuCount>::inputStream[4]; | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::currentValue[menuCount]; | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::maxValue[menuCount]; | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::pin; | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::Begin() { | ||
previousMillis = millis(); | ||
previousState = false; | ||
} | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::Update() { | ||
bool pinState = !digitalRead(pin); | ||
long timeOn = millis() - previousMillis; | ||
|
||
if (timeOn < 40) return; | ||
|
||
if (!pinState && inputCount > 0 && timeOn > 500) { | ||
uint32_t mask = 0; | ||
if (inputStream[0] > 0) mask |= (inputStream[0] < 150 ? 1 : 2) << 0; // 1 2 | ||
if (inputStream[1] > 0) mask |= (inputStream[1] < 150 ? 1 : 2) << 2; // 4 8 | ||
if (inputStream[2] > 0) mask |= (inputStream[2] < 150 ? 1 : 2) << 4; // 16 32 | ||
if (inputStream[3] > 0) mask |= (inputStream[3] < 150 ? 1 : 2) << 6; // 64 128 | ||
|
||
uint8_t val; | ||
switch (mask) { | ||
case 9: val = 1; break; // A: .- | ||
case 86: val = 2; break; // B: -... | ||
case 102: val = 3; break; // C: -.-. | ||
case 22: val = 4; break; // D: -.. | ||
case 1: val = 5; break; // E: . | ||
case 101: val = 6; break; // F: ..-. | ||
case 26: val = 7; break; // G: --. | ||
case 85: val = 8; break; // H: .... | ||
case 5: val = 9; break; // I: .. | ||
case 169: val = 10; break; // J: .--- | ||
case 38: val = 11; break; // K: -.- | ||
case 89: val = 12; break; // L: .-.. | ||
case 10: val = 13; break; // M: -- | ||
case 6: val = 14; break; // N: -. | ||
case 42: val = 15; break; // O: --- | ||
case 105: val = 16; break; // P: .--. | ||
case 154: val = 17; break; // Q: --.- | ||
case 25: val = 18; break; // R: .-. | ||
case 21: val = 19; break; // S: ... | ||
case 2: val = 20; break; // T: - | ||
case 37: val = 21; break; // U: ..- | ||
case 149: val = 22; break; // V: ...- | ||
case 41: val = 23; break; // W: .-- | ||
case 150: val = 24; break; // X: -..- | ||
case 166: val = 25; break; // Y: -.-- | ||
case 90: val = 26; break; // Z: --.. | ||
default: val = 0; break; | ||
} | ||
|
||
if (val == 20) { | ||
// T (long press) is used to advance menu, to keep it similar to default menu navigation | ||
WriteEEPROM(currentMenu, currentValue[currentMenu]); | ||
currentMenu = (currentMenu + 1) % menuCount; | ||
} else if (currentMenu > 0) { | ||
// When in the menu | ||
switch (val) { | ||
case 5: | ||
// E (short press) is used to advance selection in non-face menu, to keep it similar to default menu navigation | ||
val = currentValue[currentMenu] + 1; | ||
if (maxValue[currentMenu] > 0) val = val % maxValue[currentMenu]; | ||
currentValue[currentMenu] = val; | ||
break; | ||
case 9: | ||
// I (2 short presses) is used to go back a selection in non-face menu | ||
val = currentValue[currentMenu] - 1; | ||
if (maxValue[currentMenu] < 0) val += maxValue[currentMenu]; | ||
currentValue[currentMenu] = val; | ||
break; | ||
case 13: | ||
// M (2 long presses) is used to go back a menu | ||
WriteEEPROM(currentMenu, currentValue[currentMenu]); | ||
currentMenu = (currentMenu - 1) % menuCount; | ||
break; | ||
case 15: | ||
// O (3 long presses) is used to exit the menu | ||
WriteEEPROM(currentMenu, currentValue[currentMenu]); | ||
currentMenu = 0; | ||
break; | ||
} | ||
} else { | ||
if (maxValue[currentMenu] > 0) val = val % maxValue[currentMenu]; // If max is set, wrap value | ||
currentValue[currentMenu] = val; | ||
} | ||
|
||
std::fill_n(inputStream, inputCount, 0); | ||
inputCount = 0; | ||
previousState = false; | ||
return; | ||
} | ||
|
||
if (pinState == previousState) return; | ||
|
||
if (!pinState) { | ||
inputStream[inputCount] = timeOn; | ||
inputCount += 1; | ||
} | ||
|
||
previousMillis = millis(); | ||
previousState = pinState; | ||
} | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::ReadEEPROM(uint16_t index) { | ||
return EEPROM.read(index); | ||
} | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::WriteEEPROM(uint16_t index, uint8_t value) { | ||
EEPROM.write(index, value); | ||
} | ||
|
||
template <uint8_t menuCount> | ||
bool MenuHandler<menuCount>::Initialize(uint8_t pin, uint16_t _holdingTime) { | ||
MenuHandler::pin = pin; | ||
MenuHandler::previousState = false; | ||
|
||
pinMode(pin, INPUT_PULLUP); | ||
|
||
for (uint8_t i = 0; i < menuCount; i++) { | ||
currentValue[i] = ReadEEPROM(i); | ||
} | ||
|
||
return ReadEEPROM(menuCount + 1) != 255; | ||
} | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::SetDefaultValue(uint16_t menu, uint8_t value) { | ||
if (menu >= menuCount) return; | ||
|
||
currentValue[menu] = value; | ||
|
||
WriteEEPROM(menu, value); | ||
} | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::SetInitialized() { | ||
WriteEEPROM(menuCount + 1, 0); | ||
} | ||
|
||
template <uint8_t menuCount> | ||
void MenuHandler<menuCount>::SetMenuMax(uint8_t menu, uint8_t maxValue) { | ||
if (menu >= menuCount) return; | ||
|
||
MenuHandler::maxValue[menu] = maxValue; | ||
} | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::GetMenuValue(uint8_t menu) { | ||
return currentValue[menu]; | ||
} | ||
|
||
template <uint8_t menuCount> | ||
uint8_t MenuHandler<menuCount>::GetCurrentMenu() { | ||
return currentMenu; | ||
} |