David Knight / Mbed 2 deprecated lichtspiel

Dependencies:   PololuLedStrip mbed

Committer:
thegink
Date:
Sat May 19 14:27:12 2018 +0000
Revision:
0:8dc213146b30
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
thegink 0:8dc213146b30 1 #include "mbed.h"
thegink 0:8dc213146b30 2 #include "EffectPlugs.h"
thegink 0:8dc213146b30 3 #include "Effects.h"
thegink 0:8dc213146b30 4 #include "InteractionTimeout.h"
thegink 0:8dc213146b30 5 #include "LEDs.h"
thegink 0:8dc213146b30 6 #include "Rotary.h"
thegink 0:8dc213146b30 7 #include "Pulser.h"
thegink 0:8dc213146b30 8 #include "board.h"
thegink 0:8dc213146b30 9
thegink 0:8dc213146b30 10 //#define DEV
thegink 0:8dc213146b30 11
thegink 0:8dc213146b30 12 #ifdef DEV
thegink 0:8dc213146b30 13 static const uint16_t INTERACTION_TIMEOUT_SECONDS = 60;
thegink 0:8dc213146b30 14 #define DEBUG(...); pc.printf(__VA_ARGS__);
thegink 0:8dc213146b30 15 #else
thegink 0:8dc213146b30 16 static const uint16_t INTERACTION_TIMEOUT_SECONDS = 180;
thegink 0:8dc213146b30 17 #define DEBUG(...);
thegink 0:8dc213146b30 18 #endif
thegink 0:8dc213146b30 19
thegink 0:8dc213146b30 20
thegink 0:8dc213146b30 21 bool standBy = false;
thegink 0:8dc213146b30 22 uint8_t lastButtonState[NUM_BUTTONS] = {1,1,1,1,1};
thegink 0:8dc213146b30 23 bool buttonIsUpdatingLED[NUM_BUTTONS] = {false,false,false,false,false};
thegink 0:8dc213146b30 24
thegink 0:8dc213146b30 25 // Generated with Ruby: (0..255).map{|i| (64 + (256 - 64) / 256.0 * i).round }.join(',')
thegink 0:8dc213146b30 26 uint8_t mapS[256] = {
thegink 0:8dc213146b30 27 64,65,66,66,67,68,69,69,70,71,72,72,73,74,75,75,
thegink 0:8dc213146b30 28 76,77,78,78,79,80,81,81,82,83,84,84,85,86,87,87,
thegink 0:8dc213146b30 29 88,89,90,90,91,92,93,93,94,95,96,96,97,98,99,99,
thegink 0:8dc213146b30 30 100,101,102,102,103,104,105,105,106,107,108,108,
thegink 0:8dc213146b30 31 109,110,111,111,112,113,114,114,115,116,117,117,
thegink 0:8dc213146b30 32 118,119,120,120,121,122,123,123,124,125,126,126,
thegink 0:8dc213146b30 33 127,128,129,129,130,131,132,132,133,134,135,135,
thegink 0:8dc213146b30 34 136,137,138,138,139,140,141,141,142,143,144,144,
thegink 0:8dc213146b30 35 145,146,147,147,148,149,150,150,151,152,153,153,
thegink 0:8dc213146b30 36 154,155,156,156,157,158,159,159,160,161,162,162,
thegink 0:8dc213146b30 37 163,164,165,165,166,167,168,168,169,170,171,171,
thegink 0:8dc213146b30 38 172,173,174,174,175,176,177,177,178,179,180,180,
thegink 0:8dc213146b30 39 181,182,183,183,184,185,186,186,187,188,189,189,
thegink 0:8dc213146b30 40 190,191,192,192,193,194,195,195,196,197,198,198,
thegink 0:8dc213146b30 41 199,200,201,201,202,203,204,204,205,206,207,207,
thegink 0:8dc213146b30 42 208,209,210,210,211,212,213,213,214,215,216,216,
thegink 0:8dc213146b30 43 217,218,219,219,220,221,222,222,223,224,225,225,
thegink 0:8dc213146b30 44 226,227,228,228,229,230,231,231,232,233,234,234,
thegink 0:8dc213146b30 45 235,236,237,237,238,239,240,240,241,242,243,243,
thegink 0:8dc213146b30 46 244,245,246,246,247,248,249,249,250,251,252,252,253,254,255,255
thegink 0:8dc213146b30 47 };
thegink 0:8dc213146b30 48
thegink 0:8dc213146b30 49 // Generated with Ruby: (0..255).map{|i| (i / 2.0 + 48).round }.join(',')
thegink 0:8dc213146b30 50 uint8_t mapV[256] = {
thegink 0:8dc213146b30 51 32,33,33,34,34,35,36,36,37,37,38,39,39,40,40,41,
thegink 0:8dc213146b30 52 42,42,43,43,44,45,45,46,46,47,48,48,49,50,50,51,
thegink 0:8dc213146b30 53 51,52,53,53,54,54,55,56,56,57,57,58,59,59,60,60,
thegink 0:8dc213146b30 54 61,62,62,63,63,64,65,65,66,66,67,68,68,69,69,70,
thegink 0:8dc213146b30 55 71,71,72,72,73,74,74,75,75,76,77,77,78,78,79,80,
thegink 0:8dc213146b30 56 80,81,82,82,83,83,84,85,85,86,86,87,88,88,89,89,
thegink 0:8dc213146b30 57 90,91,91,92,92,93,94,94,95,95,96,97,97,98,98,99,
thegink 0:8dc213146b30 58 100,100,101,101,102,103,103,104,104,105,106,106,
thegink 0:8dc213146b30 59 107,107,108,109,109,110,110,111,112,112,113,114,
thegink 0:8dc213146b30 60 114,115,115,116,117,117,118,118,119,120,120,121,
thegink 0:8dc213146b30 61 121,122,123,123,124,124,125,126,126,127,127,128,
thegink 0:8dc213146b30 62 129,129,130,130,131,132,132,133,133,134,135,135,
thegink 0:8dc213146b30 63 136,136,137,138,138,139,139,140,141,141,142,142,
thegink 0:8dc213146b30 64 143,144,144,145,146,146,147,147,148,149,149,150,
thegink 0:8dc213146b30 65 150,151,152,152,153,153,154,155,155,156,156,157,
thegink 0:8dc213146b30 66 158,158,159,159,160,161,161,162,162,163,164,164,
thegink 0:8dc213146b30 67 165,165,166,167,167,168,168,169,170,170,171,171,
thegink 0:8dc213146b30 68 172,173,173,174,174,175,176,176,177,178,178,179,
thegink 0:8dc213146b30 69 179,180,181,181,182,182,183,184,184,185,185,186
thegink 0:8dc213146b30 70 };
thegink 0:8dc213146b30 71
thegink 0:8dc213146b30 72 uint8_t lastH, lastS, lastV, lastEffect;
thegink 0:8dc213146b30 73
thegink 0:8dc213146b30 74 DigitalInOut effectsPins[NUM_EFFECT_PLUGS] = {DigitalInOut(EFFECT_PLUGS_PINS[0]),
thegink 0:8dc213146b30 75 DigitalInOut(EFFECT_PLUGS_PINS[1]),
thegink 0:8dc213146b30 76 DigitalInOut(EFFECT_PLUGS_PINS[2]),
thegink 0:8dc213146b30 77 DigitalInOut(EFFECT_PLUGS_PINS[3])};
thegink 0:8dc213146b30 78
thegink 0:8dc213146b30 79 DigitalIn buttons[NUM_BUTTONS] = {DigitalIn(BUTTON_PINS[0], PullUp),
thegink 0:8dc213146b30 80 DigitalIn(BUTTON_PINS[1], PullUp),
thegink 0:8dc213146b30 81 DigitalIn(BUTTON_PINS[2], PullUp),
thegink 0:8dc213146b30 82 DigitalIn(BUTTON_PINS[3], PullUp),
thegink 0:8dc213146b30 83 DigitalIn(BUTTON_PINS[4], PullUp)};
thegink 0:8dc213146b30 84
thegink 0:8dc213146b30 85 InteractionTimeout interactionTimeout(INTERACTION_TIMEOUT_SECONDS);
thegink 0:8dc213146b30 86 Rotary rotary(ROTARY_PIN_A, ROTARY_PIN_B);
thegink 0:8dc213146b30 87 Rotary::Action action;
thegink 0:8dc213146b30 88 LEDs leds(LEDS_MAIN_STRIP_PIN, LEDS_SINGLE_STRIP_PIN);
thegink 0:8dc213146b30 89 Pulser standBySwitchPulser(STANDBY_BUTTON_LED_PIN);
thegink 0:8dc213146b30 90 EffectPlugs effectPlugs(4, effectsPins);
thegink 0:8dc213146b30 91 Effects effects(&leds);
thegink 0:8dc213146b30 92
thegink 0:8dc213146b30 93 DigitalIn StdbyButton(STANDBY_BUTTON_PIN, PullUp);
thegink 0:8dc213146b30 94 AnalogIn ainH(ANALOG_H_IN_PIN);
thegink 0:8dc213146b30 95 AnalogIn ainS(ANALOG_S_IN_PIN);
thegink 0:8dc213146b30 96 AnalogIn ainV(ANALOG_V_IN_PIN);
thegink 0:8dc213146b30 97 Serial pc(USBTX, USBRX);
thegink 0:8dc213146b30 98
thegink 0:8dc213146b30 99 void setup() {
thegink 0:8dc213146b30 100 DEBUG("INIT");
thegink 0:8dc213146b30 101
thegink 0:8dc213146b30 102 lastH = 0;
thegink 0:8dc213146b30 103 lastS = 0;
thegink 0:8dc213146b30 104 lastV = 0;
thegink 0:8dc213146b30 105 lastEffect = 0;
thegink 0:8dc213146b30 106 leds.off();
thegink 0:8dc213146b30 107 }
thegink 0:8dc213146b30 108
thegink 0:8dc213146b30 109 bool buttonPressed(uint8_t index) {
thegink 0:8dc213146b30 110 uint8_t state = buttons[index].read();
thegink 0:8dc213146b30 111 if (state == 0 && lastButtonState[index] == 1) {
thegink 0:8dc213146b30 112 lastButtonState[index] = 0;
thegink 0:8dc213146b30 113 return true;
thegink 0:8dc213146b30 114 };
thegink 0:8dc213146b30 115 lastButtonState[index] = state;
thegink 0:8dc213146b30 116 return false;
thegink 0:8dc213146b30 117 }
thegink 0:8dc213146b30 118
thegink 0:8dc213146b30 119 bool buttonDown(uint8_t index) {
thegink 0:8dc213146b30 120 uint8_t state = buttons[index].read();
thegink 0:8dc213146b30 121 return state == 0;
thegink 0:8dc213146b30 122 }
thegink 0:8dc213146b30 123
thegink 0:8dc213146b30 124 bool standByButtonPressed() {
thegink 0:8dc213146b30 125 static uint8_t lastState;
thegink 0:8dc213146b30 126 uint8_t state = StdbyButton.read();
thegink 0:8dc213146b30 127 if (state == 0 && lastState == 1) {
thegink 0:8dc213146b30 128 lastState = 0;
thegink 0:8dc213146b30 129 return true;
thegink 0:8dc213146b30 130 }
thegink 0:8dc213146b30 131 lastState = state;
thegink 0:8dc213146b30 132 return false;
thegink 0:8dc213146b30 133 }
thegink 0:8dc213146b30 134
thegink 0:8dc213146b30 135 void enterStandBy() {
thegink 0:8dc213146b30 136 standBySwitchPulser.off(); // Turn off pulser while writing LED state to EEPROM.
thegink 0:8dc213146b30 137 leds.saveStateToEEPROM();
thegink 0:8dc213146b30 138 leds.off();
thegink 0:8dc213146b30 139 standBy = true;
thegink 0:8dc213146b30 140 }
thegink 0:8dc213146b30 141
thegink 0:8dc213146b30 142 void leaveStandBy() {
thegink 0:8dc213146b30 143 leds.loadStateFromEEPROM();
thegink 0:8dc213146b30 144 standBySwitchPulser.steady();
thegink 0:8dc213146b30 145 standBy = false;
thegink 0:8dc213146b30 146 interactionTimeout.reset();
thegink 0:8dc213146b30 147 }
thegink 0:8dc213146b30 148
thegink 0:8dc213146b30 149 void dev_loop()
thegink 0:8dc213146b30 150 {
thegink 0:8dc213146b30 151 static uint8_t old_h = 0, old_s = 0, old_v = 0;
thegink 0:8dc213146b30 152
thegink 0:8dc213146b30 153 uint8_t h = ainH.read_u16() >> 8;
thegink 0:8dc213146b30 154 uint8_t s = ainS.read_u16() >> 8;
thegink 0:8dc213146b30 155 uint8_t v = ainV.read_u16() >> 8;
thegink 0:8dc213146b30 156
thegink 0:8dc213146b30 157 if (h != old_h)
thegink 0:8dc213146b30 158 {
thegink 0:8dc213146b30 159 DEBUG("\r\nH: %u", h);
thegink 0:8dc213146b30 160 old_h = h;
thegink 0:8dc213146b30 161 }
thegink 0:8dc213146b30 162
thegink 0:8dc213146b30 163 if (s != old_s)
thegink 0:8dc213146b30 164 {
thegink 0:8dc213146b30 165 DEBUG("\r\nS: %u", s);
thegink 0:8dc213146b30 166 old_s = s;
thegink 0:8dc213146b30 167 }
thegink 0:8dc213146b30 168
thegink 0:8dc213146b30 169 if (v != old_v)
thegink 0:8dc213146b30 170 {
thegink 0:8dc213146b30 171 DEBUG("\r\nV: %u", v);
thegink 0:8dc213146b30 172 old_v = v;
thegink 0:8dc213146b30 173 }
thegink 0:8dc213146b30 174
thegink 0:8dc213146b30 175
thegink 0:8dc213146b30 176 for (uint8_t i = 0; i < NUM_BUTTONS; i++)
thegink 0:8dc213146b30 177 {
thegink 0:8dc213146b30 178 if (buttonPressed(i))
thegink 0:8dc213146b30 179 {
thegink 0:8dc213146b30 180 DEBUG("\r\nButton %u Pressed", i);
thegink 0:8dc213146b30 181 }
thegink 0:8dc213146b30 182
thegink 0:8dc213146b30 183 if (buttonDown(i))
thegink 0:8dc213146b30 184 {
thegink 0:8dc213146b30 185 DEBUG("\r\nButton %u Down", i);
thegink 0:8dc213146b30 186 }
thegink 0:8dc213146b30 187 }
thegink 0:8dc213146b30 188
thegink 0:8dc213146b30 189 static uint8_t old_connection = 0;
thegink 0:8dc213146b30 190
thegink 0:8dc213146b30 191 uint8_t connection = effectPlugs.pluggedConnection();
thegink 0:8dc213146b30 192
thegink 0:8dc213146b30 193 if (connection != old_connection)
thegink 0:8dc213146b30 194 {
thegink 0:8dc213146b30 195 DEBUG("Connection %u made", connection);
thegink 0:8dc213146b30 196 old_connection = connection;
thegink 0:8dc213146b30 197 }
thegink 0:8dc213146b30 198
thegink 0:8dc213146b30 199 action = rotary.read();
thegink 0:8dc213146b30 200
thegink 0:8dc213146b30 201 if (action != Rotary::NONE)
thegink 0:8dc213146b30 202 {
thegink 0:8dc213146b30 203 DEBUG("Rotary action: %u", action);
thegink 0:8dc213146b30 204 }
thegink 0:8dc213146b30 205
thegink 0:8dc213146b30 206 static uint8_t hue = 0;
thegink 0:8dc213146b30 207
thegink 0:8dc213146b30 208 leds.updateSingleLED(hue++, 127, 127);
thegink 0:8dc213146b30 209 effects.doEffect(2, Rotary::NONE);
thegink 0:8dc213146b30 210
thegink 0:8dc213146b30 211 wait_ms(10);
thegink 0:8dc213146b30 212 }
thegink 0:8dc213146b30 213
thegink 0:8dc213146b30 214 void loop()
thegink 0:8dc213146b30 215 {
thegink 0:8dc213146b30 216 if (standBy)
thegink 0:8dc213146b30 217 {
thegink 0:8dc213146b30 218 standBySwitchPulser.pulse();
thegink 0:8dc213146b30 219
thegink 0:8dc213146b30 220 if (standByButtonPressed())
thegink 0:8dc213146b30 221 {
thegink 0:8dc213146b30 222 leaveStandBy();
thegink 0:8dc213146b30 223 return;
thegink 0:8dc213146b30 224 }
thegink 0:8dc213146b30 225
thegink 0:8dc213146b30 226 Rotary::Action act = rotary.read();
thegink 0:8dc213146b30 227
thegink 0:8dc213146b30 228 if ((act == Rotary::LEFT) || (act == Rotary::RIGHT))
thegink 0:8dc213146b30 229 {
thegink 0:8dc213146b30 230 leaveStandBy();
thegink 0:8dc213146b30 231 return;
thegink 0:8dc213146b30 232 }
thegink 0:8dc213146b30 233
thegink 0:8dc213146b30 234 for (uint8_t i = 0; i < NUM_BUTTONS; i++)
thegink 0:8dc213146b30 235 {
thegink 0:8dc213146b30 236 if (buttonPressed(i))
thegink 0:8dc213146b30 237 {
thegink 0:8dc213146b30 238 leaveStandBy();
thegink 0:8dc213146b30 239 return;
thegink 0:8dc213146b30 240 }
thegink 0:8dc213146b30 241 }
thegink 0:8dc213146b30 242
thegink 0:8dc213146b30 243 if (lastEffect != effectPlugs.pluggedConnection())
thegink 0:8dc213146b30 244 {
thegink 0:8dc213146b30 245 leaveStandBy();
thegink 0:8dc213146b30 246 return;
thegink 0:8dc213146b30 247 }
thegink 0:8dc213146b30 248 }
thegink 0:8dc213146b30 249 else
thegink 0:8dc213146b30 250 {
thegink 0:8dc213146b30 251 uint8_t h = ainH.read_u16() >> 8;
thegink 0:8dc213146b30 252 uint8_t s = (ainS.read_u16() >> 8);
thegink 0:8dc213146b30 253 uint8_t v = (ainV.read_u16() >> 8);
thegink 0:8dc213146b30 254 leds.updateSingleLED(h, mapS[s], mapV[v]);
thegink 0:8dc213146b30 255
thegink 0:8dc213146b30 256 if (abs(h - lastH) > 2 || abs(s - lastS) > 2 || abs(v - lastV) > 2)
thegink 0:8dc213146b30 257 {
thegink 0:8dc213146b30 258 interactionTimeout.reset();
thegink 0:8dc213146b30 259 lastH = h;
thegink 0:8dc213146b30 260 lastS = s;
thegink 0:8dc213146b30 261 lastV = v;
thegink 0:8dc213146b30 262 }
thegink 0:8dc213146b30 263
thegink 0:8dc213146b30 264 for (uint8_t i = 0; i < NUM_BUTTONS; i++)
thegink 0:8dc213146b30 265 {
thegink 0:8dc213146b30 266 if (buttonPressed(i))
thegink 0:8dc213146b30 267 buttonIsUpdatingLED[i] = !leds.isStripLEDOn(i);
thegink 0:8dc213146b30 268
thegink 0:8dc213146b30 269 if (buttonDown(i))
thegink 0:8dc213146b30 270 {
thegink 0:8dc213146b30 271 if (buttonIsUpdatingLED[i])
thegink 0:8dc213146b30 272 {
thegink 0:8dc213146b30 273 leds.updateStripLED(i, h, mapS[s], mapV[v]);
thegink 0:8dc213146b30 274 }
thegink 0:8dc213146b30 275 else
thegink 0:8dc213146b30 276 {
thegink 0:8dc213146b30 277 leds.turnOffStripLED(i);
thegink 0:8dc213146b30 278 }
thegink 0:8dc213146b30 279
thegink 0:8dc213146b30 280 interactionTimeout.reset();
thegink 0:8dc213146b30 281 }
thegink 0:8dc213146b30 282 }
thegink 0:8dc213146b30 283
thegink 0:8dc213146b30 284 uint8_t chosenEffect = effectPlugs.pluggedConnection();
thegink 0:8dc213146b30 285
thegink 0:8dc213146b30 286 if (lastEffect != chosenEffect)
thegink 0:8dc213146b30 287 {
thegink 0:8dc213146b30 288 lastEffect = chosenEffect;
thegink 0:8dc213146b30 289 }
thegink 0:8dc213146b30 290
thegink 0:8dc213146b30 291 action = rotary.read();
thegink 0:8dc213146b30 292 if (chosenEffect)
thegink 0:8dc213146b30 293 {
thegink 0:8dc213146b30 294 effects.doEffect(chosenEffect, action);
thegink 0:8dc213146b30 295 }
thegink 0:8dc213146b30 296 else
thegink 0:8dc213146b30 297 {
thegink 0:8dc213146b30 298 effects.noEffect();
thegink 0:8dc213146b30 299 switch (action)
thegink 0:8dc213146b30 300 {
thegink 0:8dc213146b30 301 case Rotary::LEFT:
thegink 0:8dc213146b30 302 leds.scrollStripToLeft();
thegink 0:8dc213146b30 303 break;
thegink 0:8dc213146b30 304
thegink 0:8dc213146b30 305 case Rotary::RIGHT:
thegink 0:8dc213146b30 306 leds.scrollStripToRight();
thegink 0:8dc213146b30 307 break;
thegink 0:8dc213146b30 308
thegink 0:8dc213146b30 309 default:
thegink 0:8dc213146b30 310 break;
thegink 0:8dc213146b30 311 }
thegink 0:8dc213146b30 312 }
thegink 0:8dc213146b30 313
thegink 0:8dc213146b30 314 if (action != Rotary::NONE)
thegink 0:8dc213146b30 315 interactionTimeout.reset();
thegink 0:8dc213146b30 316
thegink 0:8dc213146b30 317 if (interactionTimeout.timedOut())
thegink 0:8dc213146b30 318 enterStandBy();
thegink 0:8dc213146b30 319 }
thegink 0:8dc213146b30 320 }
thegink 0:8dc213146b30 321
thegink 0:8dc213146b30 322 int main(void)
thegink 0:8dc213146b30 323 {
thegink 0:8dc213146b30 324 setup();
thegink 0:8dc213146b30 325
thegink 0:8dc213146b30 326 while (1)
thegink 0:8dc213146b30 327 {
thegink 0:8dc213146b30 328 #ifdef DEV
thegink 0:8dc213146b30 329 dev_loop();
thegink 0:8dc213146b30 330 #else
thegink 0:8dc213146b30 331 loop();
thegink 0:8dc213146b30 332 #endif
thegink 0:8dc213146b30 333 }
thegink 0:8dc213146b30 334
thegink 0:8dc213146b30 335 return 0;
thegink 0:8dc213146b30 336 }