Published

Dependencies:   BLE_API TLC5955 mbed nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Committer:
roysandberg
Date:
Sat Jun 09 23:23:06 2018 +0000
Revision:
14:73923b07ae4a
Published

Who changed what in which revision?

UserRevisionLine numberNew 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 }