ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
NeoTrellisMenuHandler.tpp
Go to the documentation of this file.
1#pragma once
2
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;
19
20template <uint8_t menuCount>
21uint32_t MenuHandler<menuCount>::Wheel(byte WheelPos) {
22 WheelPos = 255 - WheelPos;
23 if (WheelPos < 85) {
24 return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
25 } else if (WheelPos < 170) {
26 WheelPos -= 85;
27 return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
28 } else {
29 WheelPos -= 170;
30 return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
31 }
32}
33
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))));
38
39 if (evt.bit.NUM < 8) { // Set face on the current page
40 currentMenu = 0;
41 currentValue[0] = evt.bit.NUM + 8 * faceChoices;
42 } else if (evt.bit.NUM >= 8 && evt.bit.NUM < 12) { // Set face page
43 currentMenu = 0;
44 faceChoices = evt.bit.NUM - 8;
45 } else if (evt.bit.NUM == 12) {
46 menuActive = !menuActive;
47
48 if (menuActive) {
49 currentSetting = currentSetting == 0 ? 1 : currentSetting;
50 currentMenu = currentSetting;
51 } else {
52 WriteEEPROM(currentMenu, currentValue[currentSetting]);
53
54 currentMenu = 0;
55 }
56 } else if (evt.bit.NUM == 13) { // Change current menu forward
57 WriteEEPROM(currentMenu, currentValue[currentSetting]);
58
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]);
63
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;
69 }
70 } else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
71 trellis.pixels.setPixelColor(evt.bit.NUM, 0);
72 }
73
74 trellis.pixels.show();
75
76 return 0;
77}
78
79template <uint8_t menuCount>
80uint8_t MenuHandler<menuCount>::ReadEEPROM(uint16_t index) {
81 return EEPROM.read(index);
82}
83
84template <uint8_t menuCount>
85void MenuHandler<menuCount>::WriteEEPROM(uint16_t index, uint8_t value) {
86 EEPROM.write(index, value);
87}
88
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
94}
95
96template <uint8_t menuCount>
97void MenuHandler<menuCount>::Update() {
98 unsigned long cmdTime = millis();
99
100 if (didBegin) {
101 trellis.read();
102 }
103
104 if (millis() - cmdTime > 250) {
105 // Timeout occurred
106 ResetI2CBus();
107 }
108}
109
110template <uint8_t menuCount>
111bool MenuHandler<menuCount>::Initialize() {
112 Wire.setClock(50000); // for longer-range transmissions
113
114 if (!trellis.begin()) {
115 Serial.println("Could not start Trellis, check wiring?");
116 didBegin = false;
117 } else {
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);
123 }
124
125 didBegin = true;
126
127 Serial.println("NeoPixel Trellis started");
128 }
129
130 for (uint8_t i = 0; i < menuCount; i++) {
131 currentValue[i] = ReadEEPROM(i);
132 }
133
134 return ReadEEPROM(menuCount + 1) != 255;
135}
136
137template <uint8_t menuCount>
138void MenuHandler<menuCount>::SetDefaultValue(uint16_t menu, uint8_t value) {
139 if (menu >= menuCount) return;
140
141 currentValue[menu] = value;
142
143 WriteEEPROM(menu, value);
144}
145
146template <uint8_t menuCount>
147void MenuHandler<menuCount>::SetInitialized() {
148 WriteEEPROM(menuCount + 1, 0);
149}
150
151template <uint8_t menuCount>
152void MenuHandler<menuCount>::SetMenuMax(uint8_t menu, uint8_t maxValue) {
153 if (menu >= menuCount) return;
154
155 MenuHandler::maxValue[menu] = maxValue;
156}
157
158template <uint8_t menuCount>
159uint8_t MenuHandler<menuCount>::GetMenuValue(uint8_t menu) {
160 return currentValue[menu];
161}
162
163template <uint8_t menuCount>
164uint8_t MenuHandler<menuCount>::GetCurrentMenu() {
165 return currentMenu;
166}