Published
Dependencies: BLE_API TLC5955 mbed nRF51822
Fork of BLE_LoopbackUART by
sequencer.cpp@14:73923b07ae4a, 2018-06-09 (annotated)
- Committer:
- roysandberg
- Date:
- Sat Jun 09 23:23:06 2018 +0000
- Revision:
- 14:73923b07ae4a
Published
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
roysandberg | 14:73923b07ae4a | 1 | /* |
roysandberg | 14:73923b07ae4a | 2 | |
roysandberg | 14:73923b07ae4a | 3 | Control lighting sequences |
roysandberg | 14:73923b07ae4a | 4 | |
roysandberg | 14:73923b07ae4a | 5 | |
roysandberg | 14:73923b07ae4a | 6 | */ |
roysandberg | 14:73923b07ae4a | 7 | |
roysandberg | 14:73923b07ae4a | 8 | #include "TLC5955.h" |
roysandberg | 14:73923b07ae4a | 9 | #include <ctype.h> |
roysandberg | 14:73923b07ae4a | 10 | #include "sequencer.h" |
roysandberg | 14:73923b07ae4a | 11 | #include "color.h" |
roysandberg | 14:73923b07ae4a | 12 | |
roysandberg | 14:73923b07ae4a | 13 | DigitalOut led1(LED1); |
roysandberg | 14:73923b07ae4a | 14 | |
roysandberg | 14:73923b07ae4a | 15 | // zero-based time, starts at 7:30PM |
roysandberg | 14:73923b07ae4a | 16 | volatile uint32_t TheElapsedTime = (1000*60*60*6) + (1000*60*30); |
roysandberg | 14:73923b07ae4a | 17 | |
roysandberg | 14:73923b07ae4a | 18 | |
roysandberg | 14:73923b07ae4a | 19 | // THE FOLLOWING CHANNELS (ZERO-BASED) ARE BROKEN, AND ARE SKIPPED: |
roysandberg | 14:73923b07ae4a | 20 | // 4,6,14, 35-46 |
roysandberg | 14:73923b07ae4a | 21 | |
roysandberg | 14:73923b07ae4a | 22 | |
roysandberg | 14:73923b07ae4a | 23 | // Each row address indivual panels starting at the front right panel and moving clockwise as viewed from below |
roysandberg | 14:73923b07ae4a | 24 | // These are the two middle (internal-use) channels: 12, 34 |
roysandberg | 14:73923b07ae4a | 25 | |
roysandberg | 14:73923b07ae4a | 26 | int PANELS[ROWS][COLUMNS] = { |
roysandberg | 14:73923b07ae4a | 27 | {0, 1, 2, 3, 5, 7} , // Lowest row of panels |
roysandberg | 14:73923b07ae4a | 28 | {8, 9, 10, 11, 13, 15} , |
roysandberg | 14:73923b07ae4a | 29 | {16, 17, 18, 19, 20, 21} , |
roysandberg | 14:73923b07ae4a | 30 | {22, 23, 24, 25, 26, 27} , |
roysandberg | 14:73923b07ae4a | 31 | {28, 29, 31, 32, 33, 34} // Highest row of panels |
roysandberg | 14:73923b07ae4a | 32 | }; |
roysandberg | 14:73923b07ae4a | 33 | |
roysandberg | 14:73923b07ae4a | 34 | //int PANELS[5][6] = { |
roysandberg | 14:73923b07ae4a | 35 | // {0, 1, 2, 3, 4, 5} , // Lowest row of panels |
roysandberg | 14:73923b07ae4a | 36 | // {6, 7, 8, 9, 10, 11} , |
roysandberg | 14:73923b07ae4a | 37 | // {12, 13, 14, 15, 16, 17} , |
roysandberg | 14:73923b07ae4a | 38 | // {18, 19, 20, 21, 22, 23} , |
roysandberg | 14:73923b07ae4a | 39 | // {24, 25, 26, 27, 28, 29} // Highest row of panels |
roysandberg | 14:73923b07ae4a | 40 | //}; |
roysandberg | 14:73923b07ae4a | 41 | |
roysandberg | 14:73923b07ae4a | 42 | int CHANNEL_MAPPING[] = { 8, 12, 9, 13, 14, 10, 15, 11, 7, 3, 6, 2, 1, 5, 0, 4 }; |
roysandberg | 14:73923b07ae4a | 43 | |
roysandberg | 14:73923b07ae4a | 44 | uint16_t debugRedOut[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 45 | uint16_t debugGreenOut[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 46 | uint16_t debugBlueOut[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 47 | |
roysandberg | 14:73923b07ae4a | 48 | volatile int channelColorSettings[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 49 | volatile int Settings[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 50 | volatile int channelColorPointer[2][NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 51 | volatile int randomBaseTimeOffset[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 52 | volatile int randomMovementTimeOffset[NUMBER_OF_PANELS]; |
roysandberg | 14:73923b07ae4a | 53 | |
roysandberg | 14:73923b07ae4a | 54 | volatile uint16_t UserAdjustableMovementInterval = 2000; |
roysandberg | 14:73923b07ae4a | 55 | |
roysandberg | 14:73923b07ae4a | 56 | extern TLC5955* theChip; |
roysandberg | 14:73923b07ae4a | 57 | |
roysandberg | 14:73923b07ae4a | 58 | volatile int TheBaseDitherMode; |
roysandberg | 14:73923b07ae4a | 59 | volatile int TheBaseEffectType; |
roysandberg | 14:73923b07ae4a | 60 | volatile int TheBaseTimeConstant; |
roysandberg | 14:73923b07ae4a | 61 | volatile uint32_t TheBaseEffectStartTime; |
roysandberg | 14:73923b07ae4a | 62 | const int* TheBaseColorList; |
roysandberg | 14:73923b07ae4a | 63 | |
roysandberg | 14:73923b07ae4a | 64 | volatile int TheMovementPosition; |
roysandberg | 14:73923b07ae4a | 65 | volatile int TheMoveEndPosition; |
roysandberg | 14:73923b07ae4a | 66 | volatile int TheMovementNumberOfLevels; |
roysandberg | 14:73923b07ae4a | 67 | volatile int NumberOfMovesSoFar; |
roysandberg | 14:73923b07ae4a | 68 | |
roysandberg | 14:73923b07ae4a | 69 | void (*TheMovementAddressModePtr)(int,const int*,int); |
roysandberg | 14:73923b07ae4a | 70 | |
roysandberg | 14:73923b07ae4a | 71 | volatile int TheMovementMode; |
roysandberg | 14:73923b07ae4a | 72 | volatile int TheDitherMode; |
roysandberg | 14:73923b07ae4a | 73 | volatile int TheMovementFill; |
roysandberg | 14:73923b07ae4a | 74 | volatile int TheEffectType; |
roysandberg | 14:73923b07ae4a | 75 | const int* TheColorList; |
roysandberg | 14:73923b07ae4a | 76 | volatile int TheTimeConstant; |
roysandberg | 14:73923b07ae4a | 77 | volatile int TheMoveTimeConstant; |
roysandberg | 14:73923b07ae4a | 78 | volatile uint32_t TheEffectStartTime; |
roysandberg | 14:73923b07ae4a | 79 | volatile int TheMode=1; // lighting effect mode. zero is off. |
roysandberg | 14:73923b07ae4a | 80 | volatile bool inMinuteEffect = FALSE; |
roysandberg | 14:73923b07ae4a | 81 | volatile bool inHourEffect = FALSE; |
roysandberg | 14:73923b07ae4a | 82 | |
roysandberg | 14:73923b07ae4a | 83 | // https://developer.mbed.org/questions/2886/Why-is-the-rand-function-not-the-least-b/ |
roysandberg | 14:73923b07ae4a | 84 | unsigned int m_z=12434,m_w=33254; |
roysandberg | 14:73923b07ae4a | 85 | unsigned int rnd() { |
roysandberg | 14:73923b07ae4a | 86 | m_z = 36969 * (m_z & 65535) + (m_z >>16); |
roysandberg | 14:73923b07ae4a | 87 | m_w = 18000 * (m_w & 65535) + (m_w >>16); |
roysandberg | 14:73923b07ae4a | 88 | return ((m_z <<16) + m_w); |
roysandberg | 14:73923b07ae4a | 89 | } |
roysandberg | 14:73923b07ae4a | 90 | |
roysandberg | 14:73923b07ae4a | 91 | void setMode(int mode) { |
roysandberg | 14:73923b07ae4a | 92 | TheMode = mode; |
roysandberg | 14:73923b07ae4a | 93 | } |
roysandberg | 14:73923b07ae4a | 94 | |
roysandberg | 14:73923b07ae4a | 95 | int getMode() { |
roysandberg | 14:73923b07ae4a | 96 | return TheMode; |
roysandberg | 14:73923b07ae4a | 97 | } |
roysandberg | 14:73923b07ae4a | 98 | |
roysandberg | 14:73923b07ae4a | 99 | |
roysandberg | 14:73923b07ae4a | 100 | int movementToEnum(char* input) { |
roysandberg | 14:73923b07ae4a | 101 | if (!strcmp(input,"v-")) { |
roysandberg | 14:73923b07ae4a | 102 | return VERTICAL_UP; |
roysandberg | 14:73923b07ae4a | 103 | } else if (!strcmp(input,"v+")) { |
roysandberg | 14:73923b07ae4a | 104 | return VERTICAL_DOWN; |
roysandberg | 14:73923b07ae4a | 105 | } else if (!strcmp(input,"h+")) { |
roysandberg | 14:73923b07ae4a | 106 | return HORIZONTAL_FORWARD; |
roysandberg | 14:73923b07ae4a | 107 | } else if (!strcmp(input,"h-")) { |
roysandberg | 14:73923b07ae4a | 108 | return HORIZONTAL_BACKWARDS; |
roysandberg | 14:73923b07ae4a | 109 | } else if (!strcmp(input,"r+")) { |
roysandberg | 14:73923b07ae4a | 110 | return RADIAL_CLOCKWISE; |
roysandberg | 14:73923b07ae4a | 111 | } else if (!strcmp(input,"r-")) { |
roysandberg | 14:73923b07ae4a | 112 | return RADIAL_COUNTERCLOCKWISE; |
roysandberg | 14:73923b07ae4a | 113 | } else if (!strcmp(input,"b+")) { |
roysandberg | 14:73923b07ae4a | 114 | return BARREL_CLOCKWISE; |
roysandberg | 14:73923b07ae4a | 115 | } else if (!strcmp(input,"b-")) { |
roysandberg | 14:73923b07ae4a | 116 | return BARREL_COUNTERCLOCKWISE; |
roysandberg | 14:73923b07ae4a | 117 | } else if (!strcmp(input,"al")) { |
roysandberg | 14:73923b07ae4a | 118 | return ALL; |
roysandberg | 14:73923b07ae4a | 119 | } else if (!strcmp(input,"of")) { |
roysandberg | 14:73923b07ae4a | 120 | return OFF; |
roysandberg | 14:73923b07ae4a | 121 | } else { |
roysandberg | 14:73923b07ae4a | 122 | return -1; |
roysandberg | 14:73923b07ae4a | 123 | } |
roysandberg | 14:73923b07ae4a | 124 | } |
roysandberg | 14:73923b07ae4a | 125 | |
roysandberg | 14:73923b07ae4a | 126 | int ditherToEnum(char* input) { |
roysandberg | 14:73923b07ae4a | 127 | if (!strcmp(input,"f")) { |
roysandberg | 14:73923b07ae4a | 128 | return FIXED; |
roysandberg | 14:73923b07ae4a | 129 | } else if (!strcmp(input,"c")) { |
roysandberg | 14:73923b07ae4a | 130 | return CROSSFADE; |
roysandberg | 14:73923b07ae4a | 131 | } else if (!strcmp(input,"i")) { |
roysandberg | 14:73923b07ae4a | 132 | return FADE_IN; |
roysandberg | 14:73923b07ae4a | 133 | } else if (!strcmp(input,"o")) { |
roysandberg | 14:73923b07ae4a | 134 | return FADE_OUT_AND_IN; |
roysandberg | 14:73923b07ae4a | 135 | } else if (!strcmp(input,"s")) { |
roysandberg | 14:73923b07ae4a | 136 | return FADE_IN_AND_OUT; |
roysandberg | 14:73923b07ae4a | 137 | } else if (!strcmp(input,"p")) { |
roysandberg | 14:73923b07ae4a | 138 | return PULSED_INTENSITY; |
roysandberg | 14:73923b07ae4a | 139 | } else { |
roysandberg | 14:73923b07ae4a | 140 | return -1; |
roysandberg | 14:73923b07ae4a | 141 | } |
roysandberg | 14:73923b07ae4a | 142 | } |
roysandberg | 14:73923b07ae4a | 143 | |
roysandberg | 14:73923b07ae4a | 144 | int fillToEnum(char* input) { |
roysandberg | 14:73923b07ae4a | 145 | if (!strcmp(input,"l")) { |
roysandberg | 14:73923b07ae4a | 146 | return LINE; |
roysandberg | 14:73923b07ae4a | 147 | } else if (!strcmp(input,"f")) { |
roysandberg | 14:73923b07ae4a | 148 | return FILL; |
roysandberg | 14:73923b07ae4a | 149 | } else { |
roysandberg | 14:73923b07ae4a | 150 | return -1; |
roysandberg | 14:73923b07ae4a | 151 | } |
roysandberg | 14:73923b07ae4a | 152 | } |
roysandberg | 14:73923b07ae4a | 153 | |
roysandberg | 14:73923b07ae4a | 154 | int effectToEnum(char* input) { |
roysandberg | 14:73923b07ae4a | 155 | if (!strcmp(input,"c")) { |
roysandberg | 14:73923b07ae4a | 156 | return CONSTANT; |
roysandberg | 14:73923b07ae4a | 157 | } else if (!strcmp(input,"r")) { |
roysandberg | 14:73923b07ae4a | 158 | return RANDOM; |
roysandberg | 14:73923b07ae4a | 159 | } else if (!strcmp(input,"s")) { |
roysandberg | 14:73923b07ae4a | 160 | return SEQUENCE; |
roysandberg | 14:73923b07ae4a | 161 | } else if (!strcmp(input,"f")) { |
roysandberg | 14:73923b07ae4a | 162 | return FIXED_RANDOM; |
roysandberg | 14:73923b07ae4a | 163 | } else { |
roysandberg | 14:73923b07ae4a | 164 | return -1; |
roysandberg | 14:73923b07ae4a | 165 | } |
roysandberg | 14:73923b07ae4a | 166 | } |
roysandberg | 14:73923b07ae4a | 167 | |
roysandberg | 14:73923b07ae4a | 168 | // only compare first two characters. The rest are unused. |
roysandberg | 14:73923b07ae4a | 169 | const int* colorListToPointer(char* input) { |
roysandberg | 14:73923b07ae4a | 170 | char shortInput[3] ; |
roysandberg | 14:73923b07ae4a | 171 | shortInput[0] = input[0]; |
roysandberg | 14:73923b07ae4a | 172 | shortInput[1] = input[1]; |
roysandberg | 14:73923b07ae4a | 173 | shortInput[2] = 0; |
roysandberg | 14:73923b07ae4a | 174 | for (int i=0; i< USER_COLOR_CHOICES_SIZE; i++) { |
roysandberg | 14:73923b07ae4a | 175 | char shortColor[3]; |
roysandberg | 14:73923b07ae4a | 176 | shortColor[0] = listOfColorLists[i].colorListName[0]; |
roysandberg | 14:73923b07ae4a | 177 | shortColor[1] = listOfColorLists[i].colorListName[1]; |
roysandberg | 14:73923b07ae4a | 178 | shortColor[2] = 0; |
roysandberg | 14:73923b07ae4a | 179 | if (!strcmp (shortColor, shortInput)) { |
roysandberg | 14:73923b07ae4a | 180 | return listOfColorLists[i].colorList; |
roysandberg | 14:73923b07ae4a | 181 | } |
roysandberg | 14:73923b07ae4a | 182 | } |
roysandberg | 14:73923b07ae4a | 183 | return NULL; |
roysandberg | 14:73923b07ae4a | 184 | } |
roysandberg | 14:73923b07ae4a | 185 | |
roysandberg | 14:73923b07ae4a | 186 | // The channels on the board are numbered differently than the channels in software, so this corrects for it |
roysandberg | 14:73923b07ae4a | 187 | int channelMapping(int channel) { |
roysandberg | 14:73923b07ae4a | 188 | int valueToMap = channel % 16; |
roysandberg | 14:73923b07ae4a | 189 | int channelOffset = channel / 16; |
roysandberg | 14:73923b07ae4a | 190 | return (channelOffset*16) + CHANNEL_MAPPING[valueToMap]; |
roysandberg | 14:73923b07ae4a | 191 | } |
roysandberg | 14:73923b07ae4a | 192 | |
roysandberg | 14:73923b07ae4a | 193 | int getColorArraySize(const int* colorArray) { |
roysandberg | 14:73923b07ae4a | 194 | int i=0; |
roysandberg | 14:73923b07ae4a | 195 | while (colorArray[i] != -1) { |
roysandberg | 14:73923b07ae4a | 196 | i++; |
roysandberg | 14:73923b07ae4a | 197 | } |
roysandberg | 14:73923b07ae4a | 198 | return i; |
roysandberg | 14:73923b07ae4a | 199 | } |
roysandberg | 14:73923b07ae4a | 200 | |
roysandberg | 14:73923b07ae4a | 201 | int pickRandomColorFromArray(const int* colorArray) { |
roysandberg | 14:73923b07ae4a | 202 | int n = getColorArraySize(colorArray); |
roysandberg | 14:73923b07ae4a | 203 | int random = colorArray[rnd() % n]; |
roysandberg | 14:73923b07ae4a | 204 | //printf("n=%d, s=%d, r=%d\n\r",n, rnd(), random); |
roysandberg | 14:73923b07ae4a | 205 | return random; |
roysandberg | 14:73923b07ae4a | 206 | } |
roysandberg | 14:73923b07ae4a | 207 | |
roysandberg | 14:73923b07ae4a | 208 | void setArrayColor(int panel, int color, bool isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 209 | channelColorPointer[isBaseEffect][panel] = color; |
roysandberg | 14:73923b07ae4a | 210 | } |
roysandberg | 14:73923b07ae4a | 211 | |
roysandberg | 14:73923b07ae4a | 212 | int getArrayColor(int panel, bool isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 213 | return channelColorPointer[isBaseEffect][panel]; |
roysandberg | 14:73923b07ae4a | 214 | } |
roysandberg | 14:73923b07ae4a | 215 | |
roysandberg | 14:73923b07ae4a | 216 | int pickNextColorFromArray(int panel, const int* colorArray, bool isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 217 | channelColorPointer[isBaseEffect][panel]++; |
roysandberg | 14:73923b07ae4a | 218 | int n = getColorArraySize(colorArray); |
roysandberg | 14:73923b07ae4a | 219 | channelColorPointer[isBaseEffect][panel] = channelColorPointer[isBaseEffect][panel] % n; |
roysandberg | 14:73923b07ae4a | 220 | return colorArray[channelColorPointer[isBaseEffect][panel]]; |
roysandberg | 14:73923b07ae4a | 221 | } |
roysandberg | 14:73923b07ae4a | 222 | |
roysandberg | 14:73923b07ae4a | 223 | void setChannelToColorName(int channel, int colorName) { |
roysandberg | 14:73923b07ae4a | 224 | debugRedOut[channel] = color_data[colorName].rgb.r; |
roysandberg | 14:73923b07ae4a | 225 | debugGreenOut[channel] = color_data[colorName].rgb.g; |
roysandberg | 14:73923b07ae4a | 226 | debugBlueOut[channel] = color_data[colorName].rgb.b; |
roysandberg | 14:73923b07ae4a | 227 | |
roysandberg | 14:73923b07ae4a | 228 | channel = channelMapping(channel); |
roysandberg | 14:73923b07ae4a | 229 | theChip->setChannel(channel, |
roysandberg | 14:73923b07ae4a | 230 | color_data[colorName].rgb.r, |
roysandberg | 14:73923b07ae4a | 231 | color_data[colorName].rgb.g, |
roysandberg | 14:73923b07ae4a | 232 | color_data[colorName].rgb.b); |
roysandberg | 14:73923b07ae4a | 233 | } |
roysandberg | 14:73923b07ae4a | 234 | |
roysandberg | 14:73923b07ae4a | 235 | // 8 bit r,g,b for 24 bit color |
roysandberg | 14:73923b07ae4a | 236 | void setChannelToRGB(int channel, uint16_t r, uint16_t g, uint16_t b) { |
roysandberg | 14:73923b07ae4a | 237 | |
roysandberg | 14:73923b07ae4a | 238 | debugRedOut[channel] = r; |
roysandberg | 14:73923b07ae4a | 239 | debugGreenOut[channel] = g; |
roysandberg | 14:73923b07ae4a | 240 | debugBlueOut[channel] = b; |
roysandberg | 14:73923b07ae4a | 241 | |
roysandberg | 14:73923b07ae4a | 242 | channel = channelMapping(channel); |
roysandberg | 14:73923b07ae4a | 243 | theChip->setChannel(channel,r,g,b); |
roysandberg | 14:73923b07ae4a | 244 | } |
roysandberg | 14:73923b07ae4a | 245 | |
roysandberg | 14:73923b07ae4a | 246 | void setStartingMovePosition() { |
roysandberg | 14:73923b07ae4a | 247 | switch(TheMovementMode) { |
roysandberg | 14:73923b07ae4a | 248 | case VERTICAL_UP: |
roysandberg | 14:73923b07ae4a | 249 | TheMovementPosition=-1; |
roysandberg | 14:73923b07ae4a | 250 | TheMoveEndPosition=4; |
roysandberg | 14:73923b07ae4a | 251 | break; |
roysandberg | 14:73923b07ae4a | 252 | case VERTICAL_DOWN: |
roysandberg | 14:73923b07ae4a | 253 | TheMovementPosition=5; |
roysandberg | 14:73923b07ae4a | 254 | TheMoveEndPosition=0; |
roysandberg | 14:73923b07ae4a | 255 | break; |
roysandberg | 14:73923b07ae4a | 256 | case HORIZONTAL_FORWARD: |
roysandberg | 14:73923b07ae4a | 257 | TheMovementPosition=-1; |
roysandberg | 14:73923b07ae4a | 258 | TheMoveEndPosition=2; |
roysandberg | 14:73923b07ae4a | 259 | break; |
roysandberg | 14:73923b07ae4a | 260 | case HORIZONTAL_BACKWARDS: |
roysandberg | 14:73923b07ae4a | 261 | TheMovementPosition=3; |
roysandberg | 14:73923b07ae4a | 262 | TheMoveEndPosition=0; |
roysandberg | 14:73923b07ae4a | 263 | break; |
roysandberg | 14:73923b07ae4a | 264 | case RADIAL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 265 | TheMovementPosition=-1; |
roysandberg | 14:73923b07ae4a | 266 | TheMoveEndPosition=5; |
roysandberg | 14:73923b07ae4a | 267 | |
roysandberg | 14:73923b07ae4a | 268 | break; |
roysandberg | 14:73923b07ae4a | 269 | case RADIAL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 270 | TheMovementPosition=6; |
roysandberg | 14:73923b07ae4a | 271 | TheMoveEndPosition=0; |
roysandberg | 14:73923b07ae4a | 272 | break; |
roysandberg | 14:73923b07ae4a | 273 | case BARREL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 274 | TheMovementPosition=-1; |
roysandberg | 14:73923b07ae4a | 275 | TheMoveEndPosition=9; |
roysandberg | 14:73923b07ae4a | 276 | break; |
roysandberg | 14:73923b07ae4a | 277 | case BARREL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 278 | TheMovementPosition=10; |
roysandberg | 14:73923b07ae4a | 279 | TheMoveEndPosition=0; |
roysandberg | 14:73923b07ae4a | 280 | break; |
roysandberg | 14:73923b07ae4a | 281 | case ALL: |
roysandberg | 14:73923b07ae4a | 282 | case OFF: |
roysandberg | 14:73923b07ae4a | 283 | TheMovementPosition=-1; |
roysandberg | 14:73923b07ae4a | 284 | TheMoveEndPosition=2; |
roysandberg | 14:73923b07ae4a | 285 | default: |
roysandberg | 14:73923b07ae4a | 286 | break; |
roysandberg | 14:73923b07ae4a | 287 | } |
roysandberg | 14:73923b07ae4a | 288 | } |
roysandberg | 14:73923b07ae4a | 289 | |
roysandberg | 14:73923b07ae4a | 290 | void setPanelTargetColor(int channel, int aColor) { |
roysandberg | 14:73923b07ae4a | 291 | channelColorSettings[channel] = aColor; |
roysandberg | 14:73923b07ae4a | 292 | } |
roysandberg | 14:73923b07ae4a | 293 | |
roysandberg | 14:73923b07ae4a | 294 | int getPanelTargetColor(int channel) { |
roysandberg | 14:73923b07ae4a | 295 | return channelColorSettings[channel]; |
roysandberg | 14:73923b07ae4a | 296 | } |
roysandberg | 14:73923b07ae4a | 297 | |
roysandberg | 14:73923b07ae4a | 298 | void setPanelStartingColor(int channel, int aColor) { |
roysandberg | 14:73923b07ae4a | 299 | Settings[channel] = aColor; |
roysandberg | 14:73923b07ae4a | 300 | } |
roysandberg | 14:73923b07ae4a | 301 | |
roysandberg | 14:73923b07ae4a | 302 | int getPanelStartingColor(int channel) { |
roysandberg | 14:73923b07ae4a | 303 | return Settings[channel]; |
roysandberg | 14:73923b07ae4a | 304 | } |
roysandberg | 14:73923b07ae4a | 305 | |
roysandberg | 14:73923b07ae4a | 306 | |
roysandberg | 14:73923b07ae4a | 307 | const char* getNameFromColorNumber(int color) { |
roysandberg | 14:73923b07ae4a | 308 | return color_data[color].name; |
roysandberg | 14:73923b07ae4a | 309 | } |
roysandberg | 14:73923b07ae4a | 310 | |
roysandberg | 14:73923b07ae4a | 311 | |
roysandberg | 14:73923b07ae4a | 312 | void setBaseEffect( int ditherMode, int effectType, const int* colorList, int timeConstant ) { |
roysandberg | 14:73923b07ae4a | 313 | TheBaseDitherMode = ditherMode; |
roysandberg | 14:73923b07ae4a | 314 | TheBaseEffectType = effectType; |
roysandberg | 14:73923b07ae4a | 315 | TheBaseColorList = colorList; |
roysandberg | 14:73923b07ae4a | 316 | TheBaseTimeConstant = timeConstant; // controls internal fades, blinking, etc. |
roysandberg | 14:73923b07ae4a | 317 | TheBaseEffectStartTime = TheElapsedTime; |
roysandberg | 14:73923b07ae4a | 318 | |
roysandberg | 14:73923b07ae4a | 319 | //printf ("New Base Effect. t=%d:%d dither=%d, effect=%d, firstColor=%s, timeConstant=%d\n\r", |
roysandberg | 14:73923b07ae4a | 320 | //(TheElapsedTime/(1000*60*60))+1, (TheElapsedTime%(1000*60*60))/(60*1000), |
roysandberg | 14:73923b07ae4a | 321 | //ditherMode, effectType, getNameFromColorNumber(colorList[0]), timeConstant); |
roysandberg | 14:73923b07ae4a | 322 | |
roysandberg | 14:73923b07ae4a | 323 | if (TheBaseEffectType == CONSTANT) { |
roysandberg | 14:73923b07ae4a | 324 | // set all panels to a randomly selected color |
roysandberg | 14:73923b07ae4a | 325 | int theColor = pickRandomColorFromArray(colorList); |
roysandberg | 14:73923b07ae4a | 326 | //printf ("Using constant base color=(%d), %s\n\r", theColor, getNameFromColorNumber(theColor)); |
roysandberg | 14:73923b07ae4a | 327 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 328 | setPanelStartingColor(i, getPanelTargetColor(i)); |
roysandberg | 14:73923b07ae4a | 329 | setArrayColor(i, theColor,1); |
roysandberg | 14:73923b07ae4a | 330 | } |
roysandberg | 14:73923b07ae4a | 331 | } else if (TheBaseEffectType == FIXED_RANDOM) { |
roysandberg | 14:73923b07ae4a | 332 | // set each panel to a randomly selected color that doesn't change for the duration of the effect |
roysandberg | 14:73923b07ae4a | 333 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 334 | setPanelStartingColor(i, getPanelTargetColor(i)); |
roysandberg | 14:73923b07ae4a | 335 | setArrayColor(i, pickRandomColorFromArray(colorList),1); |
roysandberg | 14:73923b07ae4a | 336 | } |
roysandberg | 14:73923b07ae4a | 337 | } |
roysandberg | 14:73923b07ae4a | 338 | |
roysandberg | 14:73923b07ae4a | 339 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 340 | randomBaseTimeOffset[i] = rnd() % TheBaseTimeConstant/2; |
roysandberg | 14:73923b07ae4a | 341 | } |
roysandberg | 14:73923b07ae4a | 342 | } |
roysandberg | 14:73923b07ae4a | 343 | |
roysandberg | 14:73923b07ae4a | 344 | |
roysandberg | 14:73923b07ae4a | 345 | void setOverlayEffect( int movementMode, int ditherMode, int movementFill, int effectType, const int* colorList, int timeConstant, int moveTimeConstant ) { |
roysandberg | 14:73923b07ae4a | 346 | TheMovementMode = movementMode; |
roysandberg | 14:73923b07ae4a | 347 | TheDitherMode = ditherMode; |
roysandberg | 14:73923b07ae4a | 348 | TheMovementFill = movementFill; |
roysandberg | 14:73923b07ae4a | 349 | TheEffectType = effectType; |
roysandberg | 14:73923b07ae4a | 350 | TheColorList = colorList; |
roysandberg | 14:73923b07ae4a | 351 | TheTimeConstant = timeConstant; // controls internal fades, blinking, etc. |
roysandberg | 14:73923b07ae4a | 352 | TheMoveTimeConstant = moveTimeConstant; |
roysandberg | 14:73923b07ae4a | 353 | TheEffectStartTime = TheElapsedTime; |
roysandberg | 14:73923b07ae4a | 354 | NumberOfMovesSoFar = 0; |
roysandberg | 14:73923b07ae4a | 355 | setStartingMovePosition(); |
roysandberg | 14:73923b07ae4a | 356 | //printf ("New Movement Effect. move=%d, dither=%d, effect=%d, firstColor=%s, timeConstant=%d\n\r", |
roysandberg | 14:73923b07ae4a | 357 | //movementMode, ditherMode, effectType, getNameFromColorNumber(colorList[0]), timeConstant); |
roysandberg | 14:73923b07ae4a | 358 | |
roysandberg | 14:73923b07ae4a | 359 | if (TheEffectType == CONSTANT) { |
roysandberg | 14:73923b07ae4a | 360 | // set all panels to a randomly selected color |
roysandberg | 14:73923b07ae4a | 361 | int theColor = pickRandomColorFromArray(colorList); |
roysandberg | 14:73923b07ae4a | 362 | //printf ("Using constant overlay color=(%d), %s\n\r", theColor, getNameFromColorNumber(theColor)); |
roysandberg | 14:73923b07ae4a | 363 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 364 | setPanelStartingColor(i, getPanelTargetColor(i)); |
roysandberg | 14:73923b07ae4a | 365 | setArrayColor(i, theColor,0); |
roysandberg | 14:73923b07ae4a | 366 | } |
roysandberg | 14:73923b07ae4a | 367 | } else if (TheEffectType == FIXED_RANDOM) { |
roysandberg | 14:73923b07ae4a | 368 | // set each panel to a randomly selected color that doesn't change for the duration of the effect |
roysandberg | 14:73923b07ae4a | 369 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 370 | setPanelStartingColor(i, getPanelTargetColor(i)); |
roysandberg | 14:73923b07ae4a | 371 | setArrayColor(i, pickRandomColorFromArray(colorList),0); |
roysandberg | 14:73923b07ae4a | 372 | } |
roysandberg | 14:73923b07ae4a | 373 | } |
roysandberg | 14:73923b07ae4a | 374 | for (int i=0; i< NUMBER_OF_PANELS; i++) { |
roysandberg | 14:73923b07ae4a | 375 | randomMovementTimeOffset[i] = rnd() % TheTimeConstant/2; |
roysandberg | 14:73923b07ae4a | 376 | } |
roysandberg | 14:73923b07ae4a | 377 | } |
roysandberg | 14:73923b07ae4a | 378 | |
roysandberg | 14:73923b07ae4a | 379 | inline void crossFade(int startingR, int startingG, int startingB, int endingR, int endingG, int endingB, uint32_t timeConstant, uint32_t currentTime, uint16_t* r, uint16_t* g, uint16_t* b) { |
roysandberg | 14:73923b07ae4a | 380 | currentTime = currentTime % timeConstant; |
roysandberg | 14:73923b07ae4a | 381 | |
roysandberg | 14:73923b07ae4a | 382 | //printf("crossFrade current=%d, total=%d\n\r", currentTime, timeConstant); |
roysandberg | 14:73923b07ae4a | 383 | |
roysandberg | 14:73923b07ae4a | 384 | //if (currentTime > timeConstant) currentTime = timeConstant; |
roysandberg | 14:73923b07ae4a | 385 | |
roysandberg | 14:73923b07ae4a | 386 | *r = (uint16_t) ((((uint32_t)startingR * (uint32_t)(timeConstant - currentTime)) + ( (uint32_t)endingR * (uint32_t) currentTime)) / ((uint32_t) timeConstant)); |
roysandberg | 14:73923b07ae4a | 387 | *g = (uint16_t) ((((uint32_t)startingG * (uint32_t)(timeConstant - currentTime)) + ( (uint32_t)endingG * (uint32_t) currentTime)) / ((uint32_t) timeConstant)); |
roysandberg | 14:73923b07ae4a | 388 | *b = (uint16_t) ((((uint32_t)startingB * (uint32_t)(timeConstant - currentTime)) + ( (uint32_t)endingB * (uint32_t) currentTime)) / ((uint32_t) timeConstant)); |
roysandberg | 14:73923b07ae4a | 389 | |
roysandberg | 14:73923b07ae4a | 390 | //printf ("t=%d, c=%d, start=(%x,%x,%x), ending=(%x,%x,%x), now=%x,%x,%x\n\r", currentTime, timeConstant, startingR, startingG, startingB, endingR, endingG, endingB, *r, *b, *g ); |
roysandberg | 14:73923b07ae4a | 391 | //printf("s={%d,%d,%d}, e={%d,%d,%d}, c={%d,%d,%d}\n\r", startingR, startingG, startingB, endingR, endingG, endingB, *r, *g, *b); |
roysandberg | 14:73923b07ae4a | 392 | } |
roysandberg | 14:73923b07ae4a | 393 | |
roysandberg | 14:73923b07ae4a | 394 | inline void crossFade(int startingColor, int endingColor, uint32_t timeConstant, uint32_t currentTime, uint16_t* r, uint16_t* g, uint16_t* b) { |
roysandberg | 14:73923b07ae4a | 395 | int startingR, startingG, startingB; |
roysandberg | 14:73923b07ae4a | 396 | int endingR, endingG, endingB; |
roysandberg | 14:73923b07ae4a | 397 | |
roysandberg | 14:73923b07ae4a | 398 | startingR = color_data[startingColor].rgb.r; |
roysandberg | 14:73923b07ae4a | 399 | startingG = color_data[startingColor].rgb.g; |
roysandberg | 14:73923b07ae4a | 400 | startingB = color_data[startingColor].rgb.b; |
roysandberg | 14:73923b07ae4a | 401 | |
roysandberg | 14:73923b07ae4a | 402 | endingR = color_data[endingColor].rgb.r; |
roysandberg | 14:73923b07ae4a | 403 | endingG = color_data[endingColor].rgb.g; |
roysandberg | 14:73923b07ae4a | 404 | endingB = color_data[endingColor].rgb.b; |
roysandberg | 14:73923b07ae4a | 405 | |
roysandberg | 14:73923b07ae4a | 406 | crossFade(startingR, startingG, startingB, endingR, endingG, endingB, timeConstant, currentTime, r, g, b); |
roysandberg | 14:73923b07ae4a | 407 | } |
roysandberg | 14:73923b07ae4a | 408 | |
roysandberg | 14:73923b07ae4a | 409 | void manageDither(int totalTimeForEffect, int timeIntoEffect, int startingColor, int endingColor, int panel) { |
roysandberg | 14:73923b07ae4a | 410 | uint16_t r,g,b; |
roysandberg | 14:73923b07ae4a | 411 | |
roysandberg | 14:73923b07ae4a | 412 | switch (TheBaseDitherMode) { |
roysandberg | 14:73923b07ae4a | 413 | case FIXED: |
roysandberg | 14:73923b07ae4a | 414 | setChannelToColorName(panel, endingColor); |
roysandberg | 14:73923b07ae4a | 415 | break; |
roysandberg | 14:73923b07ae4a | 416 | case CROSSFADE: |
roysandberg | 14:73923b07ae4a | 417 | crossFade(startingColor, endingColor, totalTimeForEffect, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 418 | setChannelToRGB(panel,r,g,b); |
roysandberg | 14:73923b07ae4a | 419 | break; |
roysandberg | 14:73923b07ae4a | 420 | case FADE_IN: |
roysandberg | 14:73923b07ae4a | 421 | crossFade(COLOR_BLACK, endingColor, totalTimeForEffect, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 422 | setChannelToRGB(panel,r,g,b); |
roysandberg | 14:73923b07ae4a | 423 | break; |
roysandberg | 14:73923b07ae4a | 424 | case FADE_OUT_AND_IN: |
roysandberg | 14:73923b07ae4a | 425 | if (timeIntoEffect < totalTimeForEffect/2) { |
roysandberg | 14:73923b07ae4a | 426 | crossFade(startingColor, COLOR_BLACK, totalTimeForEffect/2, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 427 | } else { |
roysandberg | 14:73923b07ae4a | 428 | crossFade(COLOR_BLACK, endingColor, totalTimeForEffect/2, timeIntoEffect - (totalTimeForEffect/2), &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 429 | } |
roysandberg | 14:73923b07ae4a | 430 | setChannelToRGB(panel,r,g,b); |
roysandberg | 14:73923b07ae4a | 431 | break; |
roysandberg | 14:73923b07ae4a | 432 | case FADE_IN_AND_OUT: |
roysandberg | 14:73923b07ae4a | 433 | if (timeIntoEffect < totalTimeForEffect/2) { |
roysandberg | 14:73923b07ae4a | 434 | crossFade(COLOR_BLACK, endingColor, totalTimeForEffect/2, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 435 | } else { |
roysandberg | 14:73923b07ae4a | 436 | crossFade(endingColor, COLOR_BLACK, totalTimeForEffect/2, timeIntoEffect - (totalTimeForEffect/2), &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 437 | } |
roysandberg | 14:73923b07ae4a | 438 | setChannelToRGB(panel,r,g,b); |
roysandberg | 14:73923b07ae4a | 439 | break; |
roysandberg | 14:73923b07ae4a | 440 | case PULSED_INTENSITY: |
roysandberg | 14:73923b07ae4a | 441 | if (timeIntoEffect < totalTimeForEffect/2) { |
roysandberg | 14:73923b07ae4a | 442 | crossFade( color_data[endingColor].rgb.r/4, color_data[endingColor].rgb.g/4, color_data[endingColor].rgb.b/4, |
roysandberg | 14:73923b07ae4a | 443 | color_data[endingColor].rgb.r, color_data[endingColor].rgb.g, color_data[endingColor].rgb.b, |
roysandberg | 14:73923b07ae4a | 444 | totalTimeForEffect/2, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 445 | } else { |
roysandberg | 14:73923b07ae4a | 446 | crossFade( color_data[endingColor].rgb.r, color_data[endingColor].rgb.g, color_data[endingColor].rgb.b, |
roysandberg | 14:73923b07ae4a | 447 | color_data[endingColor].rgb.r/4, color_data[endingColor].rgb.g/4, color_data[endingColor].rgb.b/4, |
roysandberg | 14:73923b07ae4a | 448 | totalTimeForEffect/2, timeIntoEffect, &r, &g, &b); |
roysandberg | 14:73923b07ae4a | 449 | } |
roysandberg | 14:73923b07ae4a | 450 | setChannelToRGB(panel,r,g,b); |
roysandberg | 14:73923b07ae4a | 451 | break; |
roysandberg | 14:73923b07ae4a | 452 | default: |
roysandberg | 14:73923b07ae4a | 453 | break; |
roysandberg | 14:73923b07ae4a | 454 | } |
roysandberg | 14:73923b07ae4a | 455 | } |
roysandberg | 14:73923b07ae4a | 456 | |
roysandberg | 14:73923b07ae4a | 457 | |
roysandberg | 14:73923b07ae4a | 458 | int isTimeForNewColor(int timeConstant, int timeSoFar) { |
roysandberg | 14:73923b07ae4a | 459 | if (timeSoFar % timeConstant < CLOCK_GRANULARITY) { |
roysandberg | 14:73923b07ae4a | 460 | //printf("isTime! soFar=%d, c=%d\n\r", timeSoFar, timeConstant); |
roysandberg | 14:73923b07ae4a | 461 | return true; |
roysandberg | 14:73923b07ae4a | 462 | } else { |
roysandberg | 14:73923b07ae4a | 463 | return false; |
roysandberg | 14:73923b07ae4a | 464 | } |
roysandberg | 14:73923b07ae4a | 465 | } |
roysandberg | 14:73923b07ae4a | 466 | |
roysandberg | 14:73923b07ae4a | 467 | |
roysandberg | 14:73923b07ae4a | 468 | void manageEffectType(int panel, const int* colorList, int isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 469 | uint32_t startTime, timeConstant; |
roysandberg | 14:73923b07ae4a | 470 | int effectType; |
roysandberg | 14:73923b07ae4a | 471 | |
roysandberg | 14:73923b07ae4a | 472 | if (isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 473 | effectType = TheBaseEffectType; |
roysandberg | 14:73923b07ae4a | 474 | timeConstant = TheBaseTimeConstant - (effectType == RANDOM) ? randomBaseTimeOffset[panel] : 0; |
roysandberg | 14:73923b07ae4a | 475 | startTime = TheBaseEffectStartTime; |
roysandberg | 14:73923b07ae4a | 476 | } else { |
roysandberg | 14:73923b07ae4a | 477 | effectType = TheEffectType; |
roysandberg | 14:73923b07ae4a | 478 | timeConstant = TheTimeConstant - (effectType == RANDOM) ? randomMovementTimeOffset[panel] : 0; |
roysandberg | 14:73923b07ae4a | 479 | startTime = TheEffectStartTime; |
roysandberg | 14:73923b07ae4a | 480 | } |
roysandberg | 14:73923b07ae4a | 481 | |
roysandberg | 14:73923b07ae4a | 482 | |
roysandberg | 14:73923b07ae4a | 483 | |
roysandberg | 14:73923b07ae4a | 484 | switch (effectType) { |
roysandberg | 14:73923b07ae4a | 485 | case CONSTANT: |
roysandberg | 14:73923b07ae4a | 486 | case FIXED_RANDOM: |
roysandberg | 14:73923b07ae4a | 487 | // the colors are selected when the effect is first created |
roysandberg | 14:73923b07ae4a | 488 | setPanelStartingColor(panel, getArrayColor(panel, isBaseEffect)); |
roysandberg | 14:73923b07ae4a | 489 | setPanelTargetColor(panel, getArrayColor(panel, isBaseEffect)); |
roysandberg | 14:73923b07ae4a | 490 | break; |
roysandberg | 14:73923b07ae4a | 491 | case RANDOM: |
roysandberg | 14:73923b07ae4a | 492 | // TODO: Change to a random number that is picked so that the average length will be elapsed time. (probability at elapsedTime is 50% that it will be time) |
roysandberg | 14:73923b07ae4a | 493 | if (isTimeForNewColor(timeConstant, TheElapsedTime-startTime)) { |
roysandberg | 14:73923b07ae4a | 494 | setPanelStartingColor(panel, getPanelTargetColor(panel)); |
roysandberg | 14:73923b07ae4a | 495 | setPanelTargetColor(panel, pickRandomColorFromArray(colorList)); |
roysandberg | 14:73923b07ae4a | 496 | if (isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 497 | randomBaseTimeOffset[panel] = rnd() % TheBaseTimeConstant / 2; |
roysandberg | 14:73923b07ae4a | 498 | } else { |
roysandberg | 14:73923b07ae4a | 499 | randomMovementTimeOffset[panel] = rnd() % TheTimeConstant / 2; |
roysandberg | 14:73923b07ae4a | 500 | } |
roysandberg | 14:73923b07ae4a | 501 | } |
roysandberg | 14:73923b07ae4a | 502 | break; |
roysandberg | 14:73923b07ae4a | 503 | case SEQUENCE: |
roysandberg | 14:73923b07ae4a | 504 | if (isTimeForNewColor(timeConstant, TheElapsedTime-startTime)) { |
roysandberg | 14:73923b07ae4a | 505 | setPanelStartingColor(panel, getPanelTargetColor(panel)); |
roysandberg | 14:73923b07ae4a | 506 | int nextColor = pickNextColorFromArray(panel,colorList,isBaseEffect); |
roysandberg | 14:73923b07ae4a | 507 | setPanelTargetColor(panel, nextColor); |
roysandberg | 14:73923b07ae4a | 508 | } |
roysandberg | 14:73923b07ae4a | 509 | // Dither from old sequence color to new sequence color |
roysandberg | 14:73923b07ae4a | 510 | break; |
roysandberg | 14:73923b07ae4a | 511 | case RANDOM_STROBE: |
roysandberg | 14:73923b07ae4a | 512 | // fluctuate intensity randomly |
roysandberg | 14:73923b07ae4a | 513 | break; |
roysandberg | 14:73923b07ae4a | 514 | default: |
roysandberg | 14:73923b07ae4a | 515 | break; |
roysandberg | 14:73923b07ae4a | 516 | } |
roysandberg | 14:73923b07ae4a | 517 | manageDither(timeConstant, TheElapsedTime-startTime, getPanelStartingColor(panel), getPanelTargetColor(panel), panel); |
roysandberg | 14:73923b07ae4a | 518 | } |
roysandberg | 14:73923b07ae4a | 519 | |
roysandberg | 14:73923b07ae4a | 520 | // top-to-bottom - 5 levels |
roysandberg | 14:73923b07ae4a | 521 | void addressVertically (int location, const int* colorList, int isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 522 | if (location >= 0 && location < 5) { |
roysandberg | 14:73923b07ae4a | 523 | for (int i = 0; i < 6; i++) { |
roysandberg | 14:73923b07ae4a | 524 | manageEffectType(PANELS[location][i], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 525 | } |
roysandberg | 14:73923b07ae4a | 526 | } |
roysandberg | 14:73923b07ae4a | 527 | } |
roysandberg | 14:73923b07ae4a | 528 | |
roysandberg | 14:73923b07ae4a | 529 | // front-to-back - 3 levels |
roysandberg | 14:73923b07ae4a | 530 | void addressHorizontally (int location, const int* colorList, int isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 531 | if (location >= 0 && location < 3) { |
roysandberg | 14:73923b07ae4a | 532 | for (int i = 0; i < 5; i++) { |
roysandberg | 14:73923b07ae4a | 533 | manageEffectType(PANELS[i][location], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 534 | manageEffectType(PANELS[i][5-location], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 535 | } |
roysandberg | 14:73923b07ae4a | 536 | } |
roysandberg | 14:73923b07ae4a | 537 | } |
roysandberg | 14:73923b07ae4a | 538 | |
roysandberg | 14:73923b07ae4a | 539 | void addressHorizontalRadially (int location, const int* colorList, int isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 540 | if (location >= 0 && location < 6) { |
roysandberg | 14:73923b07ae4a | 541 | for (int i = 0; i < 5; i++) { |
roysandberg | 14:73923b07ae4a | 542 | manageEffectType(PANELS[i][location], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 543 | } |
roysandberg | 14:73923b07ae4a | 544 | } |
roysandberg | 14:73923b07ae4a | 545 | } |
roysandberg | 14:73923b07ae4a | 546 | |
roysandberg | 14:73923b07ae4a | 547 | void addressVerticallyRadially(int location, const int* colorList, int isBaseEffect) { |
roysandberg | 14:73923b07ae4a | 548 | if (location >= 0 && location < 5) { |
roysandberg | 14:73923b07ae4a | 549 | for (int i = 0; i < 3; i++) { |
roysandberg | 14:73923b07ae4a | 550 | manageEffectType(PANELS[location][i], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 551 | } |
roysandberg | 14:73923b07ae4a | 552 | } |
roysandberg | 14:73923b07ae4a | 553 | if (location >= 5 && location < 10) { |
roysandberg | 14:73923b07ae4a | 554 | for (int i = 3; i < 6; i++) { |
roysandberg | 14:73923b07ae4a | 555 | manageEffectType(PANELS[9-location][i], colorList, isBaseEffect); |
roysandberg | 14:73923b07ae4a | 556 | } |
roysandberg | 14:73923b07ae4a | 557 | } |
roysandberg | 14:73923b07ae4a | 558 | } |
roysandberg | 14:73923b07ae4a | 559 | |
roysandberg | 14:73923b07ae4a | 560 | int getMovementLevels(int aMovementMode) { |
roysandberg | 14:73923b07ae4a | 561 | switch (aMovementMode) { |
roysandberg | 14:73923b07ae4a | 562 | case VERTICAL_UP: |
roysandberg | 14:73923b07ae4a | 563 | return ROWS; |
roysandberg | 14:73923b07ae4a | 564 | case VERTICAL_DOWN: |
roysandberg | 14:73923b07ae4a | 565 | return ROWS; |
roysandberg | 14:73923b07ae4a | 566 | case HORIZONTAL_FORWARD: |
roysandberg | 14:73923b07ae4a | 567 | return 3; |
roysandberg | 14:73923b07ae4a | 568 | case HORIZONTAL_BACKWARDS: |
roysandberg | 14:73923b07ae4a | 569 | return 3; |
roysandberg | 14:73923b07ae4a | 570 | case RADIAL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 571 | return 6; |
roysandberg | 14:73923b07ae4a | 572 | case RADIAL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 573 | return 6; |
roysandberg | 14:73923b07ae4a | 574 | case BARREL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 575 | return 10; |
roysandberg | 14:73923b07ae4a | 576 | case BARREL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 577 | return 10; |
roysandberg | 14:73923b07ae4a | 578 | case ALL: |
roysandberg | 14:73923b07ae4a | 579 | return 1; |
roysandberg | 14:73923b07ae4a | 580 | case OFF: |
roysandberg | 14:73923b07ae4a | 581 | return 1; |
roysandberg | 14:73923b07ae4a | 582 | default: |
roysandberg | 14:73923b07ae4a | 583 | return 1; |
roysandberg | 14:73923b07ae4a | 584 | } |
roysandberg | 14:73923b07ae4a | 585 | } |
roysandberg | 14:73923b07ae4a | 586 | |
roysandberg | 14:73923b07ae4a | 587 | void manageMovement() { |
roysandberg | 14:73923b07ae4a | 588 | // Track which panels get painted with the Base information, and which get the effect information |
roysandberg | 14:73923b07ae4a | 589 | |
roysandberg | 14:73923b07ae4a | 590 | // cycle through moves at TheMoveTimeConstant rate |
roysandberg | 14:73923b07ae4a | 591 | //printf (">> t=%d, c=%d, %d <? %d\n\r", (TheElapsedTime-TheEffectStartTime), TheMoveTimeConstant, (TheElapsedTime-TheEffectStartTime) % TheMoveTimeConstant, CLOCK_GRANULARITY); |
roysandberg | 14:73923b07ae4a | 592 | |
roysandberg | 14:73923b07ae4a | 593 | if ((TheElapsedTime-TheEffectStartTime) % TheMoveTimeConstant < CLOCK_GRANULARITY) { |
roysandberg | 14:73923b07ae4a | 594 | //printf ("Moving. Mode=%d\n\r", TheMovementMode); |
roysandberg | 14:73923b07ae4a | 595 | switch(TheMovementMode) { |
roysandberg | 14:73923b07ae4a | 596 | case VERTICAL_UP: |
roysandberg | 14:73923b07ae4a | 597 | TheMovementPosition++; |
roysandberg | 14:73923b07ae4a | 598 | TheMovementNumberOfLevels = ROWS; |
roysandberg | 14:73923b07ae4a | 599 | TheMovementAddressModePtr = &addressVertically; |
roysandberg | 14:73923b07ae4a | 600 | break; |
roysandberg | 14:73923b07ae4a | 601 | case VERTICAL_DOWN: |
roysandberg | 14:73923b07ae4a | 602 | TheMovementPosition--; |
roysandberg | 14:73923b07ae4a | 603 | TheMovementNumberOfLevels = ROWS; |
roysandberg | 14:73923b07ae4a | 604 | TheMovementAddressModePtr = &addressVertically; |
roysandberg | 14:73923b07ae4a | 605 | break; |
roysandberg | 14:73923b07ae4a | 606 | case HORIZONTAL_FORWARD: |
roysandberg | 14:73923b07ae4a | 607 | TheMovementPosition++; |
roysandberg | 14:73923b07ae4a | 608 | TheMovementNumberOfLevels = 3; |
roysandberg | 14:73923b07ae4a | 609 | TheMovementAddressModePtr = &addressHorizontally; |
roysandberg | 14:73923b07ae4a | 610 | break; |
roysandberg | 14:73923b07ae4a | 611 | case HORIZONTAL_BACKWARDS: |
roysandberg | 14:73923b07ae4a | 612 | TheMovementPosition--; |
roysandberg | 14:73923b07ae4a | 613 | TheMovementNumberOfLevels = 3; |
roysandberg | 14:73923b07ae4a | 614 | TheMovementAddressModePtr = &addressHorizontally; |
roysandberg | 14:73923b07ae4a | 615 | break; |
roysandberg | 14:73923b07ae4a | 616 | case RADIAL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 617 | TheMovementNumberOfLevels = 6; |
roysandberg | 14:73923b07ae4a | 618 | TheMovementPosition++; |
roysandberg | 14:73923b07ae4a | 619 | TheMovementAddressModePtr = &addressHorizontalRadially; |
roysandberg | 14:73923b07ae4a | 620 | break; |
roysandberg | 14:73923b07ae4a | 621 | case RADIAL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 622 | TheMovementNumberOfLevels = 6; |
roysandberg | 14:73923b07ae4a | 623 | TheMovementPosition--; |
roysandberg | 14:73923b07ae4a | 624 | TheMovementAddressModePtr = &addressHorizontalRadially; |
roysandberg | 14:73923b07ae4a | 625 | break; |
roysandberg | 14:73923b07ae4a | 626 | case BARREL_CLOCKWISE: |
roysandberg | 14:73923b07ae4a | 627 | TheMovementPosition++; |
roysandberg | 14:73923b07ae4a | 628 | TheMovementNumberOfLevels = 10; |
roysandberg | 14:73923b07ae4a | 629 | TheMovementAddressModePtr = &addressVerticallyRadially; |
roysandberg | 14:73923b07ae4a | 630 | break; |
roysandberg | 14:73923b07ae4a | 631 | case BARREL_COUNTERCLOCKWISE: |
roysandberg | 14:73923b07ae4a | 632 | TheMovementPosition--; |
roysandberg | 14:73923b07ae4a | 633 | TheMovementNumberOfLevels = 10; |
roysandberg | 14:73923b07ae4a | 634 | TheMovementAddressModePtr = &addressVerticallyRadially; |
roysandberg | 14:73923b07ae4a | 635 | break; |
roysandberg | 14:73923b07ae4a | 636 | case ALL: |
roysandberg | 14:73923b07ae4a | 637 | TheMovementPosition = 0; |
roysandberg | 14:73923b07ae4a | 638 | TheMovementNumberOfLevels = 3; |
roysandberg | 14:73923b07ae4a | 639 | TheMovementAddressModePtr = &addressHorizontally; |
roysandberg | 14:73923b07ae4a | 640 | break; |
roysandberg | 14:73923b07ae4a | 641 | case OFF: |
roysandberg | 14:73923b07ae4a | 642 | TheMovementPosition = 0; |
roysandberg | 14:73923b07ae4a | 643 | TheMovementNumberOfLevels = 3; |
roysandberg | 14:73923b07ae4a | 644 | TheMovementAddressModePtr = &addressHorizontally; |
roysandberg | 14:73923b07ae4a | 645 | break; |
roysandberg | 14:73923b07ae4a | 646 | default: |
roysandberg | 14:73923b07ae4a | 647 | break; |
roysandberg | 14:73923b07ae4a | 648 | } |
roysandberg | 14:73923b07ae4a | 649 | if (TheMovementMode != OFF) { |
roysandberg | 14:73923b07ae4a | 650 | NumberOfMovesSoFar++; |
roysandberg | 14:73923b07ae4a | 651 | //printf ("Incrementing moves to: %d\n\r", NumberOfMovesSoFar); |
roysandberg | 14:73923b07ae4a | 652 | } |
roysandberg | 14:73923b07ae4a | 653 | } |
roysandberg | 14:73923b07ae4a | 654 | // end the move after it has reached its end |
roysandberg | 14:73923b07ae4a | 655 | if (NumberOfMovesSoFar > TheMovementNumberOfLevels) { |
roysandberg | 14:73923b07ae4a | 656 | //printf ("TURNING MOVE OFF.\n\r"); |
roysandberg | 14:73923b07ae4a | 657 | TheMovementMode = OFF; |
roysandberg | 14:73923b07ae4a | 658 | NumberOfMovesSoFar = 0; |
roysandberg | 14:73923b07ae4a | 659 | } |
roysandberg | 14:73923b07ae4a | 660 | |
roysandberg | 14:73923b07ae4a | 661 | if (TheMovementPosition < 0) TheMovementPosition = TheMovementNumberOfLevels-1; |
roysandberg | 14:73923b07ae4a | 662 | TheMovementPosition = TheMovementPosition % TheMovementNumberOfLevels; |
roysandberg | 14:73923b07ae4a | 663 | |
roysandberg | 14:73923b07ae4a | 664 | |
roysandberg | 14:73923b07ae4a | 665 | //printf("mode=%d, pos=%d, levels=%d, numMoves=%d\n\r",TheMovementMode, TheMovementPosition, TheMovementNumberOfLevels, NumberOfMovesSoFar); |
roysandberg | 14:73923b07ae4a | 666 | |
roysandberg | 14:73923b07ae4a | 667 | // paint all the subeffects at 40Hz (or whatever the refresh rate is) |
roysandberg | 14:73923b07ae4a | 668 | for (int i=0; i < TheMovementNumberOfLevels; i++) { |
roysandberg | 14:73923b07ae4a | 669 | if (TheMovementMode != OFF && (i < TheMovementPosition && TheMovementFill == FILL || (TheMovementMode == ALL))) { |
roysandberg | 14:73923b07ae4a | 670 | TheMovementAddressModePtr (i, TheColorList, false); |
roysandberg | 14:73923b07ae4a | 671 | } else if (i == TheMovementPosition && (TheMovementMode != OFF)){ |
roysandberg | 14:73923b07ae4a | 672 | TheMovementAddressModePtr (i, TheColorList, false); |
roysandberg | 14:73923b07ae4a | 673 | } else { |
roysandberg | 14:73923b07ae4a | 674 | TheMovementAddressModePtr (i, TheBaseColorList, true); |
roysandberg | 14:73923b07ae4a | 675 | } |
roysandberg | 14:73923b07ae4a | 676 | } |
roysandberg | 14:73923b07ae4a | 677 | |
roysandberg | 14:73923b07ae4a | 678 | // Latch the current color settings into the hardware |
roysandberg | 14:73923b07ae4a | 679 | theChip->latchData(); |
roysandberg | 14:73923b07ae4a | 680 | } |
roysandberg | 14:73923b07ae4a | 681 | |
roysandberg | 14:73923b07ae4a | 682 | const int* getRandomMovementColorList() { |
roysandberg | 14:73923b07ae4a | 683 | return movementColors[rnd() % MOVEMENT_COLOR_LIST_SIZE]; |
roysandberg | 14:73923b07ae4a | 684 | } |
roysandberg | 14:73923b07ae4a | 685 | |
roysandberg | 14:73923b07ae4a | 686 | const int* getRandomBaseColorList() { |
roysandberg | 14:73923b07ae4a | 687 | return baseColors[rnd() % BASE_COLOR_LIST_SIZE]; |
roysandberg | 14:73923b07ae4a | 688 | } |
roysandberg | 14:73923b07ae4a | 689 | |
roysandberg | 14:73923b07ae4a | 690 | const int* getRandomColorList() { |
roysandberg | 14:73923b07ae4a | 691 | return listOfColorLists[rnd() % USER_COLOR_CHOICES_SIZE].colorList; |
roysandberg | 14:73923b07ae4a | 692 | } |
roysandberg | 14:73923b07ae4a | 693 | |
roysandberg | 14:73923b07ae4a | 694 | void generateBaseEffect(bool isBackgroundYellow) { |
roysandberg | 14:73923b07ae4a | 695 | if (TheMode == USER_BASE || TheMode == USER_MOVEMENT_AND_BASE) { |
roysandberg | 14:73923b07ae4a | 696 | return; // already set by user |
roysandberg | 14:73923b07ae4a | 697 | } else { |
roysandberg | 14:73923b07ae4a | 698 | int randomDitherMode = rnd() % 6; |
roysandberg | 14:73923b07ae4a | 699 | int randomEffectType = rnd() % 4; |
roysandberg | 14:73923b07ae4a | 700 | const int* randomColorList; |
roysandberg | 14:73923b07ae4a | 701 | if (isBackgroundYellow) { |
roysandberg | 14:73923b07ae4a | 702 | randomColorList = getRandomBaseColorList(); |
roysandberg | 14:73923b07ae4a | 703 | } else { |
roysandberg | 14:73923b07ae4a | 704 | randomColorList = getRandomMovementColorList(); |
roysandberg | 14:73923b07ae4a | 705 | } |
roysandberg | 14:73923b07ae4a | 706 | int timeConstant = 300 + (rnd() % 8000); |
roysandberg | 14:73923b07ae4a | 707 | setBaseEffect( randomDitherMode, randomEffectType, randomColorList, timeConstant ); |
roysandberg | 14:73923b07ae4a | 708 | } |
roysandberg | 14:73923b07ae4a | 709 | } |
roysandberg | 14:73923b07ae4a | 710 | |
roysandberg | 14:73923b07ae4a | 711 | void generateMovementEffect(int durationMS) { |
roysandberg | 14:73923b07ae4a | 712 | |
roysandberg | 14:73923b07ae4a | 713 | // select a random movement effect to overlay onto the base effect |
roysandberg | 14:73923b07ae4a | 714 | if (TheMode == USER_MOVEMENT || TheMode == USER_MOVEMENT_AND_BASE) { |
roysandberg | 14:73923b07ae4a | 715 | return; // already set by user |
roysandberg | 14:73923b07ae4a | 716 | } else { |
roysandberg | 14:73923b07ae4a | 717 | int randomMovementMode = rnd() % 9; |
roysandberg | 14:73923b07ae4a | 718 | int randomDitherMode = rnd() % 6; |
roysandberg | 14:73923b07ae4a | 719 | int randomMovementFill = rnd() % 3; |
roysandberg | 14:73923b07ae4a | 720 | int randomEffectType = rnd() % 4; |
roysandberg | 14:73923b07ae4a | 721 | const int* randomColorList = getRandomMovementColorList(); |
roysandberg | 14:73923b07ae4a | 722 | int moveTimeConstant = (durationMS*(3+(rnd()%5))/8) / getMovementLevels(randomMovementMode); |
roysandberg | 14:73923b07ae4a | 723 | //int timeConstant = ((durationMS*7)/8) / getMovementLevels(randomMovementMode); |
roysandberg | 14:73923b07ae4a | 724 | int timeConstant = 200 + (rnd() % (durationMS-200)); |
roysandberg | 14:73923b07ae4a | 725 | setOverlayEffect( randomMovementMode, randomDitherMode, randomMovementFill, randomEffectType, randomColorList, timeConstant, moveTimeConstant); |
roysandberg | 14:73923b07ae4a | 726 | //printf ("New Movement Effect. move=%d, dither=%d, effect=%d, firstColor=%s, timeConstant=%d\n\r", |
roysandberg | 14:73923b07ae4a | 727 | } |
roysandberg | 14:73923b07ae4a | 728 | } |
roysandberg | 14:73923b07ae4a | 729 | |
roysandberg | 14:73923b07ae4a | 730 | // hour is zero based, starting at midnight |
roysandberg | 14:73923b07ae4a | 731 | void generateHourlyMovement(int hour, int msIntoEffect) { |
roysandberg | 14:73923b07ae4a | 732 | inHourEffect = TRUE; |
roysandberg | 14:73923b07ae4a | 733 | |
roysandberg | 14:73923b07ae4a | 734 | if (msIntoEffect < 2000) { |
roysandberg | 14:73923b07ae4a | 735 | // turn off for two seconds |
roysandberg | 14:73923b07ae4a | 736 | setChannelToColorName (BEAK, COLOR_BLACK); |
roysandberg | 14:73923b07ae4a | 737 | setChannelToColorName (EYES, COLOR_BLACK); |
roysandberg | 14:73923b07ae4a | 738 | setBaseEffect( CROSSFADE, CONSTANT, Black, 500 ); |
roysandberg | 14:73923b07ae4a | 739 | setOverlayEffect( ALL, FIXED, LINE, CONSTANT, Black, 2000, 2000); |
roysandberg | 14:73923b07ae4a | 740 | } else if (msIntoEffect < 3000 + (hour*1000)) { |
roysandberg | 14:73923b07ae4a | 741 | if (msIntoEffect%1000 < 500) { |
roysandberg | 14:73923b07ae4a | 742 | //normal |
roysandberg | 14:73923b07ae4a | 743 | setChannelToColorName (BEAK, COLOR_ORANGE_WEB_COLOR); |
roysandberg | 14:73923b07ae4a | 744 | setChannelToColorName (EYES, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 745 | setBaseEffect( FIXED, CONSTANT, OneYellow, 500 ); |
roysandberg | 14:73923b07ae4a | 746 | setOverlayEffect( OFF, FIXED, LINE, CONSTANT, Black, 500, 500); |
roysandberg | 14:73923b07ae4a | 747 | } else { |
roysandberg | 14:73923b07ae4a | 748 | //weird |
roysandberg | 14:73923b07ae4a | 749 | setChannelToColorName (BEAK, COLOR_HUNTER_GREEN); |
roysandberg | 14:73923b07ae4a | 750 | setChannelToColorName (EYES, COLOR_BLUE); |
roysandberg | 14:73923b07ae4a | 751 | setBaseEffect( FIXED, RANDOM, Electrics, 100 ); |
roysandberg | 14:73923b07ae4a | 752 | setOverlayEffect( OFF, FIXED, LINE, CONSTANT, Black, 500, 500); |
roysandberg | 14:73923b07ae4a | 753 | } |
roysandberg | 14:73923b07ae4a | 754 | |
roysandberg | 14:73923b07ae4a | 755 | } else if (msIntoEffect < 4000 + (hour*1000)) { |
roysandberg | 14:73923b07ae4a | 756 | // turn off for one seconds |
roysandberg | 14:73923b07ae4a | 757 | setChannelToColorName (BEAK, COLOR_BLACK); |
roysandberg | 14:73923b07ae4a | 758 | setChannelToColorName (EYES, COLOR_BLACK); |
roysandberg | 14:73923b07ae4a | 759 | setChannelToColorName(INTERNAL1, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 760 | setChannelToColorName(INTERNAL2, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 761 | setBaseEffect( CROSSFADE, CONSTANT, Black, 500 ); |
roysandberg | 14:73923b07ae4a | 762 | setOverlayEffect( ALL, FIXED, LINE, CONSTANT, Black, 2000, 2000); |
roysandberg | 14:73923b07ae4a | 763 | } else { |
roysandberg | 14:73923b07ae4a | 764 | inHourEffect = FALSE; |
roysandberg | 14:73923b07ae4a | 765 | // select a new yellow (normal duck) base effect |
roysandberg | 14:73923b07ae4a | 766 | generateBaseEffect(true); |
roysandberg | 14:73923b07ae4a | 767 | setChannelToColorName (BEAK, COLOR_ORANGE_WEB_COLOR); |
roysandberg | 14:73923b07ae4a | 768 | setChannelToColorName (EYES, COLOR_BLUE); |
roysandberg | 14:73923b07ae4a | 769 | setChannelToColorName(INTERNAL1, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 770 | setChannelToColorName(INTERNAL2, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 771 | } |
roysandberg | 14:73923b07ae4a | 772 | } |
roysandberg | 14:73923b07ae4a | 773 | |
roysandberg | 14:73923b07ae4a | 774 | void generatePerMinuteMovement(int msIntoEffect) { |
roysandberg | 14:73923b07ae4a | 775 | inMinuteEffect = TRUE; |
roysandberg | 14:73923b07ae4a | 776 | |
roysandberg | 14:73923b07ae4a | 777 | // end after 4 seconds |
roysandberg | 14:73923b07ae4a | 778 | if (msIntoEffect >= 4000) { |
roysandberg | 14:73923b07ae4a | 779 | inMinuteEffect = FALSE; |
roysandberg | 14:73923b07ae4a | 780 | // select a new yellow (normal duck) base effect |
roysandberg | 14:73923b07ae4a | 781 | generateBaseEffect(true); |
roysandberg | 14:73923b07ae4a | 782 | setChannelToColorName (BEAK, COLOR_ORANGE_WEB_COLOR); |
roysandberg | 14:73923b07ae4a | 783 | setChannelToColorName (EYES, COLOR_BLUE); |
roysandberg | 14:73923b07ae4a | 784 | setChannelToColorName(INTERNAL1, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 785 | setChannelToColorName(INTERNAL2, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 786 | } else { |
roysandberg | 14:73923b07ae4a | 787 | if (msIntoEffect % 500 < CLOCK_GRANULARITY) { |
roysandberg | 14:73923b07ae4a | 788 | // do some number of movement effects in a row, twice a second |
roysandberg | 14:73923b07ae4a | 789 | generateBaseEffect(false); |
roysandberg | 14:73923b07ae4a | 790 | generateMovementEffect(500); |
roysandberg | 14:73923b07ae4a | 791 | setChannelToColorName (BEAK, COLOR_HUNTER_GREEN); |
roysandberg | 14:73923b07ae4a | 792 | setChannelToColorName (EYES, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 793 | setChannelToColorName(INTERNAL1, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 794 | setChannelToColorName(INTERNAL2, COLOR_RED); |
roysandberg | 14:73923b07ae4a | 795 | } |
roysandberg | 14:73923b07ae4a | 796 | } |
roysandberg | 14:73923b07ae4a | 797 | } |
roysandberg | 14:73923b07ae4a | 798 | |
roysandberg | 14:73923b07ae4a | 799 | |
roysandberg | 14:73923b07ae4a | 800 | // This could also be used to beat match, hence the duration |
roysandberg | 14:73923b07ae4a | 801 | void generatePerSecondMovement(int durationMS) { |
roysandberg | 14:73923b07ae4a | 802 | // single movement effect |
roysandberg | 14:73923b07ae4a | 803 | // if the movement effect is a fill, it will be restored in the next cycle |
roysandberg | 14:73923b07ae4a | 804 | generateMovementEffect(durationMS); |
roysandberg | 14:73923b07ae4a | 805 | } |
roysandberg | 14:73923b07ae4a | 806 | |
roysandberg | 14:73923b07ae4a | 807 | |
roysandberg | 14:73923b07ae4a | 808 | void manageTimedInteractions() { |
roysandberg | 14:73923b07ae4a | 809 | TheElapsedTime += CLOCK_GRANULARITY; // called every 25mS |
roysandberg | 14:73923b07ae4a | 810 | if (TheElapsedTime % 43200000 < CLOCK_GRANULARITY) { |
roysandberg | 14:73923b07ae4a | 811 | TheElapsedTime = 0; // reset timer at midnight |
roysandberg | 14:73923b07ae4a | 812 | } else if (TheElapsedTime % 3600000 < CLOCK_GRANULARITY || inHourEffect) { |
roysandberg | 14:73923b07ae4a | 813 | // hourly tasks (reset timer) |
roysandberg | 14:73923b07ae4a | 814 | generateHourlyMovement(TheElapsedTime / 3600000, TheElapsedTime % 3600000); |
roysandberg | 14:73923b07ae4a | 815 | } else if (TheElapsedTime % 60000 < CLOCK_GRANULARITY || inMinuteEffect) { |
roysandberg | 14:73923b07ae4a | 816 | // one minute tasks |
roysandberg | 14:73923b07ae4a | 817 | generatePerMinuteMovement(TheElapsedTime % 60000); |
roysandberg | 14:73923b07ae4a | 818 | } else if (TheElapsedTime % UserAdjustableMovementInterval < CLOCK_GRANULARITY) { |
roysandberg | 14:73923b07ae4a | 819 | // one second tasks |
roysandberg | 14:73923b07ae4a | 820 | generatePerSecondMovement(UserAdjustableMovementInterval); |
roysandberg | 14:73923b07ae4a | 821 | } |
roysandberg | 14:73923b07ae4a | 822 | |
roysandberg | 14:73923b07ae4a | 823 | // This manages all the effects |
roysandberg | 14:73923b07ae4a | 824 | manageMovement(); |
roysandberg | 14:73923b07ae4a | 825 | } |
roysandberg | 14:73923b07ae4a | 826 | |
roysandberg | 14:73923b07ae4a | 827 | // called prior to effects to initialize everything |
roysandberg | 14:73923b07ae4a | 828 | void SequencerConfig() { |
roysandberg | 14:73923b07ae4a | 829 | for (int i=0;i<NUMBER_OF_PANELS;i++) { |
roysandberg | 14:73923b07ae4a | 830 | channelColorPointer[0][i]=0; // default to first color in list |
roysandberg | 14:73923b07ae4a | 831 | channelColorPointer[1][i]=0; // default to first color in list |
roysandberg | 14:73923b07ae4a | 832 | channelColorSettings[i] = COLOR_BLACK; |
roysandberg | 14:73923b07ae4a | 833 | Settings[i] = COLOR_BLACK; |
roysandberg | 14:73923b07ae4a | 834 | } |
roysandberg | 14:73923b07ae4a | 835 | |
roysandberg | 14:73923b07ae4a | 836 | TheMovementPosition = 0; |
roysandberg | 14:73923b07ae4a | 837 | TheMovementNumberOfLevels = 3; |
roysandberg | 14:73923b07ae4a | 838 | TheMovementAddressModePtr = &addressHorizontally; |
roysandberg | 14:73923b07ae4a | 839 | |
roysandberg | 14:73923b07ae4a | 840 | // Set a default base effect |
roysandberg | 14:73923b07ae4a | 841 | //setBaseEffect( CROSSFADE, RANDOM, Electrics, 300 ); |
roysandberg | 14:73923b07ae4a | 842 | //setBaseEffect( CROSSFADE, RANDOM, KulorSunsetCamping, 500 ); |
roysandberg | 14:73923b07ae4a | 843 | //setBaseEffect( CROSSFADE, RANDOM, TestColors, 2000 ); |
roysandberg | 14:73923b07ae4a | 844 | setBaseEffect( FIXED, CONSTANT, GoodYellows, 5000 ); |
roysandberg | 14:73923b07ae4a | 845 | |
roysandberg | 14:73923b07ae4a | 846 | // Set overlay effect to a reasonable neutral setting (OFF) |
roysandberg | 14:73923b07ae4a | 847 | setOverlayEffect(OFF , FIXED , LINE, CONSTANT, All, 1000, 1000 ); |
roysandberg | 14:73923b07ae4a | 848 | setChannelToColorName (BEAK, COLOR_ORANGE_WEB_COLOR); |
roysandberg | 14:73923b07ae4a | 849 | setChannelToColorName (EYES, COLOR_BLUE); |
roysandberg | 14:73923b07ae4a | 850 | setChannelToColorName(INTERNAL1, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 851 | setChannelToColorName(INTERNAL2, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 852 | |
roysandberg | 14:73923b07ae4a | 853 | } |
roysandberg | 14:73923b07ae4a | 854 | |
roysandberg | 14:73923b07ae4a | 855 | void convertStringToLowercase(const char* input, char*output) { |
roysandberg | 14:73923b07ae4a | 856 | for (int i=0; i<strlen(input);i++) { |
roysandberg | 14:73923b07ae4a | 857 | output[i] = tolower(input[i]); |
roysandberg | 14:73923b07ae4a | 858 | } |
roysandberg | 14:73923b07ae4a | 859 | output[strlen(input)] = 0; |
roysandberg | 14:73923b07ae4a | 860 | } |
roysandberg | 14:73923b07ae4a | 861 | |
roysandberg | 14:73923b07ae4a | 862 | int getColorByName(char* colorName) { |
roysandberg | 14:73923b07ae4a | 863 | char lowerCaseInput[64]; |
roysandberg | 14:73923b07ae4a | 864 | char lowerCaseSearch[64]; |
roysandberg | 14:73923b07ae4a | 865 | |
roysandberg | 14:73923b07ae4a | 866 | convertStringToLowercase(colorName, lowerCaseInput); |
roysandberg | 14:73923b07ae4a | 867 | for (int i=0; i< COLOR_NAMES_MAX; i++) { |
roysandberg | 14:73923b07ae4a | 868 | convertStringToLowercase(color_data[i].name, lowerCaseSearch); |
roysandberg | 14:73923b07ae4a | 869 | if (!strcmp(lowerCaseSearch, lowerCaseInput)) { |
roysandberg | 14:73923b07ae4a | 870 | return i; |
roysandberg | 14:73923b07ae4a | 871 | } |
roysandberg | 14:73923b07ae4a | 872 | } |
roysandberg | 14:73923b07ae4a | 873 | return -1; |
roysandberg | 14:73923b07ae4a | 874 | } |
roysandberg | 14:73923b07ae4a | 875 | |
roysandberg | 14:73923b07ae4a | 876 | void debugInteractions() { |
roysandberg | 14:73923b07ae4a | 877 | // Display panel settings using a text output |
roysandberg | 14:73923b07ae4a | 878 | printf ("t=%d\n\r", TheElapsedTime); |
roysandberg | 14:73923b07ae4a | 879 | for (int i=0;i<ROWS;i++) { |
roysandberg | 14:73923b07ae4a | 880 | for (int j=0;j<COLUMNS;j++) { |
roysandberg | 14:73923b07ae4a | 881 | //printf ("-%d", (channelColorSettings[PANELS[i][j]])); |
roysandberg | 14:73923b07ae4a | 882 | //printf ("-%u:%u:%u", debugRedOut[PANELS[i][j]], debugGreenOut[PANELS[i][j]], debugBlueOut[PANELS[i][j]]); |
roysandberg | 14:73923b07ae4a | 883 | printf ("-%s", getNameFromColorNumber(channelColorSettings[PANELS[i][j]])); |
roysandberg | 14:73923b07ae4a | 884 | } |
roysandberg | 14:73923b07ae4a | 885 | printf ("\n\r"); |
roysandberg | 14:73923b07ae4a | 886 | } |
roysandberg | 14:73923b07ae4a | 887 | printf("\n\r\n\r"); |
roysandberg | 14:73923b07ae4a | 888 | } |
roysandberg | 14:73923b07ae4a | 889 | |
roysandberg | 14:73923b07ae4a | 890 | // called at 40Hz from main's Ticker |
roysandberg | 14:73923b07ae4a | 891 | uint16_t timeCount=0; |
roysandberg | 14:73923b07ae4a | 892 | uint16_t count=0; |
roysandberg | 14:73923b07ae4a | 893 | void Sequencer() { |
roysandberg | 14:73923b07ae4a | 894 | led1 = !led1; |
roysandberg | 14:73923b07ae4a | 895 | |
roysandberg | 14:73923b07ae4a | 896 | if (TheMode == TEST) { |
roysandberg | 14:73923b07ae4a | 897 | return; // mode zero turns the sequencer off. Useful for testing or setting up a static display |
roysandberg | 14:73923b07ae4a | 898 | } else if (TheMode == SUN) { |
roysandberg | 14:73923b07ae4a | 899 | // sun mode |
roysandberg | 14:73923b07ae4a | 900 | for (int i=0; i< NUMBER_OF_PANELS;i++) { |
roysandberg | 14:73923b07ae4a | 901 | setChannelToColorName(i, COLOR_WHITE); |
roysandberg | 14:73923b07ae4a | 902 | } |
roysandberg | 14:73923b07ae4a | 903 | theChip->latchData(); |
roysandberg | 14:73923b07ae4a | 904 | return; |
roysandberg | 14:73923b07ae4a | 905 | } |
roysandberg | 14:73923b07ae4a | 906 | |
roysandberg | 14:73923b07ae4a | 907 | // mode 1 is the standard mode |
roysandberg | 14:73923b07ae4a | 908 | manageTimedInteractions(); |
roysandberg | 14:73923b07ae4a | 909 | if (SEQUENCER_RATE >= 0.25) { |
roysandberg | 14:73923b07ae4a | 910 | // only show debug output if the sequencer is running slow enough |
roysandberg | 14:73923b07ae4a | 911 | debugInteractions(); |
roysandberg | 14:73923b07ae4a | 912 | } |
roysandberg | 14:73923b07ae4a | 913 | } |