31 fID(ledControl.addDevice(3)),
33 fPreviousEffect(~fDisplayEffect),
40 fPrevEffectSeqCount(0),
41 fEffectLengthMillis(0),
42 fEffectStartMillis(0),
59 fLC.setPower(fID,
true, NUMDEVICES);
60 fLC.setIntensity(fID, 5, NUMDEVICES);
63 fStatusMillis = millis();
68 fDisplayEffectVal = inputNum;
73 if (*cmd++ ==
'R' && *cmd++ ==
'L')
75 long int cmdvalue = 0;
77 while (*c >=
'0' && *c <=
'9')
79 cmdvalue = cmdvalue * 10 + (*c++ -
'0');
87 bool timerExpired =
false;
88 unsigned long currentMillis = millis();
89 if (currentMillis - fStatusMillis >= fStatusDelay)
92 fStatusMillis = currentMillis;
93 fFlipFlop = !fFlipFlop;
94 fEffectSeqCount += fEffectSeqDir;
95 randomSeed(analogRead(A0));
98 int selectSequence = (fDisplayEffectVal % 1000000) / 10000;
100 int selectSpeed = (fDisplayEffectVal % 10000) / 100;
101 int selectLength = (fDisplayEffectVal % 100);
103 switch (selectSequence)
114 fDisplayEffect = selectSequence;
120 if (fPreviousEffect != fDisplayEffect)
125 fPrevEffectSeqCount = 0;
126 fStatusDelay = (selectSpeed) ? 100 * (selectSpeed) : 75;
127 fEffectStartMillis = currentMillis;
128 fEffectLengthMillis = selectLength * 1000;
129 fLC.clearDisplay(fID, NUMDEVICES);
131 unsigned int effectMillis = currentMillis - fEffectStartMillis;
135 switch (fDisplayEffect)
142 for (
int dev = 0; dev < 3; dev++)
144 for (
int row = 0; row < 6; row++)
145 fLC.setRowNoCache(fID+dev, row, randomRow(2));
244 fPrevEffectSeqCount = fEffectSeqCount;
246 if (fEffectLengthMillis > 0 && fEffectLengthMillis < effectMillis)
250 fPreviousEffect = fDisplayEffect;
273 static const byte NUMDEVICES = 3;
276 unsigned long fDisplayEffect;
277 unsigned long fPreviousEffect;
280 unsigned long fStatusDelay;
281 unsigned long fStatusMillis;
284 int fPrevEffectSeqCount;
285 unsigned int fEffectLengthMillis;
286 unsigned long fEffectStartMillis;
287 unsigned long fDisplayEffectVal;
288 unsigned long LEDgrid[5];
290 void setRow(
byte row, uint32_t bits)
298 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
304 void setCol(
byte col, uint8_t data)
306 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
309 byte LEDon = (data & 1<<row);
311 LEDgrid[4-row] |= (1L << col);
313 LEDgrid[4-row] &= ~(1L << col);
317 static uint8_t rev(uint8_t n)
320 static uint8_t revlookup[] = {
326 return (revlookup[n & 0x0F] << 4) | revlookup[n >> 4];
329 byte randomRow(
int loop)
332 byte val = random(256);
335 return (random(2) == 1) ? rev(val) : val;
341 unsigned char col8 = 0;
342 unsigned char col17 = 0;
343 unsigned char col26 = 0;
346 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
348 for (
int dev = 0; dev < 3; dev++)
351 fLC.setRowNoCache(fID+dev, row, rev((LEDgrid[row] & 255L << (9 * dev)) >> (9 * dev)));
354 if ((LEDgrid[row] & 1L<<8) == 1L<<8) col8 += 128 >> row;
355 if ((LEDgrid[row] & 1L<<17) == 1L<<17) col17 += 128 >> row;
356 if ((LEDgrid[row] & 1L<<26) == 1L<<26) col26 += 128 >> row;
359 fLC.setRowNoCache(fID+0, 5, col8);
360 fLC.setRowNoCache(fID+1, 5, col17);
361 fLC.setRowNoCache(fID+2, 5, col26);
387 fID(ledControl.addDevice()),
389 fPreviousEffect(~fDisplayEffect),
391 fFlipFlopLast(false),
396 fPrevEffectSeqCount(0),
397 fEffectLengthMillis(0),
398 fEffectStartMillis(0),
415 fLC.setPower(fID,
true);
416 fLC.setIntensity(fID, 5);
419 fStatusMillis = millis();
424 fDisplayEffectVal = inputNum;
435 if ((cmd[0] ==
'F' && cmd[1] ==
'L') ||
436 (cmd[0] ==
'T' && cmd[1] ==
'L') ||
437 (cmd[0] ==
'B' && cmd[1] ==
'L'))
439 long int cmdvalue = 0;
440 const char* c = &cmd[2];
441 while (*c >=
'0' && *c <=
'9')
443 cmdvalue = cmdvalue * 10 + (*c++ -
'0');
451 bool timerExpired =
false;
452 unsigned long currentMillis = millis();
453 if (currentMillis - fStatusMillis >= fStatusDelay)
456 fStatusMillis = currentMillis;
457 fFlipFlop = !fFlipFlop;
458 fEffectSeqCount += fEffectSeqDir;
459 randomSeed(analogRead(A0));
462 int selectSequence = (fDisplayEffectVal % 1000000) / 10000;
464 int selectSpeed = (fDisplayEffectVal % 10000) / 100;
465 int selectLength = (fDisplayEffectVal % 100);
467 switch (selectSequence)
478 fDisplayEffect = selectSequence;
484 if (fPreviousEffect != fDisplayEffect)
489 fPrevEffectSeqCount = 0;
490 fStatusDelay = (selectSpeed) ? 100 * (selectSpeed) : 75;
491 fEffectStartMillis = currentMillis;
492 fEffectLengthMillis = selectLength * 1000;
493 fLC.clearDisplay(fID);
495 unsigned int effectMillis = currentMillis - fEffectStartMillis;
499 switch (fDisplayEffect)
506 for (
int dev = 0; dev < 3; dev++)
508 for (
int row = 0; row < 6; row++)
509 fLC.setRowNoCache(fID+dev, row, randomRow(2));
608 fPrevEffectSeqCount = fEffectSeqCount;
610 if (fEffectLengthMillis > 0 && fEffectLengthMillis < effectMillis)
614 fPreviousEffect = fDisplayEffect;
639 unsigned long fDisplayEffect;
640 unsigned long fPreviousEffect;
643 unsigned long fStatusDelay;
644 unsigned long fStatusMillis;
647 int fPrevEffectSeqCount;
648 unsigned int fEffectLengthMillis;
649 unsigned long fEffectStartMillis;
650 unsigned long fDisplayEffectVal;
651 unsigned long LEDgrid[5];
653 void setRow(
byte row, uint32_t bits)
661 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
667 void setCol(
byte col, uint8_t data)
669 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
672 byte LEDon = (data & 1<<row);
674 LEDgrid[4-row] |= (1L << col);
676 LEDgrid[4-row] &= ~(1L << col);
680 static uint8_t rev(uint8_t n)
683 static uint8_t revlookup[] = {
689 return (revlookup[n & 0x0F] << 4) | revlookup[n >> 4];
692 byte randomRow(
int loop)
695 byte val = random(256);
698 return (random(2) == 1) ? rev(val) : val;
704 unsigned char col8 = 0;
705 unsigned char col17 = 0;
706 unsigned char col26 = 0;
709 for (
byte row = 0; row <
SizeOfArray(LEDgrid); row++)
711 for (
int dev = 0; dev < 3; dev++)
714 fLC.setRowNoCache(fID+dev, row, rev((LEDgrid[row] & 255L << (9 * dev)) >> (9 * dev)));
717 if ((LEDgrid[row] & 1L<<8) == 1L<<8) col8 += 128 >> row;
718 if ((LEDgrid[row] & 1L<<17) == 1L<<17) col17 += 128 >> row;
719 if ((LEDgrid[row] & 1L<<26) == 1L<<26) col26 += 128 >> row;
722 fLC.setRowNoCache(fID+0, 5, col8);
723 fLC.setRowNoCache(fID+1, 5, col17);
724 fLC.setRowNoCache(fID+2, 5, col26);
757 #include <avr/pgmspace.h>
758 #include <TeecesControl.h>
828 #define BAUDRATE 2400
831 char TFLDtext[] =
"R2-D2 ";
832 char BFLDtext[] =
" ASTROMECH";
833 char RLDtext[] =
"CURIOUSMARC SKETCH V1.2 ";
907 #define RLDbrightness 5 //rear Logic
908 #define RPSIbrightness 15 //rear PSI
909 #define FLDbrightness 5 //front Logics
910 #define FPSIbrightness 15 //front PSI
913 #define LOGICupdateDelay 75
922 #define LOGICRandomStyle 4
925 #define BARGRAPHupdateDelay 50
928 #define PSIwipeDelay 70
931 #define FPSIgetsStuck 0
932 #define RPSIgetsStuck 0
935 #define PSIstuckhowlong 10000 // stuck time in ms
936 #define PSIstuckhowoften 5 // how often. 5 means 1 out of 5 swipes on average. So the higher the less often.
939 #define SCROLLspeed 48
942 #define LEIAduration 34000 // in ms
943 #define LEIAspeed 100 //2200 // in no particular units, lower=faster
946 #define ALARMduration 4000 // in ms
947 #define ALARMspeed 100 // in ms
950 #define MARCHduration 47000 // in ms
951 #define MARCHspeed 555 // in ms. Adjusted to the tempo of 108 of my March recording (60/108=555ms).
954 #define FAILUREduration 10000
955 #define FAILUREloops 5
956 #define FAILUREspeed 75
982 #define FDEV 3 //3 devices for front chain (top FLD, bottom FLD, front PSI
983 #define FPSIDEV 2 //front PSI is device #2 in the front chain
984 #define RPSIDEV 3 //rear PSI is device #3 in the rear chain
986 #define LETTERWIDTH 5 // letter with in pixels
987 #define MAXSTRINGSIZE 64 // maximum number of letters in a logic display message
988 #define CMD_MAX_LENGTH 64 // maximum number of characters in a command (63 chars since we need the null termination)
999 unsigned long LEDgrid[3][5];
1002 int scrollPositions[]={9,9,27};
1006 long textScrollCount[3];
1011 byte alphabetType[3];
1027 byte displayState[3];
1036 #define YELLOW COLOR1
1037 #define GREEN COLOR2
1040 byte randomStyle[3]={LOGICRandomStyle, LOGICRandomStyle, LOGICRandomStyle};
1046 char logicText[3][MAXSTRINGSIZE+1];
1049 char cmdString[CMD_MAX_LENGTH];
1052 LedControl lcRear=LedControl(DVAL,CVAL,LVAL,4);
1053 LedControl lcFront=LedControl(9,8,7,FDEV);
1056 HardwareSerial* serialPort;
1063 #define HPPAT1 B10101010
1064 #define HPPAT2 B01010101
1065 int psiPatterns[]={HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2};
1068 #define HPPAT1 B11100000
1069 #define HPPAT2 B00011111
1070 int psiPatterns[]={HPPAT1,HPPAT1,HPPAT1,HPPAT1,HPPAT1,HPPAT2,HPPAT2,HPPAT2,HPPAT2,HPPAT2};
1073 #define HPPAT1 B10101000
1074 #define HPPAT2 B01010100
1075 int psiPatterns[]={HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2,HPPAT1,HPPAT2};
1078 #define HPPAT1 B11000000
1079 #define HPPAT2 B00110000
1080 int psiPatterns[]={HPPAT1,HPPAT1,HPPAT1,HPPAT1,HPPAT1,HPPAT2,HPPAT2,HPPAT2,HPPAT2,HPPAT2};
1093 #if (BOARDtype==2 || BOARDtype==3)
1094 Serial1.begin(BAUDRATE);
1095 serialPort=&Serial1;
1098 Serial.begin(BAUDRATE);
1103 serialPort->println();
1104 serialPort->println();
1105 serialPort->println(
"--- CuriousMarc Teeces v1.0 ---");
1107 randomSeed(analogRead(0));
1110 for(
int dev=0;dev<lcRear.getDeviceCount();dev++)
1112 lcRear.shutdown(dev,
false);
1113 lcRear.clearDisplay(dev);
1115 for(
int dev=0;dev<lcFront.getDeviceCount();dev++)
1117 lcFront.shutdown(dev,
false);
1118 lcFront.clearDisplay(dev);
1122 lcRear.setIntensity(0, RLDbrightness);
1123 lcRear.setIntensity(1, RLDbrightness);
1124 lcRear.setIntensity(2, RLDbrightness);
1125 lcRear.setIntensity(3, RPSIbrightness);
1128 for(
int dev=0;dev<(lcFront.getDeviceCount()-1);dev++)
1130 lcFront.setIntensity(dev, FLDbrightness);
1132 lcFront.setIntensity(FPSIDEV, FPSIbrightness);
1139 while((textScrollCount[0]<1) || (textScrollCount[1]<1) || (textScrollCount[2]<1))
1141 if (textScrollCount[0]<1) scrollText(0,TFLDtext);
1142 if (textScrollCount[1]<1) scrollText(1,BFLDtext);
1143 if (textScrollCount[2]<1) scrollText(2,RLDtext);
1150 serialPort->println(
"Ready for command.");
1151 serialPort->println();
1152 serialPort->print(
"> ");
1192 if(serialPort->available())
1195 byte command_available;
1197 ch=serialPort->read();
1198 serialPort->print(ch);
1199 command_available=buildCommand(ch, cmdString);
1200 if (command_available)
1202 parseCommand(cmdString);
1203 serialPort->println();
1204 serialPort->print(
"> ");
1223 switch(displayEffect)
1227 alarmDisplay(ALARMduration);
1230 marchDisplay(MARCHduration);
1233 leiaDisplay(LEIAduration);
1236 failureDisplay(FAILUREduration);
1240 for(
byte disp=0; disp<3; disp++)
1242 switch(displayState[disp])
1245 randomDisplay(disp);
1257 bargraphDisplay(disp);
1260 randomDisplay(disp);
1269 case COLOR1:
case COLOR2:
case OFF:
case TEST:
1270 setFPSI(psiState[0]);
1281 case COLOR1:
case COLOR2:
case OFF:
case TEST:
1282 setRPSI(psiState[1]);
1298 byte buildCommand(
char ch,
char* output_str)
1300 static uint8_t pos=0;
1304 output_str[pos]=
'\0';
1310 if(pos<=CMD_MAX_LENGTH-1)pos++;
1321 void parseCommand(
char* inputStr)
1323 byte hasArgument=
false;
1327 byte length=strlen(inputStr);
1328 if(length<2)
goto beep;
1332 if(!isdigit(inputStr[pos]))
goto beep;
1333 addrStr[pos]=inputStr[pos];
1335 if(isdigit(inputStr[pos]))
1337 addrStr[pos]=inputStr[pos];
1341 address=
atoi(addrStr);
1344 if(!length>pos)
goto beep;
1347 if(inputStr[pos]==
'M')
1350 if(!length>pos)
goto beep;
1351 doMcommand(address, inputStr+pos);
1358 if(!length>pos) hasArgument=
false;
1361 for(
byte i=pos; i<length; i++)
1363 if(!isdigit(inputStr[i]))
goto beep;
1365 argument=
atoi(inputStr+pos);
1370 switch(inputStr[pos-1])
1373 if(!hasArgument)
goto beep;
1374 doTcommand(address, argument);
1377 doDcommand(address);
1380 if(!hasArgument)
goto beep;
1381 doPcommand(address, argument);
1384 if(!hasArgument)
goto beep;
1385 doRcommand(address, argument);
1388 if(!hasArgument)
goto beep;
1389 doScommand(address, argument);
1399 serialPort->write(0x7);
1407 void doMcommand(
int address,
char* message)
1409 serialPort->println();
1410 serialPort->print(
"Command: M ");
1411 serialPort->print(
"Address: ");
1412 serialPort->print(address);
1413 serialPort->print(
" Argument: ");
1414 serialPort->print(message);
1416 if(address==0) {setText(0, message); setText(1, message); setText(2, message); resetAllText();}
1417 if(address==1) {setText(0, message); resetText(0);}
1418 if(address==2) {setText(1, message); resetText(1);}
1419 if(address==3) {setText(2, message); resetText(2);}
1424 void doTcommand(
int address,
int argument)
1426 serialPort->println();
1427 serialPort->print(
"Command: T ");
1428 serialPort->print(
"Address: ");
1429 serialPort->print(address);
1430 serialPort->print(
" Argument: ");
1431 serialPort->print(argument);
1438 if(address==0) {displayState[0]=displayState[1]=displayState[2]=psiState[0]=psiState[1]=TEST; resetAllText();}
1439 if(address==1) {displayState[0]=TEST; resetText(0);}
1440 if(address==2) {displayState[1]=TEST; resetText(1);}
1441 if(address==3) {displayState[2]=TEST; resetText(2);}
1442 if(address==4) {psiState[0]=TEST;}
1443 if(address==5) {psiState[1]=TEST;}
1447 if(address==0) {displayState[0]=displayState[1]=displayState[2]=psiState[0]=psiState[1]=RANDOM; resetAllText();}
1448 if(address==1) {displayState[0]=RANDOM; resetText(0);}
1449 if(address==2) {displayState[1]=RANDOM; resetText(1);}
1450 if(address==3) {displayState[2]=RANDOM; resetText(2);}
1451 if(address==4) {psiState[0]=RANDOM;}
1452 if(address==5) {psiState[1]=RANDOM;}
1454 case 2:
case 3:
case 5:
1456 displayEffect=ALARM;
1460 displayEffect=FAILURE;
1469 for(
byte disp=0; disp<3; disp++)
1472 alphabetType[disp]=0;
1473 displayState[disp]=TEXT;
1478 setText(2,
"STAR WARS ");
1482 displayEffect=MARCH;
1486 if(address==0) {displayState[0]=displayState[1]=displayState[2]=psiState[0]=psiState[1]=
OFF; resetAllText();}
1487 if(address==1) {displayState[0]=
OFF; resetText(0);}
1488 if(address==2) {displayState[1]=
OFF; resetText(1);}
1489 if(address==3) {displayState[2]=
OFF; resetText(2);}
1490 if(address==4) {psiState[0]=
OFF;}
1491 if(address==5) {psiState[1]=
OFF;}
1495 if(address==0) {displayState[0]=displayState[1]=displayState[2]=BARGRAPH; resetAllText();}
1496 if(address==1) {displayState[0]=BARGRAPH; resetText(0);}
1497 if(address==2) {displayState[1]=BARGRAPH; resetText(1);}
1498 if(address==3) {displayState[2]=BARGRAPH; resetText(2);}
1502 if(address==0) {displayState[0]=displayState[1]=displayState[2]=TEXT; resetAllText();}
1503 if(address==1) {displayState[0]=TEXT; resetText(0);}
1504 if(address==2) {displayState[1]=TEXT; resetText(1);}
1505 if(address==3) {displayState[2]=TEXT; resetText(2);}
1514 void doDcommand(
int address)
1516 serialPort->println();
1517 serialPort->print(
"Command: D ");
1518 serialPort->print(
"Address: ");
1519 serialPort->print(address);
1525 void doPcommand(
int address,
int argument)
1527 serialPort->println();
1528 serialPort->print(
"Command: P ");
1529 serialPort->print(
"Address: ");
1530 serialPort->print(address);
1531 serialPort->print(
" Argument: ");
1532 serialPort->print(argument);
1536 if(address==0) {alphabetType[0]=alphabetType[1]=alphabetType[2]=LATIN;}
1537 if(address==1) {alphabetType[0]=LATIN;}
1538 if(address==2) {alphabetType[1]=LATIN;}
1539 if(address==3) {alphabetType[2]=LATIN;}
1542 if(address==0) {alphabetType[0]=alphabetType[1]=alphabetType[2]=AURABESH;}
1543 if(address==1) {alphabetType[0]=AURABESH;}
1544 if(address==2) {alphabetType[1]=AURABESH;}
1545 if(address==3) {alphabetType[2]=AURABESH;}
1554 void doRcommand(
int address,
int argument)
1556 serialPort->println();
1557 serialPort->print(
"Command: R ");
1558 serialPort->print(
"Address: ");
1559 serialPort->print(address);
1560 serialPort->print(
" Argument: ");
1561 serialPort->print(argument);
1563 if(address==0) {randomStyle[0]=randomStyle[1]=randomStyle[2]=argument;}
1564 if(address==1) {randomStyle[0]=argument;}
1565 if(address==2) {randomStyle[1]=argument;}
1566 if(address==3) {randomStyle[2]=argument;}
1569 void doScommand(
int address,
int argument)
1571 serialPort->println();
1572 serialPort->print(
"Command: S ");
1573 serialPort->print(
"Address: ");
1574 serialPort->print(address);
1575 serialPort->print(
" Argument: ");
1576 serialPort->print(argument);
1580 if(address==0) {psiState[0]=psiState[1]=TEST;}
1581 if(address==4) {psiState[0]=TEST;}
1582 if(address==5) {psiState[1]=TEST;}
1585 if(address==0) {psiState[0]=psiState[1]=RANDOM;}
1586 if(address==4) {psiState[0]=RANDOM;}
1587 if(address==5) {psiState[1]=RANDOM;}
1590 if(address==0) {psiState[0]=psiState[1]=COLOR1;}
1591 if(address==4) {psiState[0]=COLOR1;}
1592 if(address==5) {psiState[1]=COLOR1;}
1595 if(address==0) {psiState[0]=psiState[1]=COLOR2;}
1596 if(address==4) {psiState[0]=COLOR2;}
1597 if(address==5) {psiState[1]=COLOR2;}
1600 if(address==0) {psiState[0]=psiState[1]=
OFF;}
1601 if(address==4) {psiState[0]=
OFF;}
1602 if(address==5) {psiState[1]=
OFF;}
1617 void randomDisplay(
byte disp)
1622 randomDisplayTFLD();
1625 randomDisplayBFLD();
1636 void textDisplay(
byte disp)
1639 scrollText(disp, logicText[disp]);
1644 void testDisplay(
byte disp)
1647 for(
byte i=0; i<5; i++)
1649 LEDgrid[disp][i]=~0L;
1656 void offDisplay(
byte disp)
1659 for(
byte i=0; i<5; i++)
1661 LEDgrid[disp][i]=0L;
1668 void bargraphDisplay(
byte disp)
1670 static byte bargraphdata[3][27];
1675 static long previousDisplayUpdate[3]={0,0,0};
1676 unsigned long currentMillis = millis();
1677 if(currentMillis - previousDisplayUpdate[disp] < BARGRAPHupdateDelay)
return;
1678 previousDisplayUpdate[disp] = currentMillis;
1681 if(disp==0 || disp==1) maxcol=9;
1685 for(
byte column=0; column<maxcol; column++)
1688 byte value = updatebar(disp, column, bargraphdata[disp]);
1690 for(
int i=0; i<=value; i++)
1695 fillColumn( disp, column, data);
1701 byte updatebar(
byte disp,
byte column,
byte* bargraphdata)
1704 int variation = random(0,3);
1705 int value=(int)bargraphdata[column];
1706 if (value==5) value=3;
1707 else value += (variation-1);
1708 if (value<=0) value=0;
1709 if (value>5) value=5;
1710 bargraphdata[column]=(byte)value;
1715 void fillColumn(
byte disp,
byte column,
byte data)
1717 if (disp==2 && column>27)
return;
1718 if (disp!=2 && column>9)
return;
1719 for(
byte row=0; row<5; row++)
1722 byte LEDon=(data & 1<<row);
1724 LEDgrid[disp][4-row] |= (1L << column);
1726 LEDgrid[disp][4-row] &= ~(1L << column);
1731 long randomRow(
byte randomMode)
1736 return (random(256)&random(256)&random(256)&random(256));
1739 return (random(256)&random(256)&random(256));
1742 return (random(256)&random(256));
1748 return (random(256)|random(256));
1751 return (random(256)|random(256)|random(256));
1754 return (random(256)|random(256)|random(256)|random(256));
1767 void randomDisplayRLD()
1770 static long previousDisplayUpdate=0;
1773 unsigned long currentMillis = millis();
1774 if(currentMillis - previousDisplayUpdate < LOGICupdateDelay)
return;
1775 previousDisplayUpdate = currentMillis;
1777 #if defined(TESTLOGICS) //turn on all logic LEDs to make sure they're all working
1779 for (
int dev=0; dev<3; dev++)
1781 for (
int row=0; row<6; row++)
1782 lcRear.setRow(dev,row,255);
1786 #else // regular random code
1789 for (
int dev=0; dev<3; dev++)
1791 for (
int row=0; row<6; row++)
1792 lcRear.setRow(dev,row,randomRow(randomStyle[2]));
1803 void randomDisplayTFLD()
1806 static long previousDisplayUpdate=0;
1809 unsigned long currentMillis = millis();
1810 if(currentMillis - previousDisplayUpdate < LOGICupdateDelay)
return;
1811 previousDisplayUpdate = currentMillis;
1813 #if defined(TESTLOGICS) //turn on all logic LEDs to make sure they're all working
1816 for (
int row=0; row<6; row++)
1817 lcFront.setRow(dev,row,255);
1819 #else // regular random code
1823 for (
int row=0; row<6; row++)
1824 lcFront.setRow(dev,row,randomRow(randomStyle[0]));
1833 void randomDisplayBFLD()
1836 static long previousDisplayUpdate=0;
1839 unsigned long currentMillis = millis();
1840 if(currentMillis - previousDisplayUpdate < LOGICupdateDelay)
return;
1841 previousDisplayUpdate = currentMillis;
1843 #if defined(TESTLOGICS) //turn on all logic LEDs to make sure they're all working
1846 for (
int row=0; row<6; row++)
1847 lcFront.setRow(dev,row,255);
1849 #else // regular random code
1853 for (
int row=0; row<6; row++)
1854 lcFront.setRow(dev,row,randomRow(randomStyle[1]));
1870 void setFPSI(
byte mode)
1875 for(
byte row=0; row<HPROW; row++)
1877 lcFront.setRow(2, row, 0x00);
1881 for(
byte row=0; row<HPROW; row++)
1883 lcFront.setRow(2, row, 0xFF);
1887 for(
byte row=0; row<HPROW; row++)
1889 lcFront.setRow(2, row, psiPatterns[row]);
1893 for(
byte row=0; row<HPROW; row++)
1895 lcFront.setRow(2, row, psiPatterns[row+5]);
1903 void setRPSI(
byte mode)
1908 for(
byte row=0; row<HPROW; row++)
1910 lcRear.setRow(3, row, 0x00);
1914 for(
byte row=0; row<HPROW; row++)
1916 lcRear.setRow(3, row, 0xFF);
1920 for(
byte row=0; row<HPROW; row++)
1922 lcRear.setRow(3, row, psiPatterns[row]);
1926 for(
byte row=0; row<HPROW; row++)
1928 lcRear.setRow(3, row, psiPatterns[row+5]);
1944 static unsigned long psiMillisChangeDir=0;
1945 static unsigned long psiMillisSwipe=0;
1947 static long unsigned psiChangeColorDelay=0;
1949 static int psiColor=0;
1950 static int psiCurrentSwipeRow=0;
1952 static byte isStuck=0;
1954 unsigned long currentMillis = millis();
1958 psiMillisChangeDir = currentMillis;
1963 if(currentMillis - psiMillisChangeDir > psiChangeColorDelay*500)
1966 psiMillisChangeDir = currentMillis;
1967 psiChangeColorDelay = random(1,11);
1973 psiCurrentSwipeRow=0;
1978 psiCurrentSwipeRow=HPROW-1;
1985 {
if (currentMillis - psiMillisSwipe < PSIstuckhowlong)
return;}
1987 {
if(currentMillis - psiMillisSwipe < PSIwipeDelay)
return;}
1990 if(isStuck) isStuck=0;
1993 if (psiCurrentSwipeRow<HPROW && psiColor == 5)
1995 psiMillisSwipe = currentMillis;
1996 lcFront.setRow(2, psiCurrentSwipeRow, psiPatterns[psiCurrentSwipeRow+psiColor]);
1997 psiCurrentSwipeRow++;
2000 else if (psiCurrentSwipeRow>=0 && psiColor == 0)
2002 psiMillisSwipe = currentMillis;
2003 lcFront.setRow(2, psiCurrentSwipeRow, psiPatterns[psiCurrentSwipeRow+psiColor]);
2004 psiCurrentSwipeRow--;
2008 if(FPSIgetsStuck && psiCurrentSwipeRow==2 && psiColor==5)
2011 byte onceinawhile=random(PSIstuckhowoften);
2012 if(onceinawhile==1) isStuck=1;
2022 static unsigned long psiMillisChangeDir=0;
2023 static unsigned long psiMillisSwipe=0;
2025 static unsigned long psiChangeColorDelay=0;
2027 static int psiColor=0;
2028 static int psiCurrentSwipeRow=0;
2030 static byte isStuck=0;
2033 unsigned long currentMillis = millis();
2037 psiMillisChangeDir = currentMillis;
2042 if(currentMillis - psiMillisChangeDir > psiChangeColorDelay*500)
2045 psiMillisChangeDir = currentMillis;
2046 psiChangeColorDelay = random(1,11);
2052 psiCurrentSwipeRow=0;
2057 psiCurrentSwipeRow=HPROW-1;
2064 {
if (currentMillis - psiMillisSwipe < PSIstuckhowlong)
return;}
2066 {
if(currentMillis - psiMillisSwipe < PSIwipeDelay)
return;}
2069 if(isStuck) isStuck=0;
2072 if (psiCurrentSwipeRow<HPROW && psiColor == 5)
2074 psiMillisSwipe = currentMillis;
2075 lcRear.setRow(3, psiCurrentSwipeRow, psiPatterns[psiCurrentSwipeRow+psiColor]);
2076 psiCurrentSwipeRow++;
2079 else if (psiCurrentSwipeRow>=0 && psiColor == 0)
2081 psiMillisSwipe = currentMillis;
2082 lcRear.setRow(3, psiCurrentSwipeRow, psiPatterns[psiCurrentSwipeRow+psiColor]);
2083 psiCurrentSwipeRow--;
2087 if(RPSIgetsStuck && psiCurrentSwipeRow==2 && psiColor==5)
2090 byte onceinawhile=random(PSIstuckhowoften);
2091 if(onceinawhile==1) isStuck=1;
2104 void resetText(
byte display)
2107 scrollPositions[display]= (display==2? 27 : 9);
2108 textScrollCount[display]=0;
2114 for(
byte disp=0; disp<3; disp++)
2130 void resetDisplays()
2134 for(
byte disp=0; disp<3; disp++)
2136 alphabetType[disp]=LATIN;
2137 displayState[disp]=NORM;
2145 void leiaDisplay(
unsigned long playTime)
2151 unsigned long currentMillis = millis();
2152 static unsigned long swtchMillis;
2153 static unsigned long enterMillis;
2156 if(effectRunning==0)
2158 enterMillis=currentMillis;
2161 clearGrid(0); showGrid(0);
2162 clearGrid(1); showGrid(1);
2163 clearGrid(2); showGrid(2);
2166 if(playTime && (currentMillis - enterMillis > playTime))
2178 if (currentMillis - swtchMillis > LEIAspeed)
2180 swtchMillis=currentMillis;
2182 for(
int dev=0;dev<3;dev++)
2185 lcRear.setRow(dev,a,255);
2186 lcRear.setLed(dev,5,a,
true);
2189 lcRear.setRow(dev,b,0);
2190 lcRear.setLed(dev,5,b,
false);
2197 lcFront.setRow(dev,a,255);
2198 lcFront.setLed(dev,5,a,
true);
2201 lcFront.setRow(dev,b,0);
2202 lcFront.setLed(dev,5,b,
false);
2209 lcFront.setRow(dev,4-a,255);
2210 lcFront.setLed(dev,5,4-a,
true);
2213 lcFront.setRow(dev,4-b,0);
2214 lcFront.setLed(dev,5,4-b,
false);
2247 void alarmDisplay(
unsigned long playTime)
2249 static byte swtch = 0;
2252 static unsigned long swtchMillis;
2253 unsigned long currentMillis = millis();
2256 static unsigned long enterMillis;
2257 if(effectRunning==0)
2259 enterMillis=currentMillis;
2263 if(playTime && (currentMillis - enterMillis > playTime))
2271 if (currentMillis - swtchMillis > ALARMspeed)
2280 for(
int row=0;row<5;row++)
2282 LEDgrid[0][row]=0xFFFFFFFFL;
2283 LEDgrid[1][row]=0xFFFFFFFFL;
2284 LEDgrid[2][row]=0xFFFFFFFFL;
2294 swtchMillis = millis();
2297 else if (swtch == 1)
2311 swtchMillis = millis();
2319 void marchDisplay(
unsigned long playTime)
2321 unsigned long currentMillis = millis();
2322 static unsigned long swtchMillis = millis();
2323 static byte swtch = 0;
2326 static unsigned long enterMillis;
2327 if(effectRunning==0)
2329 enterMillis=currentMillis;
2333 if(playTime && (currentMillis - enterMillis > playTime))
2340 if (currentMillis - swtchMillis > MARCHspeed)
2348 for(
int row=0;row<5;row++)
2350 LEDgrid[0][row]=31L;
2351 LEDgrid[1][row]=31L;
2352 LEDgrid[2][row]=16383L;
2362 swtchMillis = millis();
2365 else if (swtch == 1)
2371 for(
int row=0;row<5;row++)
2373 LEDgrid[0][row]= ~15L;
2374 LEDgrid[1][row]= ~15L;
2375 LEDgrid[2][row]= ~8191L;
2385 swtchMillis = millis();
2396 void showFailure(
byte style)
2399 for (
int row=0; row<6; row++)
2400 lcFront.setRow(0,row,randomRow(style));
2402 for (
int row=0; row<6; row++)
2403 lcFront.setRow(1,row,randomRow(style));
2405 for (
int dev=0; dev<3; dev++)
2407 for (
int row=0; row<6; row++)
2408 lcRear.setRow(dev,row,randomRow(style));
2411 for (
int row=0; row<HPROW; row++)
2412 lcFront.setRow(2,row,randomRow(style));
2414 for (
int row=0; row<HPROW; row++)
2415 lcRear.setRow(3,row,randomRow(style));
2419 void failureDisplay(
unsigned long playTime)
2421 static int loopCount=0;
2422 static unsigned long lastMillis;
2423 unsigned long currentMillis = millis();
2424 static unsigned long blinkSpeed = FAILUREspeed;
2427 static unsigned long enterMillis;
2428 if(effectRunning==0)
2430 blinkSpeed = FAILUREspeed;
2432 enterMillis=currentMillis;
2436 if(playTime && (currentMillis - enterMillis > playTime))
2444 if (currentMillis - lastMillis < blinkSpeed)
return;
2445 lastMillis = currentMillis;
2449 if (loopCount<FAILUREloops)
2451 blinkSpeed=FAILUREspeed;
2454 else if(loopCount<2*FAILUREloops)
2456 blinkSpeed=2*FAILUREspeed;
2459 else if(loopCount<3*FAILUREloops)
2461 blinkSpeed=3*FAILUREspeed;
2464 else if(loopCount<4*FAILUREloops)
2466 blinkSpeed=4*FAILUREspeed;
2469 else if(loopCount<5*FAILUREloops)
2486 uint8_t revlookup[16] = {
2490 0x3, 0xB, 0x7, 0xF };
2492 uint8_t rev( uint8_t n )
2496 return (revlookup[n&0x0F] << 4) | revlookup[n>>4];
2500 void clearGrid(
byte display)
2502 for (
byte row=0; row<5; row++) LEDgrid[display][row]=0L;
2506 void showGrid(
byte display)
2513 unsigned char col8=0;
2514 unsigned char col17=0;
2515 unsigned char col26=0;
2523 for (
byte row=0; row<5; row++)
2526 lcFront.setRow(0, row, rev(LEDgrid[display][row] & 255L));
2528 if ( (LEDgrid[display][row] & 1L<<8) == 1L<<8) col8 += 128>>row;
2531 lcFront.setRow(0, 5, col8);
2537 for (
byte row=0; row<5; row++)
2540 lcFront.setRow(1, 4-row, (LEDgrid[display][row] & 255L<<1) >> 1);
2544 if ( (LEDgrid[display][row] & 1L) == 1L) col8 += 8<<row;
2547 lcFront.setRow(1, 5, col8);
2551 for (
byte row=0; row<5; row++)
2554 for (
byte dev=0; dev < 3; dev++)
2557 lcRear.setRow(dev, row, rev( (LEDgrid[display][row] & 255L<<(9*loops)) >> (9*loops) ));
2561 if ( (LEDgrid[display][row] & 1L<<8) == 1L<<8) col8 += 128>>row;
2562 if ( (LEDgrid[display][row] & 1L<<17) == 1L<<17) col17 += 128>>row;
2563 if ( (LEDgrid[display][row] & 1L<<26) == 1L<<26) col26 += 128>>row;
2566 lcRear.setRow(0, 5, col8);
2567 lcRear.setRow(1, 5, col17);
2568 lcRear.setRow(2, 5, col26);
2585 void setText(
byte disp,
const char* message)
2587 strncpy(logicText[disp], message, MAXSTRINGSIZE);
2588 logicText[disp][MAXSTRINGSIZE]=0;
2593 const int cA[] PROGMEM = { B00000110,
2599 const int cB[] PROGMEM = { B00000111,
2605 const int cC[] PROGMEM = { B00000110,
2611 const int cD[] PROGMEM = { B0000111,
2617 const int cE[] PROGMEM = { B00001111,
2623 const int cF[] PROGMEM = { B00001111,
2629 const int cG[] PROGMEM = { B00001110,
2635 const int cH[] PROGMEM = { B00001001,
2641 const int cI[] PROGMEM = { B00000111,
2647 const int cJ[] PROGMEM = { B00001000,
2653 const int cK[] PROGMEM = { B00001001,
2659 const int cL[] PROGMEM = { B00000001,
2665 const int cM[] PROGMEM = { B00010001,
2671 const int cN[] PROGMEM = { B00001001,
2677 const int cO[] PROGMEM = { B00000110,
2683 const int cP[] PROGMEM = { B00000111,
2689 const int cQ[] PROGMEM = { B00000110,
2695 const int cR[] PROGMEM = { B00000111,
2701 const int cS[] PROGMEM = { B00001110,
2706 const int cT[] PROGMEM = { B00001111,
2711 const int cU[] PROGMEM = { B00001001,
2716 const int cV[] PROGMEM = { B00001001,
2721 const int cW[] PROGMEM = { B00010001,
2726 const int cX[] PROGMEM = { B00001001,
2731 const int cY[] PROGMEM = { B00001001,
2736 const int cZ[] PROGMEM = { B00001111,
2741 const int c0[] PROGMEM = {
2748 const int c1[] PROGMEM = {
2754 const int c2[] PROGMEM = {
2760 const int c3[] PROGMEM = {
2766 const int c4[] PROGMEM = {
2772 const int c5[] PROGMEM = {
2778 const int c6[] PROGMEM = {
2784 const int c7[] PROGMEM = {
2790 const int c8[] PROGMEM = {
2796 const int c9[] PROGMEM = {
2803 const int ch[] PROGMEM = { B00110110,
2809 const int ct[] PROGMEM = { B00100010,
2815 const int cr[] PROGMEM = { B00001110,
2821 const int cd[] PROGMEM = { B00000000,
2827 const int cf[] PROGMEM = { B00000100,
2834 const int cb[] PROGMEM = { B00000000,
2841 const int cu[] PROGMEM = { B00000001,
2848 const int cn[] PROGMEM = { B00010000,
2855 const int cdot[] PROGMEM = { B00000000,
2863 void getLatinLetter(
int* letterbitmap,
char let)
2871 case 'A': pLetter=cA;
break;
2872 case 'B': pLetter=cB;
break;
2873 case 'C': pLetter=cC;
break;
2874 case 'D': pLetter=cD;
break;
2875 case 'E': pLetter=cE;
break;
2876 case 'F': pLetter=cF;
break;
2877 case 'G': pLetter=cG;
break;
2878 case 'H': pLetter=cH;
break;
2879 case 'I': pLetter=cI;
break;
2880 case 'J': pLetter=cJ;
break;
2881 case 'K': pLetter=cK;
break;
2882 case 'L': pLetter=cL;
break;
2883 case 'M': pLetter=cM;
break;
2884 case 'N': pLetter=cN;
break;
2885 case 'O': pLetter=cO;
break;
2886 case 'P': pLetter=cP;
break;
2887 case 'Q': pLetter=cQ;
break;
2888 case 'R': pLetter=cR;
break;
2889 case 'S': pLetter=cS;
break;
2890 case 'T': pLetter=cT;
break;
2891 case 'U': pLetter=cU;
break;
2892 case 'V': pLetter=cV;
break;
2893 case 'W': pLetter=cW;
break;
2894 case 'X': pLetter=cX;
break;
2895 case 'Y': pLetter=cY;
break;
2896 case 'Z': pLetter=cZ;
break;
2899 case '0': pLetter=c0;
break;
2900 case '1': pLetter=c1;
break;
2901 case '2': pLetter=c2;
break;
2902 case '3': pLetter=c3;
break;
2903 case '4': pLetter=c4;
break;
2904 case '5': pLetter=c5;
break;
2905 case '6': pLetter=c6;
break;
2906 case '7': pLetter=c7;
break;
2907 case '8': pLetter=c8;
break;
2908 case '9': pLetter=c9;
break;
2910 case '*': pLetter=ch;
break;
2911 case '#': pLetter=ct;
break;
2912 case '@': pLetter=cr;
break;
2913 case '-': pLetter=cd;
break;
2914 case '|': pLetter=cf;
break;
2915 case '.': pLetter=cdot;
break;
2917 case ' ': pLetter=cb;
break;
2918 case '<': pLetter=cu;
break;
2919 case '>': pLetter=cn;
break;
2920 default : pLetter=cb;
break;
2925 for(
byte i=0; i<5; i++)
2927 letterbitmap[i]=(int)pgm_read_word(&(pLetter[i]));
2933 const int a2[] PROGMEM = {
2939 const int aA[] PROGMEM = {
2945 const int aB[] PROGMEM = {
2951 const int aC[] PROGMEM = {
2957 const int aD[] PROGMEM = {
2963 const int aE[] PROGMEM = {
2969 const int aF[] PROGMEM = {
2975 const int aG[] PROGMEM = {
2981 const int aH[] PROGMEM = {
2987 const int aI[] PROGMEM = {
2993 const int aJ[] PROGMEM = {
2999 const int aK[] PROGMEM = {
3005 const int aL[] PROGMEM = {
3011 const int aM[] PROGMEM = {
3017 const int aN[] PROGMEM = {
3023 const int aO[] PROGMEM = {
3029 const int aP[] PROGMEM = {
3035 const int aQ[] PROGMEM = {
3041 const int aR[] PROGMEM = {
3047 const int aS[] PROGMEM = {
3053 const int aT[] PROGMEM = {
3059 const int aU[] PROGMEM = {
3065 const int aV[] PROGMEM = {
3071 const int aW[] PROGMEM = {
3077 const int aX[] PROGMEM = {
3083 const int aY[] PROGMEM = {
3089 const int aZ[] PROGMEM = {
3095 const int aZZ[] PROGMEM = {
3103 void getAurabeshLetter(
int* letterbitmap,
char let)
3111 case '2': pLetter=a2;
break;
3112 case 'A': pLetter=aA;
break;
3113 case 'B': pLetter=aB;
break;
3114 case 'C': pLetter=aC;
break;
3115 case 'D': pLetter=aD;
break;
3116 case 'E': pLetter=aE;
break;
3117 case 'F': pLetter=aF;
break;
3118 case 'G': pLetter=aG;
break;
3119 case 'H': pLetter=aH;
break;
3120 case 'I': pLetter=aI;
break;
3121 case 'J': pLetter=aJ;
break;
3122 case 'K': pLetter=aK;
break;
3123 case 'L': pLetter=aL;
break;
3124 case 'M': pLetter=aM;
break;
3125 case 'N': pLetter=aN;
break;
3126 case 'O': pLetter=aO;
break;
3127 case 'P': pLetter=aP;
break;
3128 case 'Q': pLetter=aQ;
break;
3129 case 'R': pLetter=aR;
break;
3130 case 'S': pLetter=aS;
break;
3131 case 'T': pLetter=aT;
break;
3132 case 'U': pLetter=aU;
break;
3133 case 'V': pLetter=aV;
break;
3134 case 'W': pLetter=aW;
break;
3135 case 'X': pLetter=aX;
break;
3136 case 'Y': pLetter=aY;
break;
3137 case 'Z': pLetter=aZ;
break;
3138 case ' ': pLetter=aZZ;
break;
3139 default : pLetter=aZZ;
break;
3144 for(
byte i=0; i<5; i++)
3146 letterbitmap[i]=(int)pgm_read_word(&(pLetter[i]));
3154 void drawLetter(
byte display,
char let,
int shift)
3158 if(shift < -LETTERWIDTH || shift>27)
return;
3161 int letterBitmap[5];
3164 switch(alphabetType[display])
3167 getLatinLetter(letterBitmap, let);
3170 getAurabeshLetter(letterBitmap, let);
3173 getLatinLetter(letterBitmap, let);
3181 for (
byte i=0; i<5; i++)
3184 LEDgrid[display][i] |= ((long)letterBitmap[i]) << shift;
3186 LEDgrid[display][i] |= ((long)letterBitmap[i]) >> -shift;
3196 void scrollText(
byte display,
char text[])
3198 static unsigned long previousTextScroll[3];
3201 unsigned long currentMillis = millis();
3202 if((currentMillis - previousTextScroll[display]) < SCROLLspeed)
return;
3203 previousTextScroll[display] = currentMillis;
3212 for (
unsigned int i=0; i<strlen(text); i++)
3214 int shift=i*LETTERWIDTH + scrollPositions[display];
3217 drawLetter(display, text[i], shift);
3223 scrollPositions[display]--;
3226 if (scrollPositions[display] < -LETTERWIDTH*(
int)strlen(text))
3229 if (display==2) scrollPositions[display]=27;
3230 else scrollPositions[display]=9;
3236 textScrollCount[display]++;