17 template<u
int8_t DATA_PIN, u
int32_t RGB_ORDER, u
int16_t NUM_LEDS>
18 class HoloLEDPCB :
public FastLED_NeoPixel<NUM_LEDS, DATA_PIN, RGB_ORDER>
23 #define USE_HOLO_TEMPLATE 1
25 template<u
int8_t DATA_PIN, u
int32_t RGB_ORDER, u
int16_t NUM_LEDS>
30 Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, RGB_ORDER)
56 template<u
int8_t DATA_PIN, u
int32_t RGB_ORDER = GRB, u
int16_t NUM_LEDS = 7>
65 #if !USE_HOLO_TEMPLATE
68 kRGBW = NEO_GRBW + NEO_KHZ800,
69 kRGB = NEO_GRB + NEO_KHZ800
132 #if USE_HOLO_TEMPLATE
137 fID((id == 0) ? getNextID() : id)
142 HoloLights(const byte pin, PixelType type = kRGBW, const int id = 0, const byte
numPixels = 7) :
144 fID((id == 0) ? getNextID() : id)
176 #if USE_HOLO_TEMPLATE
306 printf(
"COMMAND: %s\n", cmd);
307 int durationSec = -1;
309 byte functionState = 0;
310 int optionState = -1;
311 int optionState2 = -1;
313 if (*cmd++ !=
'H' || *cmd++ !=
'P')
316 int commandLength = strlen(cmd);
317 const char* pipeIndex = strchr(cmd,
'|');
318 if (pipeIndex != NULL)
320 durationSec =
atoi(pipeIndex+1);
321 commandLength = pipeIndex - cmd;
333 if (commandLength >= 2)
334 typeState = cmd[1]-
'0';
335 if (commandLength >= 4)
336 functionState = (cmd[2]-
'0')*10+(cmd[3]-
'0');
338 if (commandLength >= 5)
340 optionState = cmd[4]-
'0';
342 else if (typeState == 1)
346 if (commandLength >= 6)
348 optionState2 = cmd[5]-
'0';
351 bool match = (cmd[0]==
'A');
353 match = (match || (fID ==
kFrontHolo && (cmd[0]==
'F' || cmd[0]==
'X' || cmd[0]==
'Y')));
355 match = (match || (fID ==
kRearHolo && (cmd[0]==
'R' || cmd[0]==
'X' || cmd[0]==
'Z')));
357 match = (match || (fID ==
kTopHolo && (cmd[0]==
'T' || cmd[0]==
'Y' || cmd[0]==
'Z')));
359 match = (match || (fID ==
kRadarEye && cmd[0]==
'D'));
361 match = (match || (fID ==
kOtherHolo && cmd[0]==
'O'));
367 fLEDFunction = functionState;
368 if (optionState >= 0)
370 if (optionState == 0)
371 fLEDOption1 = random(0,9);
373 fLEDOption1 = optionState;
377 fLEDOption1 = (functionState == 7) ? fShortColor : fDefaultColor;
379 if (optionState2 >= 0 && functionState == 3)
380 fLEDOption2 = optionState2;
381 else if (optionState2 < 0 && functionState == 3)
382 fLEDOption2 = kDimPulseSpeed;
383 fLEDHalt = (durationSec >= 1) ? durationSec : -1;
384 fLEDHaltTime = millis();
387 else if (typeState == 1)
390 fHPFunction = functionState;
391 fHPOption1 = optionState;
392 if (durationSec >= 1)
393 fHPHalt = durationSec;
395 fHPHaltTime = millis();
400 else if (cmd[0] ==
'S')
402 if (commandLength >= 2)
404 functionState = (cmd[1]-
'0');
421 if (fLEDHaltTime + (fLEDHalt * 1000L) < millis())
428 switch (fLEDFunction)
431 effectColorProjectorLED(5);
434 effectColorProjectorLED(fLEDOption1);
437 effectDimPulse(fLEDOption1, fLEDOption2);
440 effectCycle(fLEDOption1);
449 effectShortCircuit(fLEDOption1);
453 fEnableTwitchLED = 0;
455 fOffColorOverride =
true;
460 if (fLEDOption1 == 1 || fLEDOption1 == 2)
462 fEnableTwitchLED = fLEDOption1;
466 fEnableTwitchLED = fStartEnableTwitchLED;
469 fOffColorOverride =
true;
474 fEnableTwitchLED = 0;
476 fOffColorOverride =
false;
481 if (fLEDOption1 == 1 || fLEDOption1 == 2)
483 fEnableTwitchLED = fLEDOption1;
487 fEnableTwitchLED = fStartEnableTwitchLED;
490 fOffColorOverride =
false;
501 if (millis() - fHPHaltTime >= (
unsigned(fHPHalt) * 1000L))
510 moveHP(fHPOption1, SERVO_SPEED[0]);
533 fEnableTwitchHP =
false;
538 fEnableTwitchHP =
true;
544 if (millis() > fTwitchLEDTime && fEnableTwitchLED >= 1 && fLEDFunction > 99)
546 fTwitchLEDTime = (1000L * random(fLEDTwitchInterval[0], fLEDTwitchInterval[1])) + millis();
547 fTwitchLEDRunTime = random(fLEDTwitchRunInterval[0], fLEDTwitchRunInterval[1]);
549 fLEDHaltTime = millis();
551 if (fEnableTwitchLED == 2)
553 fLEDFunction = random(2,7);
554 fLEDOption1 = random(1,9);
555 fLEDOption2 = random(1,9);
556 fLEDHalt = fTwitchLEDRunTime;
560 fLEDFunction = fDefaultLEDTwitchCommand[0];
561 fLEDOption1 = fDefaultLEDTwitchCommand[1];
562 fLEDOption2 = fDefaultLEDTwitchCommand[2];
563 fLEDHalt = fTwitchLEDRunTime;
566 if (millis() > fTwitchHPTime && fEnableTwitchHP && fHPFunction > 99)
597 if (durationSec >= 1)
599 fLEDHalt = durationSec;
600 fLEDHaltTime = millis();
601 fHPHalt = durationSec;
602 fHPHaltTime = millis();
606 fEnableTwitchHP =
false;
610 fEnableTwitchLED = 0;
613 fEnableTwitchHP =
true;
617 fEnableTwitchLED = 1;
620 fEnableTwitchHP =
true;
624 fEnableTwitchLED = 2;
636 fServoDispatch = dispatcher;
685 for (
unsigned i = 0; i < numLEDs; i++)
707 for (
unsigned i = 0; i < numLEDs; i++)
717 fTwitchLEDTime = (1000L * random(fLEDTwitchInterval[0], fLEDTwitchInterval[1])) + millis();
722 fTwitchHPTime = (1000 * random(fHPTwitchInterval[0], fHPTwitchInterval[1])) + millis();
727 if (fServoDispatch != NULL)
729 fServoDispatch->
moveTo(fHPpins[0], speed, hpos);
730 fServoDispatch->
moveTo(fHPpins[1], speed, vpos);
771 setHoloPosition(pgm_read_float(&sPositions[pos][0]), pgm_read_float(&sPositions[pos][1]), speed);
773 static const char* position[] = {
795 int speed = random(SERVO_SPEED[0], SERVO_SPEED[1]);
813 fWagTimer = millis();
815 if (millis() - fWagTimer >= 400)
818 fWagTimer = millis();
823 moveHP((fWagCount % 2) ? 3 : 6 , speed);
829 moveHP((fWagCount % 2) ? 0 : 2, speed);
834 void effectColorProjectorLED(
int c)
837 if ((millis() - fCounter) > fInterval)
839 for (
unsigned i = 0; i < numLEDs; i++)
845 fInterval = random(50,150);
850 void effectDimPulse(
int c,
int setting)
853 unsigned inter = map(setting, 0, 9, dimPulseSpeedRange[1], dimPulseSpeedRange[0]);
854 if ((millis() - fCounter) > fInterval)
856 unsigned elapsed = millis() - fCounter;
857 int frames = elapsed / inter;
864 frames = 32 - (frames - 32);
866 if (elapsed >= inter)
868 for (
unsigned i = 0; i < numLEDs; i++)
876 void effectShortCircuit(
int c)
879 const int kShortCircuitMaxLoops = 20;
880 if (fSCloop <= kShortCircuitMaxLoops)
882 if ((millis() - fCounter) > fSCinterval)
884 if (fSCflag ==
false)
886 for (
unsigned i = 0; i < numLEDs; i++)
889 fSCinterval = 10 + (fSCloop * random(15,25));
893 for (
unsigned i = 0; i < numLEDs; i++)
905 void effectCycle(
int c)
908 const unsigned int inter = 75;
909 if ((millis() - fCounter) > inter)
916 if (fFrame >= numLEDs)
920 for (
unsigned i = 1; i < numLEDs; i++)
935 if (fFrame >= numLEDs)
939 for (
unsigned i = 0; i < numLEDs; i++)
960 const unsigned int inter = 10;
961 unsigned elapsed = millis() - fCounter;
962 unsigned int frames = elapsed / inter;
963 if (frames > 256 * 5)
969 for (
unsigned i = 0; i < numLEDs; i++)
971 setPixelColor(i, getWheelColor(((i * 256 / numLEDs) + frames) & 255));
973 if (elapsed >= inter)
982 if (minSeconds < maxSeconds)
984 fLEDTwitchInterval[0] = minSeconds;
985 fLEDTwitchInterval[1] = maxSeconds;
986 fTwitchLEDTime = (1000L * random(fLEDTwitchInterval[0], fLEDTwitchInterval[1])) + millis();
992 if (minSeconds < maxSeconds)
994 fLEDTwitchRunInterval[0] = minSeconds;
995 fLEDTwitchRunInterval[1] = maxSeconds;
996 fTwitchLEDRunTime = (1000L * random(fLEDTwitchRunInterval[0], fLEDTwitchRunInterval[1]));
1002 if (minSeconds < maxSeconds)
1004 fHPTwitchInterval[0] = minSeconds;
1005 fHPTwitchInterval[1] = maxSeconds;
1016 inline void begin() { Begin(); }
1017 inline void show() { Show(); }
1020 inline uint16_t
numPixels() {
return PixelCount(); }
1021 inline void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
1023 SetPixelColor(n, RgbColor(r, g, b));
1027 SetPixelColor(n, RgbColor((c>>16)&0xFF, (c>>8)&0xFF, c&0xFF));
1037 void flushLEDState()
1040 if (fOffColor >= 0 && !fOffColorOverride)
1049 fLEDOption1 = color;
1059 if (fEnableTwitchHP)
1076 static inline uint32_t basicColor(
int color,
int variant = 0)
1078 static const uint32_t basicColors[10][10] PROGMEM =
1079 {{
kRed,
kYellow,
kGreen,
kCyan,
kBlue,
kMagenta,
kPurple,
kWhite,
kOff,
kOff},
1080 {
kRed,
kRed,
kRed,
kWhite, 0xFFA0A0, 0xFD5555, 0xFFD3D3,
kOff,
kOff,
kOff},
1081 {
kYellow,
kYellow,
kYellow,
kWhite, 0xFDFD43, 0xFFFF82, 0xFFFFBA,
kOff,
kOff,
kOff},
1082 {
kGreen,
kGreen,
kGreen,
kWhite, 0x57FC57, 0x80FC80, 0xBDFFB1,
kOff,
kOff,
kOff},
1083 {
kCyan,
kCyan,
kCyan,
kWhite, 0x38FFFF, 0x71FDFD, 0xA4FDFD,
kOff,
kOff,
kOff},
1084 {
kBlue,
kBlue,
kBlue,
kWhite, 0xACACFF, 0x7676FF, 0x5A5AFF,
kOff,
kOff,
kOff},
1085 {
kMagenta,
kMagenta,
kMagenta,
kWhite, 0xFB3BFB, 0xFD75FD, 0xFD9EFD,
kOff,
kOff,
kOff},
1086 {
kOrange,
kOrange,
kOrange,
kWhite, 0xFB9B3A, 0xFFBE7D, 0xFCD2A7,
kOff,
kOff,
kOff},
1087 {
kPurple,
kPurple,
kPurple,
kWhite, 0xA131A1, 0x9B449B, 0xBD5FBD,
kOff,
kOff,
kOff},
1089 return pgm_read_dword(&basicColors[color][variant]);
1092 static int getNextID()
1105 static inline uint32_t RGB(
byte r,
byte g,
byte b)
1107 return (uint32_t(r)<<16) | (uint32_t(g)<<8) | (uint32_t(b));
1117 static uint32_t getWheelColor(
byte wheelPos)
1121 return RGB(wheelPos * 3, 255 - wheelPos * 3, 0);
1123 else if (wheelPos < 170)
1126 return RGB(255 - wheelPos * 3, 0, wheelPos * 3);
1129 return RGB(0, wheelPos * 3, 255 - wheelPos * 3);
1142 static uint32_t dimColorVal(
int c,
int brightness)
1149 return RGB(255 / brightness, 0, 0);
1151 return RGB(255 / brightness, 255 / brightness, 0);
1153 return RGB(0, 255 / brightness, 0);
1155 return RGB(0, 255 / brightness, 255 / brightness);
1157 return RGB(0, 0, 255 / brightness);
1159 return RGB(255 / brightness, 0, 255 / brightness);
1161 return RGB(255 / brightness, 180 / brightness, 0);
1163 return RGB(255 / brightness, 255 / brightness, 255 / brightness);
1176 unsigned long fCounter = 0;
1177 unsigned int fInterval = 100;
1179 unsigned int fLEDTwitchInterval[2];
1180 unsigned int fLEDTwitchRunInterval[2];
1182 unsigned int fHPTwitchInterval[2];
1186 bool fSCflag =
false;
1187 bool fDirty =
false;
1188 unsigned int fSCinterval = 10;
1195 unsigned long fWagTimer = 0;
1197 unsigned long fTwitchLEDTime = 3800 + random(10) * 100;
1198 unsigned long fTwitchLEDRunTime;
1200 unsigned long fTwitchHPTime = 4000;
1202 unsigned long fLEDHaltTime = 0;
1203 unsigned long fHPHaltTime = 0;
1205 bool fStartEnableTwitchLED =
true;
1206 bool fEnableTwitchHP;
1207 byte fEnableTwitchLED = 1;
1210 bool fOffColorOverride =
false;
1212 byte fLEDFunction = -1;
1213 byte fLEDOption1 = -1;
1214 byte fLEDOption2 = -1;
1218 byte fDefaultLEDTwitchCommand[3] = { 1, 5, 0 };
1220 byte fHPFunction = -1;
1221 byte fHPOption1 = -1;
1246 uint8_t fDefaultColor = 5;
1247 uint8_t fShortColor = 7;
1249 const unsigned int SERVO_SPEED[2] = {150, 400};
1251 const int kDimPulseSpeed = 5;
1252 const uint8_t dimPulseSpeedRange[2] = {5, 75};
1255 #if USE_HOLO_TEMPLATE
1256 template<u
int8_t DATA_PIN = 45, u
int32_t RGB_ORDER = GRB, u
int16_t NUM_LEDS = 12>
1258 public HoloLights<DATA_PIN, RGB_ORDER, NUM_LEDS>
1265 #if USE_HOLO_TEMPLATE
1269 HoloOLED(HardwareSerial& oledSerialPort,
const int id = 0,
const byte resetPin = 46) :
1270 HoloLights<DATA_PIN, RGB_ORDER, NUM_LEDS>(id),
1275 HoloOLED(HardwareSerial& oledSerialPort, PixelType type = kRGBW, const int id = 0, const byte pin = 45, const byte resetPin = 46, const byte
numPixels = 12) :
1278 fSerialInit(oledSerialPort),
1279 fSerialPort(oledSerialPort),
1280 fResetPin(resetPin),
1291 #if USE_HOLO_TEMPLATE
1296 pinMode(fResetPin, OUTPUT);
1304 if (cmd[0] !=
'H' || cmd[1] !=
'O')
1306 #if USE_HOLO_TEMPLATE
1317 return (fMovieIndex >= 0 || (fMovieIndex == -1 && !fResetState && fNextCmd > millis()));
1322 #if USE_HOLO_TEMPLATE
1329 if (fNextCmd < millis())
1331 digitalWrite(fResetPin, HIGH);
1332 fResetState =
false;
1333 fNextCmd = millis() + 10000;
1336 else if (fMovieIndex == 0)
1339 fSerialPort.print((
char)(fMovieIndex));
1340 fSerialPort.flush();
1341 fNextCmd = millis();
1344 else if (fMovieIndex > 0)
1347 fSerialPort.print((
char)(fMovieIndex));
1348 fSerialPort.flush();
1349 fNextCmd = millis() + 20000;
1356 digitalWrite(fResetPin, LOW);
1357 fNextCmd = millis() + 100;
1368 fMovieIndex = movieIndex;
1380 SerialInit(HardwareSerial& port)
1387 SerialInit fSerialInit;
1388 Stream& fSerialPort;