3template <uint8_t menuCount>
4Adafruit_NeoTrellis MenuHandler<menuCount>::trellis;
5template <uint8_t menuCount>
6uint8_t MenuHandler<menuCount>::currentMenu;
7template <uint8_t menuCount>
8uint8_t MenuHandler<menuCount>::currentSetting = 0;
9template <uint8_t menuCount>
10uint8_t MenuHandler<menuCount>::currentValue[menuCount];
11template <uint8_t menuCount>
12uint8_t MenuHandler<menuCount>::maxValue[menuCount];
13template <uint8_t menuCount>
14uint8_t MenuHandler<menuCount>::faceChoices = 0;
15template <uint8_t menuCount>
16bool MenuHandler<menuCount>::menuActive = false;
17template <uint8_t menuCount>
18bool MenuHandler<menuCount>::didBegin = false;
20template <uint8_t menuCount>
21uint32_t MenuHandler<menuCount>::Wheel(byte WheelPos) {
22 WheelPos = 255 - WheelPos;
24 return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
25 } else if (WheelPos < 170) {
27 return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
30 return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
34template <uint8_t menuCount>
35TrellisCallback MenuHandler<menuCount>::blink(keyEvent evt) {
36 if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
37 trellis.pixels.setPixelColor(evt.bit.NUM, Wheel(map(uint16_t(evt.bit.NUM), uint16_t(0), trellis.pixels.numPixels(), uint16_t(0), uint16_t(255))));
39 if (evt.bit.NUM < 8) { // Set face on the current page
41 currentValue[0] = evt.bit.NUM + 8 * faceChoices;
42 } else if (evt.bit.NUM >= 8 && evt.bit.NUM < 12) { // Set face page
44 faceChoices = evt.bit.NUM - 8;
45 } else if (evt.bit.NUM == 12) {
46 menuActive = !menuActive;
49 currentSetting = currentSetting == 0 ? 1 : currentSetting;
50 currentMenu = currentSetting;
52 WriteEEPROM(currentMenu, currentValue[currentSetting]);
56 } else if (evt.bit.NUM == 13) { // Change current menu forward
57 WriteEEPROM(currentMenu, currentValue[currentSetting]);
59 currentSetting = currentSetting + 1 > menuCount ? menuCount : currentSetting + 1;
60 currentMenu = currentSetting;
61 } else if (evt.bit.NUM == 14) { // Change current menu backward
62 WriteEEPROM(currentMenu, currentValue[currentSetting]);
64 currentSetting = currentSetting - 1 == 0 ? 1 : currentSetting - 1;
65 currentMenu = currentSetting;
66 } else if (evt.bit.NUM == 15) {
67 currentValue[currentSetting] += 1;
68 if (currentValue[currentSetting] >= maxValue[currentSetting]) currentValue[currentSetting] = 0;
70 } else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
71 trellis.pixels.setPixelColor(evt.bit.NUM, 0);
74 trellis.pixels.show();
79template <uint8_t menuCount>
80uint8_t MenuHandler<menuCount>::ReadEEPROM(uint16_t index) {
81 return EEPROM.read(index);
84template <uint8_t menuCount>
85void MenuHandler<menuCount>::WriteEEPROM(uint16_t index, uint8_t value) {
86 EEPROM.write(index, value);
89template <uint8_t menuCount>
90void MenuHandler<menuCount>::ResetI2CBus() {
91 Wire.end(); // Disable the I2C hardware
92 delay(10); // Wait a bit
93 Wire.begin(); // Re-enable the I2C hardware
96template <uint8_t menuCount>
97void MenuHandler<menuCount>::Update() {
98 unsigned long cmdTime = millis();
104 if (millis() - cmdTime > 250) {
110template <uint8_t menuCount>
111bool MenuHandler<menuCount>::Initialize() {
112 Wire.setClock(50000); // for longer-range transmissions
114 if (!trellis.begin()) {
115 Serial.println("Could not start Trellis, check wiring?");
118 // Activate all keys and set callbacks
119 for (int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++) {
120 trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
121 trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
122 trellis.registerCallback(i, blink);
127 Serial.println("NeoPixel Trellis started");
130 for (uint8_t i = 0; i < menuCount; i++) {
131 currentValue[i] = ReadEEPROM(i);
134 return ReadEEPROM(menuCount + 1) != 255;
137template <uint8_t menuCount>
138void MenuHandler<menuCount>::SetDefaultValue(uint16_t menu, uint8_t value) {
139 if (menu >= menuCount) return;
141 currentValue[menu] = value;
143 WriteEEPROM(menu, value);
146template <uint8_t menuCount>
147void MenuHandler<menuCount>::SetInitialized() {
148 WriteEEPROM(menuCount + 1, 0);
151template <uint8_t menuCount>
152void MenuHandler<menuCount>::SetMenuMax(uint8_t menu, uint8_t maxValue) {
153 if (menu >= menuCount) return;
155 MenuHandler::maxValue[menu] = maxValue;
158template <uint8_t menuCount>
159uint8_t MenuHandler<menuCount>::GetMenuValue(uint8_t menu) {
160 return currentValue[menu];
163template <uint8_t menuCount>
164uint8_t MenuHandler<menuCount>::GetCurrentMenu() {