SHOW:
|
|
- or go back to the newest paste.
1 | // ======================================================================================= | |
2 | - | // Teeces V3.1 Sketch for Arduino Pro Micro with 2 chains |
2 | + | // ============================ Universal Dome Lighting Sketch =========================== |
3 | - | // with John V's PSI slide method (using the standard PSI LED pattern) |
3 | + | // ======================================================================================= |
4 | - | // Boards should be hooked up like this... |
4 | + | |
5 | - | // RLD OUT1 -> Rear PSI |
5 | + | // A sketch to run on an Arduino inside the dome. This runs Teeces lighting. |
6 | - | // RLD OUT2 -> FLD -> FLD -> Front PSI |
6 | + | |
7 | - | // Note: RLD OUT2 is only on the newer v3.1 boards. If you have an earlier v3.0 board |
7 | + | // Version : 2013-01-23 |
8 | - | // you can use Arduino pins 9, 8 and 7 and +5 and GND for the front chain. |
8 | + | // Added a special 'random fadey' function for CuriousMarc's Holo Light (the Input+ of |
9 | - | // If you're using an Arduino Pro Mini instead of a Pro Micro, you'll need to |
9 | + | // each Holo Light should be connected to Arduino pins 3 or 6). |
10 | - | // adjust the LedControl lines. |
10 | + | // Added support for Arduino/Adafruit Micro ( http://arduino.cc/en/Main/ArduinoBoardMicro ) |
11 | // | |
12 | // | |
13 | // Thrown together by Paul Murphy (JoyMonkey) from various sources including... | |
14 | // John V, Michael Erwin, Michael Smith, Roger Moolay, Chris Reiff and Brad Oakley | |
15 | // | |
16 | // Required : http://arduino.cc/playground/uploads/Main/LedControl.zip | |
17 | - | { |
17 | + | // (that's an Arduino Library - it needs to be downloaded and extracted into your |
18 | - | int stage; //0 thru 4 |
18 | + | // Libraries folder for this sketch to work) |
19 | // | |
20 | - | int stageDelay[5]; |
20 | + | // Logic Display and PSI Boards should be wired up in two chains (to prevent problems that |
21 | - | int cols[5]; |
21 | + | // some builders ran into when using a single chain setup for an extended period of time). |
22 | // In early 2012 a revised RLD board was released with two outputs to make wiring up in a | |
23 | // two chain setup a little easier. | |
24 | // V3.1 OUT2 uses Arduino Pro Micro or Pro Mini pins 9,8,7 for the FLDs and front PSI. | |
25 | // If you're using the older V3 RLD and don't have the OUT2 pins, don't panic! You can | |
26 | // still wire up a front chain by connecting directly to the Arduino pins. | |
27 | // | |
28 | - | PSI(int _delay1, int _delay2, int _device) |
28 | + | // If using a V3 RLD... |
29 | // RLD OUT -> Rear PSI | |
30 | // Arduino Pins 9,8,7 -> FLD IN D,C,L -> FLD -> Front PSI | |
31 | // (you will also need to supply +5V and GND to the front chain; it can go to any pins | |
32 | // labeled +5V and GND on any of the FLD or front PSI boards) | |
33 | // | |
34 | // If using a V3.1 RLD connections are a little simpler... | |
35 | // RLD OUT1 -> Rear PSI | |
36 | - | cols[0] = B11000000; |
36 | + | // RLD OUT2 -> FLD -> FLD -> Front PSI |
37 | - | cols[1] = B11100000; |
37 | + | |
38 | - | cols[2] = B01100000; |
38 | + | // This sketch will work with an Arduino Pro Micro or Pro Mini mounted to the RLD. |
39 | - | cols[3] = B01110000; |
39 | + | // The Pro Micro uses slightly different pin numbers and has additional small LEDs on it |
40 | - | cols[4] = B00110000; |
40 | + | // that we can blink back and forth to confirm it's working (I call this microPSI). |
41 | // Because of these differences this sketch needs to be edited to suit a Pro Micro or a | |
42 | - | stageDelay[0] = _delay1 - 300; |
42 | + | // Pro Mini. If using a Pro Mini, simply delete the first line of code below... |
43 | - | stageDelay[1] = 100; |
43 | + | |
44 | - | stageDelay[2] = 100; |
44 | + | // BOARDtype sets which Arduino we're using |
45 | - | stageDelay[3] = 100; |
45 | + | // 1 = Arduino Pro Mini or Uno or Duemilanove ( http://arduino.cc/en/Main/ArduinoBoardProMini ) |
46 | - | stageDelay[4] = _delay2 - 300; |
46 | + | // 2 = Sparkfun Pro Micro ( https://www.sparkfun.com/products/11098 ) |
47 | // 3 = Arduino Micro ( http://arduino.cc/en/Main/ArduinoBoardMicro ) | |
48 | #define BOARDtype 2 | |
49 | ||
50 | char text[] = "R2D2"; //PUT YOUR STARTUP TEXT HERE. (it'll scroll in aurebesh on all logics) | |
51 | ||
52 | // set brightness levels here (a value of 0-15)... | |
53 | int RLDbright=5; //rear Logic | |
54 | int RPSIbright=12; //rear PSI | |
55 | int FLDbright=5; //front Logics | |
56 | - | if (stage>4 || stage<0 ) |
56 | + | int FPSIbright=12; //front PSI |
57 | ||
58 | //delay time of logic display blinkyness (lower = blink faster) | |
59 | int LogicBlinkTime=175; | |
60 | ||
61 | //set the type of our front and rear PSI's | |
62 | - | for (int row=0; row<4; row++) |
62 | + | #define PSItype 4 |
63 | // 1 = Teeces original (6 LEDs of each color, arranged side by side) | |
64 | // 2 = Teeces original checkerboard (6 LEDs of each color arranged in a checkerboard pattern) | |
65 | // 3 = Teeces V3.2 PSI by John V (13 LEDs of each color, arranged side by side) | |
66 | // 4 = Teeces V3.2 PSI checkerboard by John V (13 LEDs of each color, in a checkerboard pattern) | |
67 | - | PSI psiFront=PSI(2500, 1700, 2); //2000 ms on red, 1000 ms on blue. device is 2 |
67 | + | |
68 | - | PSI psiRear =PSI(1700, 2500, 3); //1000 ms on yellow, 2000 ms on green. device is 3 |
68 | + | //set timing of the PSI's here (in milliseconds)... |
69 | - | LedControl lc=LedControl(14,16,10,4); //rear chain |
69 | + | int psiRed=2500; //how long front PSI stays red |
70 | - | LedControl lc2=LedControl(9,8,7,3); //front chain for v3.1 |
70 | + | int psiBlue=1700; //how long front PSI stays blue |
71 | int psiYellow=1700; //how long rear PSI stays yellow | |
72 | - | void setup() |
72 | + | int psiGreen=2500; //how long rear PSI stays green |
73 | - | { |
73 | + | int rbSlide=125; // mts - time to transition between red and blue in slide mode |
74 | - | for(int dev=0;dev<lc.getDeviceCount();dev++) |
74 | + | int ygSlide=300; // mts - time to transition between yellow and green in slide mode |
75 | ||
76 | - | lc.shutdown(dev, false); //take the device out of shutdown (power save) mode |
76 | + | //pulse the PSI Brightness (0=off, 1=Front, 2=Rear, 3=Both) |
77 | - | lc.clearDisplay(dev); |
77 | + | #define PSIPULSER 0 |
78 | ||
79 | - | for(int dev=0;dev<lc2.getDeviceCount();dev++) |
79 | + | //Use CuriousMarc's Holo Light boards in PWM mode |
80 | //(this means they'll need to be connected to pins 3 and 6) | |
81 | - | lc2.shutdown(dev, false); //take the device out of shutdown (power save) mode |
81 | + | #define CURIOUS |
82 | - | lc2.clearDisplay(dev); |
82 | + | |
83 | //#define TESTLOGICS //turns on all logic LEDs at once, useful for troubleshooting | |
84 | ||
85 | - | lc.setIntensity(0, 7); //RLD (RLD brightness is 7 by default. change to 15 for blinding bright) |
85 | + | //#define FLDx4 //for an R7 dome with 4 FLDs (if you have 4 FLDs then delete the first // ) |
86 | - | lc.setIntensity(1, 7); //RLD |
86 | + | |
87 | - | lc.setIntensity(2, 7); //RLD |
87 | + | // Most builders shouldn't have to edit anything below here. Enjoy! |
88 | - | lc.setIntensity(3, 15); //Rear PSI |
88 | + | |
89 | ||
90 | - | lc2.setIntensity(0, 5); //FLD (FLD brightness is 5 by default. change to 15 for blinding bright) |
90 | + | |
91 | - | lc2.setIntensity(1, 5); //FLD |
91 | + | |
92 | - | lc2.setIntensity(2, 15); //Front PSI |
92 | + | |
93 | // ======================================================================================= | |
94 | - | // pinMode(13, OUTPUT); |
94 | + | // ======================================================================================= |
95 | - | // digitalWrite(13, HIGH); |
95 | + | |
96 | /* | |
97 | - | //HP lights on constant |
97 | + | Different Arduino's have different pin numbers that are used for the rear chains. |
98 | - | lc.setRow(3,4,255); //rear psi |
98 | + | Arduino Pro Mini uses pins 12,11,10 for rear D,C,L |
99 | - | lc2.setRow(2,4,255); //front psi |
99 | + | Sparkfun Pro Micro uses pins 14,16,10 for rear D,C,L |
100 | Arduino Micro uses pins A2,A1,A0 for rear D,C,L | |
101 | - | pinMode(17, OUTPUT); // Set RX LED as an output |
101 | + | */ |
102 | #if (BOARDtype==1) | |
103 | #define DVAL 12 | |
104 | #define CVAL 11 | |
105 | - | void loop() |
105 | + | #define LVAL 10 |
106 | - | { |
106 | + | #elif (BOARDtype==2) |
107 | #define DVAL 14 | |
108 | - | psiFront.Animate(timeNew, lc2); |
108 | + | #define CVAL 16 |
109 | - | psiRear.Animate(timeNew, lc); |
109 | + | #define LVAL 10 |
110 | #elif (BOARDtype==3) | |
111 | #define DVAL A2 | |
112 | #define CVAL A1 | |
113 | #define LVAL A0 | |
114 | - | void animateLogic(unsigned long elapsed) |
114 | + | #endif |
115 | - | { |
115 | + | |
116 | #if defined(FLDx4) | |
117 | - | if ((elapsed - timeLast) < 200) return; |
117 | + | #define FDEV 5 //5 devices for front chain |
118 | #define FPSIDEV 4 //front PSI is device #4 in the chain | |
119 | #else | |
120 | #define FDEV 3 //3 devices for front chain | |
121 | #define FPSIDEV 2 //front PSI is device #2 in the chain | |
122 | - | lc.setRow(dev,row,random(0,256)); |
122 | + | #endif |
123 | - | for (int dev=0; dev<2; dev++) |
123 | + | |
124 | #define RPSIDEV 3 //rear PSI is device #3 in the chain | |
125 | - | lc2.setRow(dev,row,random(0,256)); |
125 | + | |
126 | //for scrolling text on logics... | |
127 | int pixelPos=27; | |
128 | - | int RXLED = 17; |
128 | + | int scrollCount=0; |
129 | - | int ledState = LOW; |
129 | + | //virtual coords are 5x45; device coords are 3 panels 6x8 each |
130 | unsigned long v_grid[5]; //this will give 5x40 bits | |
131 | - | void microPSI(unsigned long elapsed) |
131 | + | |
132 | - | { |
132 | + | |
133 | #undef round | |
134 | ||
135 | //START UP LEDCONTROL... | |
136 | - | timeLast = elapsed; |
136 | + | LedControl lcRear=LedControl(DVAL,CVAL,LVAL,4); //rear chain (Pro Mini/Pro Micro pins) |
137 | - | // if the LED is off turn it on and vice-versa: |
137 | + | LedControl lcFront=LedControl(9,8,7,FDEV); //front chain |
138 | - | if (ledState == LOW) { |
138 | + | |
139 | - | ledState = HIGH; |
139 | + | // ======================================================================================= |
140 | - | digitalWrite(17, HIGH); // set the LED on |
140 | + | #if (PSItype==4) // slide animation code for Teeces V2 PSI boards (code by John V) |
141 | - | TXLED1; //TX LED is not tied to a normally controlled pin |
141 | + | #define HPROW 5 |
142 | class PSI { | |
143 | - | else { |
143 | + | int stage; //0 thru 6 |
144 | - | ledState = LOW; |
144 | + | |
145 | - | digitalWrite(17, LOW); // set the LED off |
145 | + | int stageDelay[7]; |
146 | - | TXLED0; |
146 | + | int cols[7][5]; |
147 | int randNumber; //a random number to decide the fate of the last stage | |
148 | - | //} |
148 | + | |
149 | - | } |
149 | + | |
150 | int device; | |
151 | ||
152 | public: | |
153 | ||
154 | PSI(int _delay1, int _delay2, int _delay3, int _device) | |
155 | { | |
156 | device=_device; | |
157 | ||
158 | stage=0; | |
159 | timeLast=0; | |
160 | inc=1; | |
161 | ||
162 | cols[0][0] = B10101000; | |
163 | cols[0][1] = B01010100; | |
164 | cols[0][2] = B10101000; | |
165 | cols[0][3] = B01010100; | |
166 | cols[0][4] = B10101000; | |
167 | ||
168 | cols[1][0] = B00101000; //R B R B R B | |
169 | cols[1][1] = B11010100; //B R B R B R | |
170 | cols[1][2] = B00101000; //R B R B R B | |
171 | cols[1][3] = B11010100; //B R B R B R | |
172 | cols[1][4] = B00101000; //R B R B R B | |
173 | ||
174 | cols[2][0] = B01101000; | |
175 | cols[2][1] = B10010100; | |
176 | cols[2][2] = B01101000; | |
177 | cols[2][3] = B10010100; | |
178 | cols[2][4] = B01101000; | |
179 | ||
180 | cols[3][0] = B01001000; | |
181 | cols[3][1] = B10110100; | |
182 | cols[3][2] = B01001000; | |
183 | cols[3][3] = B10110100; | |
184 | cols[3][4] = B01001000; | |
185 | ||
186 | cols[4][0] = B01011000; | |
187 | cols[4][1] = B10100100; | |
188 | cols[4][2] = B01011000; | |
189 | cols[4][3] = B10100100; | |
190 | cols[4][4] = B01011000; | |
191 | ||
192 | cols[5][0] = B01010000; | |
193 | cols[5][1] = B10101100; | |
194 | cols[5][2] = B01010000; | |
195 | cols[5][3] = B10101100; | |
196 | cols[5][4] = B01010000; | |
197 | ||
198 | cols[6][0] = B01010100; | |
199 | cols[6][1] = B10101000; | |
200 | cols[6][2] = B01010100; | |
201 | cols[6][3] = B10101000; | |
202 | cols[6][4] = B01010100; | |
203 | ||
204 | stageDelay[0] = _delay1 - _delay3; | |
205 | stageDelay[1] = _delay3/5; | |
206 | stageDelay[2] = _delay3/5; | |
207 | stageDelay[3] = _delay3/5; | |
208 | stageDelay[4] = _delay3/5; | |
209 | stageDelay[5] = _delay3/5; | |
210 | stageDelay[6] = _delay2 - _delay3; | |
211 | } | |
212 | ||
213 | void Animate(unsigned long elapsed, LedControl control) | |
214 | { | |
215 | if ((elapsed - timeLast) < stageDelay[stage]) return; | |
216 | ||
217 | timeLast = elapsed; | |
218 | stage+=inc; | |
219 | ||
220 | if (stage>6 || stage<0 ) | |
221 | { | |
222 | inc *= -1; | |
223 | stage+=inc*2; | |
224 | } | |
225 | ||
226 | if (stage==6) //randomly choose whether or not to go 'stuck' | |
227 | { | |
228 | randNumber = random(9); | |
229 | if (randNumber<5) { //set the last stage to 'stuck' | |
230 | cols[6][0] = B01010000; | |
231 | cols[6][1] = B10101100; | |
232 | cols[6][2] = B01010000; | |
233 | cols[6][3] = B10101100; | |
234 | cols[6][4] = B01010000; | |
235 | } | |
236 | else //reset the last stage to a solid color | |
237 | { | |
238 | cols[6][0] = B01010100; | |
239 | cols[6][1] = B10101000; | |
240 | cols[6][2] = B01010100; | |
241 | cols[6][3] = B10101000; | |
242 | cols[6][4] = B01010100; | |
243 | } | |
244 | } | |
245 | if (stage==0) //randomly choose whether or not to go 'stuck' | |
246 | { | |
247 | randNumber = random(9); | |
248 | if (randNumber<5) { //set the first stage to 'stuck' | |
249 | cols[0][0] = B00101000; //R B R B R B | |
250 | cols[0][1] = B11010100; //B R B R B R | |
251 | cols[0][2] = B00101000; //R B R B R B | |
252 | cols[0][3] = B11010100; //B R B R B R | |
253 | cols[0][4] = B00101000; //R B R B R B | |
254 | } | |
255 | else //reset the first stage to a solid color | |
256 | { | |
257 | cols[0][0] = B10101000; | |
258 | cols[0][1] = B01010100; | |
259 | cols[0][2] = B10101000; | |
260 | cols[0][3] = B01010100; | |
261 | cols[0][4] = B10101000; | |
262 | } | |
263 | } | |
264 | ||
265 | for (int row=0; row<5; row++) | |
266 | control.setRow(device,row,cols[stage][row]); | |
267 | } | |
268 | }; | |
269 | ||
270 | #endif | |
271 | ||
272 | // ======================================================================================= | |
273 | #if (PSItype==3) // slide animation code for Teeces V2 PSI boards (code by John V) | |
274 | #define HPROW 5 | |
275 | class PSI { | |
276 | int stage; //0 thru 6 | |
277 | int inc; | |
278 | int stageDelay[7]; | |
279 | int cols[7]; | |
280 | ||
281 | unsigned long timeLast; | |
282 | int device; | |
283 | ||
284 | public: | |
285 | ||
286 | PSI(int _delay1, int _delay2, int _delay3, int _device) | |
287 | { | |
288 | device=_device; | |
289 | ||
290 | stage=0; | |
291 | timeLast=0; | |
292 | inc=1; | |
293 | ||
294 | cols[0] = B11100000; | |
295 | cols[1] = B11110000; | |
296 | cols[2] = B01110000; | |
297 | cols[3] = B01111000; | |
298 | cols[4] = B00111000; | |
299 | cols[5] = B00111100; | |
300 | cols[6] = B00011100; | |
301 | ||
302 | stageDelay[0] = _delay1 - _delay3; | |
303 | stageDelay[1] = _delay3/5; | |
304 | stageDelay[2] = _delay3/5; | |
305 | stageDelay[3] = _delay3/5; | |
306 | stageDelay[4] = _delay3/5; | |
307 | stageDelay[5] = _delay3/5; | |
308 | stageDelay[6] = _delay2 - _delay3; | |
309 | } | |
310 | void Animate(unsigned long elapsed, LedControl control) | |
311 | { | |
312 | if ((elapsed - timeLast) < stageDelay[stage]) return; | |
313 | ||
314 | timeLast = elapsed; | |
315 | stage+=inc; | |
316 | ||
317 | if (stage>6 || stage<0 ) | |
318 | { | |
319 | inc *= -1; | |
320 | stage+=inc*2; | |
321 | } | |
322 | ||
323 | for (int row=0; row<5; row++) | |
324 | control.setRow(device,row,cols[stage]); | |
325 | } | |
326 | }; | |
327 | #endif | |
328 | // ======================================================================================= | |
329 | //michael smith's checkerboard PSI method for Teeces original PSI boards | |
330 | // Michael's original sketch is here : http://pastebin.com/hXeZb7Gd | |
331 | #if (PSItype==2) | |
332 | #define HPROW 4 | |
333 | static const int patternAtStage[] = { B01010000, B11010000, B10010000, B10110000, B10100000, B00100000, B01100000, B01000000, B01010000 }; | |
334 | class PSI | |
335 | { | |
336 | bool state; | |
337 | int stage; | |
338 | unsigned long timeLast; | |
339 | int delay1, delay2, delay3; | |
340 | int device; | |
341 | int delayAtStage[9]; | |
342 | int slideDirection; // is either 1 or -1 | |
343 | int maxStage; // for PSIslide it's either 5 or 9 stages, for traditional PSI it's just back and forth between 2 | |
344 | public: | |
345 | PSI(int _delay1, int _delay2, int _delay3, int _device) | |
346 | { | |
347 | delayAtStage[0] = _delay1; | |
348 | delayAtStage[1] = _delay3/3; // delay3 is total transition time - divide it by the 3 stages of transition | |
349 | delayAtStage[2] = delayAtStage[1]; | |
350 | delayAtStage[3] = delayAtStage[1]; | |
351 | delayAtStage[4] = _delay2; | |
352 | delayAtStage[5] = delayAtStage[1]; | |
353 | delayAtStage[6] = delayAtStage[1]; | |
354 | delayAtStage[7] = delayAtStage[1]; | |
355 | delayAtStage[8] = _delay1; // repeated because it's not a loop it cycles back and forth across the pattern. | |
356 | stage=0; | |
357 | slideDirection=1; | |
358 | maxStage=8; // change to 5 would skip the LtoR from blue to red. | |
359 | timeLast=0; | |
360 | device=_device; | |
361 | // legacy for traditional PSI animation | |
362 | delay1=_delay1; | |
363 | delay2=_delay2; | |
364 | delay3=_delay3; | |
365 | state=false; | |
366 | } | |
367 | void Animate(unsigned long timeNow, LedControl control) | |
368 | { | |
369 | if ((timeNow - timeLast) < delayAtStage[stage]) return; | |
370 | //Serial.begin(9600); | |
371 | //Serial.println(stage); | |
372 | //Serial.println(patternAtStage[stage]); | |
373 | timeLast = timeNow; | |
374 | stage+=slideDirection; //move to the next stage, which could be up or down in the array | |
375 | if (stage >= maxStage) | |
376 | { | |
377 | // limit the stage to the maxStage and reverse the direction of the slide | |
378 | stage=maxStage; | |
379 | slideDirection = -1; | |
380 | } | |
381 | else if (stage <= 0) | |
382 | { | |
383 | stage=0; | |
384 | slideDirection = 1; | |
385 | } | |
386 | // set the patterns for this stage | |
387 | control.setRow(device,0,patternAtStage[stage]); | |
388 | control.setRow(device,1,~patternAtStage[stage]); | |
389 | control.setRow(device,2,patternAtStage[stage]); | |
390 | control.setRow(device,3,~patternAtStage[stage]); | |
391 | } | |
392 | }; | |
393 | #endif | |
394 | // ======================================================================================= | |
395 | // slide animation code for Teeces original PSI boards | |
396 | #if (PSItype==1) | |
397 | #define HPROW 4 | |
398 | class PSI { | |
399 | int stage; //0 thru 4 | |
400 | int inc; | |
401 | int stageDelay[5]; | |
402 | int cols[5]; | |
403 | unsigned long timeLast; | |
404 | int device; | |
405 | public: | |
406 | PSI(int _delay1, int _delay2, int _device) { | |
407 | device=_device; | |
408 | stage=0; | |
409 | timeLast=0; | |
410 | inc=1; | |
411 | cols[0] = B11000000; | |
412 | cols[1] = B11100000; | |
413 | cols[2] = B01100000; | |
414 | cols[3] = B01110000; | |
415 | cols[4] = B00110000; | |
416 | stageDelay[0] = _delay1 - 300; | |
417 | stageDelay[1] = 100; | |
418 | stageDelay[2] = 100; | |
419 | stageDelay[3] = 100; | |
420 | stageDelay[4] = _delay2 - 300; | |
421 | } | |
422 | void Animate(unsigned long elapsed, LedControl control) { | |
423 | if ((elapsed - timeLast) < stageDelay[stage]) return; | |
424 | timeLast = elapsed; | |
425 | stage+=inc; | |
426 | if (stage>4 || stage<0 ) { | |
427 | inc *= -1; | |
428 | stage+=inc*2; | |
429 | } | |
430 | for (int row=0; row<4; row++) control.setRow(device,row,cols[stage]); | |
431 | } | |
432 | }; | |
433 | #endif | |
434 | // ======================================================================================= | |
435 | #if (PSItype==1) | |
436 | PSI psiFront=PSI(psiRed, psiBlue, FPSIDEV); // device is FPSIDEV (#2 or #4 for an R7 dome) | |
437 | PSI psiRear =PSI(psiYellow, psiGreen, RPSIDEV); // device is #3 | |
438 | //#endif | |
439 | //#if (PSItype==2) || (PSItype==3) | |
440 | #else | |
441 | PSI psiFront=PSI(psiRed, psiBlue, rbSlide, FPSIDEV); //2000 ms on red, 1000 ms on blue. | |
442 | PSI psiRear =PSI(psiYellow, psiGreen, ygSlide, RPSIDEV); //1000 ms on yellow, 2000 ms on green. | |
443 | #endif | |
444 | // ======================================================================================= | |
445 | void setup() { | |
446 | Serial.begin(9600); //used for debugging | |
447 | for(int dev=0;dev<lcRear.getDeviceCount();dev++) { | |
448 | lcRear.shutdown(dev, false); //take the device out of shutdown (power save) mode | |
449 | lcRear.clearDisplay(dev); | |
450 | } | |
451 | for(int dev=0;dev<lcFront.getDeviceCount();dev++) { | |
452 | lcFront.shutdown(dev, false); //take the device out of shutdown (power save) mode | |
453 | lcFront.clearDisplay(dev); | |
454 | } | |
455 | //set intensity of devices in rear chain... | |
456 | lcRear.setIntensity(0, RLDbright); //RLD | |
457 | lcRear.setIntensity(1, RLDbright); //RLD | |
458 | lcRear.setIntensity(2, RLDbright); //RLD | |
459 | lcRear.setIntensity(3, RPSIbright); //Rear PSI | |
460 | //set intensity of devices in front chain... | |
461 | for(int dev=0;dev<(lcFront.getDeviceCount()-1);dev++) { | |
462 | lcFront.setIntensity(dev, FLDbright); //front logics (all but the last dev in chain) | |
463 | } | |
464 | lcFront.setIntensity(FPSIDEV, FPSIbright); //Front PSI | |
465 | //HP lights on constantly... | |
466 | lcRear.setRow(RPSIDEV,HPROW,255); //rear psi | |
467 | lcFront.setRow(FPSIDEV,HPROW,255); //front psi | |
468 | ||
469 | #if (BOARDtype==2) | |
470 | pinMode(17, OUTPUT); // Set RX LED of Pro Micro as an output | |
471 | #endif | |
472 | ||
473 | #if defined(CURIOUS) | |
474 | pinMode(3, OUTPUT); | |
475 | pinMode(6, OUTPUT); | |
476 | #endif | |
477 | ||
478 | } | |
479 | // ======================================================================================= | |
480 | void loop() { | |
481 | // | |
482 | if (text!="") { //if startup text isn't empty, lets scroll! | |
483 | initGrid(); | |
484 | if (scrollCount==0) { | |
485 | scrollingText(); | |
486 | delay(60); | |
487 | return; | |
488 | } | |
489 | } | |
490 | // | |
491 | unsigned long timeNew= millis(); | |
492 | psiFront.Animate(timeNew, lcFront); | |
493 | psiRear.Animate(timeNew, lcRear); | |
494 | animateLogic(timeNew); | |
495 | #if (BOARDtype==2) | |
496 | microPSI(timeNew); | |
497 | #endif | |
498 | #if PSIPULSER>0 | |
499 | PSIpulse(timeNew); | |
500 | #endif | |
501 | #if defined(CURIOUS) | |
502 | CuriousFade(timeNew); | |
503 | #endif | |
504 | } | |
505 | // ======================================================================================= | |
506 | // this is the code to blink all the logic LEDs randomly... | |
507 | void animateLogic(unsigned long elapsed) { | |
508 | static unsigned long timeLast=0; | |
509 | if ((elapsed - timeLast) < LogicBlinkTime) return; | |
510 | timeLast = elapsed; | |
511 | #if defined(TESTLOGICS) | |
512 | //turn on all logic LEDs to make sure they're all working | |
513 | for (int dev=0; dev<3; dev++) | |
514 | for (int row=0; row<6; row++) | |
515 | lcRear.setRow(dev,row,255); | |
516 | for (int dev=0; dev<FPSIDEV; dev++) | |
517 | for (int row=0; row<6; row++) | |
518 | lcFront.setRow(dev,row,255); | |
519 | #else | |
520 | //do the usual blinkyness | |
521 | for (int dev=0; dev<3; dev++) | |
522 | for (int row=0; row<6; row++) | |
523 | lcRear.setRow(dev,row,random(0,256)); | |
524 | for (int dev=0; dev<FPSIDEV; dev++) | |
525 | for (int row=0; row<6; row++) | |
526 | lcFront.setRow(dev,row,random(0,256)); | |
527 | #endif | |
528 | } | |
529 | // ======================================================================================= | |
530 | // PULSING PSI LED BRIGHTNESS/INTENSITY | |
531 | #if PSIPULSER>0 | |
532 | int pulseState = LOW; //initial state of our PSI (high intensity, going down) | |
533 | int pulseVal = 15; //initial value of our PSI (full intensity) | |
534 | void PSIpulse(unsigned long elapsed) { | |
535 | static unsigned long timeLast=0; | |
536 | if ((elapsed - timeLast) < 100) return; //proceed if 100 milliseconds have passed | |
537 | timeLast = elapsed; | |
538 | if (pulseState == HIGH) { //increase intensity | |
539 | pulseVal++; //increase value by 1 | |
540 | if (pulseVal == 16) { //if we've gone beyond full intensity, start going down again | |
541 | pulseVal = 15; | |
542 | pulseState = LOW; | |
543 | } | |
544 | } | |
545 | else { //decrease intensity | |
546 | pulseVal--; //increase value by 1 | |
547 | if (pulseVal == 0) { //if we've gone beyond full intensity, start going down again | |
548 | pulseVal = 1; | |
549 | pulseState = HIGH; | |
550 | } | |
551 | } | |
552 | #if PSIPULSER==1 || PSIPULSER==3 | |
553 | lcFront.setIntensity(2,pulseVal); //set the front intensity | |
554 | #endif | |
555 | #if PSIPULSER==2 || PSIPULSER==3 | |
556 | lcRear.setIntensity(3,pulseVal); //set the rear intensity | |
557 | #endif | |
558 | } | |
559 | #endif | |
560 | //////////////////////////////////// | |
561 | ||
562 | // ======================================================================================= | |
563 | // PULSE THE BRIGHTNESS OF THE CURIOUS MARC HOLO LIGHTS | |
564 | #if defined(CURIOUS) | |
565 | int Cbrightness = 0; // how bright the LED starts at | |
566 | int CfadeAmount = 1; // how many points to fade the LED by | |
567 | int holdtime=1000; //default 'pause' is set to 5 seconds | |
568 | int fadespeed=1; //milliseconds to wait between actions (lower number speeds things up) | |
569 | void CuriousFade(unsigned long elapsed) { | |
570 | analogWrite(3, Cbrightness); | |
571 | analogWrite(6, Cbrightness); | |
572 | static unsigned long timeLast=0; | |
573 | if ((elapsed - timeLast) < (fadespeed + holdtime)) return; //proceed if some fadespeed+holdtime milliseconds have passed | |
574 | timeLast = elapsed; | |
575 | holdtime = 0; | |
576 | Cbrightness = Cbrightness + CfadeAmount; | |
577 | if (Cbrightness == 0 || Cbrightness == 255) { | |
578 | CfadeAmount = -CfadeAmount ; //reverse fade direction | |
579 | holdtime = random(9)*1000; //generate a new 'pause' time of 0 to 9 seconds | |
580 | fadespeed = random(1,20); //generate a new fadespeed time of 1 to 20 milliseconds | |
581 | } | |
582 | } | |
583 | #endif | |
584 | //////////////////////////////////// | |
585 | ||
586 | ||
587 | // ======================================================================================= | |
588 | // AUREBESH CHARACTERS TAKEN FROM MOOLAY'S SKETCH | |
589 | // http://astromech.net/forums/showthread.php?p=99487 | |
590 | void showGrid() { | |
591 | //copy from virt coords to device coords | |
592 | unsigned char col8=0; | |
593 | unsigned char col17=0; | |
594 | unsigned char col26=0; | |
595 | for (int row=0; row<5; row++) { | |
596 | lcRear.setRow(0,row, rev( v_grid[row] & 255L ) ); //device 0 | |
597 | lcRear.setRow(1,row, rev( (v_grid[row] & 255L<<9) >> 9 ) ); //device 1 | |
598 | lcRear.setRow(2,row, rev( (v_grid[row] & 255L<<18) >> 18 ) ); //device 2 | |
599 | lcFront.setRow(0,row, rev( v_grid[row] & 255L ) ); //device 0 | |
600 | lcFront.setRow(1,row, rev( (v_grid[row] & 255L<<9) >> 9 ) ); //device 1 | |
601 | if ( (v_grid[row] & 1L<<8) == 1L<<8) col8 += 128>>row; | |
602 | if ( (v_grid[row] & 1L<<17) == 1L<<17) col17 += 128>>row; | |
603 | if ( (v_grid[row] & 1L<<26) == 1L<<26) col26 += 128>>row; | |
604 | } | |
605 | lcRear.setRow(0, 5, col8); | |
606 | lcRear.setRow(1, 5, col17); | |
607 | lcRear.setRow(2, 5, col26); | |
608 | lcFront.setRow(0, 5, col8); | |
609 | lcFront.setRow(1, 5, col17); | |
610 | } | |
611 | unsigned char rev(unsigned char b) { | |
612 | //reverse bits of a byte | |
613 | return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; | |
614 | } | |
615 | void initGrid() { | |
616 | for (int row=0; row<6; row++) v_grid[row]=0L; | |
617 | } | |
618 | int c2[] = { | |
619 | B00001111, | |
620 | B00001001, | |
621 | B00000100, | |
622 | B00001001, | |
623 | B00001111 }; | |
624 | int cA[] = { | |
625 | B00010001, | |
626 | B00001111, | |
627 | B00000000, | |
628 | B00001111, | |
629 | B00010001 }; | |
630 | int cB[] = { | |
631 | B00001110, | |
632 | B00010001, | |
633 | B00001110, | |
634 | B00010001, | |
635 | B00001110 }; | |
636 | int cC[] = { | |
637 | B00000001, | |
638 | B00000001, | |
639 | B00000100, | |
640 | B00010000, | |
641 | B00010000 }; | |
642 | int cD[] = { | |
643 | B00011111, | |
644 | B00001000, | |
645 | B00000111, | |
646 | B00000010, | |
647 | B00000001 }; | |
648 | int cE[] = { | |
649 | B00011001, | |
650 | B00011001, | |
651 | B00011001, | |
652 | B00010110, | |
653 | B00010100 }; | |
654 | int cF[] = { | |
655 | B00010000, | |
656 | B00001010, | |
657 | B00000111, | |
658 | B00000011, | |
659 | B00011111 }; | |
660 | int cG[] = { | |
661 | B00011101, | |
662 | B00010101, | |
663 | B00010001, | |
664 | B00001001, | |
665 | B00000111 }; | |
666 | int cH[] = { | |
667 | B00011111, | |
668 | B00000000, | |
669 | B00001110, | |
670 | B00000000, | |
671 | B00011111 }; | |
672 | int cI[] = { | |
673 | B00000100, | |
674 | B00000110, | |
675 | B00000100, | |
676 | B00000100, | |
677 | B00000100 }; | |
678 | int cJ[] = { | |
679 | B00010000, | |
680 | B00011000, | |
681 | B00001111, | |
682 | B00000100, | |
683 | B00000011 }; | |
684 | int cK[] = { | |
685 | B00011111, | |
686 | B00010000, | |
687 | B00010000, | |
688 | B00010000, | |
689 | B00011111 }; | |
690 | int cL[] = { | |
691 | B00010000, | |
692 | B00010001, | |
693 | B00010010, | |
694 | B00010100, | |
695 | B00011000 }; | |
696 | int cM[] = { | |
697 | B00011100, | |
698 | B00010010, | |
699 | B00000001, | |
700 | B00010001, | |
701 | B00011111 }; | |
702 | int cN[] = { | |
703 | B00001010, | |
704 | B00010101, | |
705 | B00010101, | |
706 | B00010011, | |
707 | B00010010 }; | |
708 | int cO[] = { | |
709 | B00000000, | |
710 | B00001110, | |
711 | B00010001, | |
712 | B00010001, | |
713 | B00011111 }; | |
714 | int cP[] = { | |
715 | B00010110, | |
716 | B00010101, | |
717 | B00010001, | |
718 | B00010001, | |
719 | B00011110 }; | |
720 | int cQ[] = { | |
721 | B00011111, | |
722 | B00010001, | |
723 | B00000001, | |
724 | B00000001, | |
725 | B00000111 }; | |
726 | int cR[] = { | |
727 | B00011111, | |
728 | B00001000, | |
729 | B00000100, | |
730 | B00000010, | |
731 | B00000001 }; | |
732 | int cS[] = { | |
733 | B00010000, | |
734 | B00010010, | |
735 | B00010101, | |
736 | B00011010, | |
737 | B00010100 }; | |
738 | int cT[] = { | |
739 | B00001111, | |
740 | B00000010, | |
741 | B00000010, | |
742 | B00000010, | |
743 | B00000010 }; | |
744 | int cU[] = { | |
745 | B00000100, | |
746 | B00000100, | |
747 | B00010101, | |
748 | B00001110, | |
749 | B00000100 }; | |
750 | int cV[] = { | |
751 | B00010001, | |
752 | B00001010, | |
753 | B00000100, | |
754 | B00000100, | |
755 | B00000100 }; | |
756 | int cW[] = { | |
757 | B00011111, | |
758 | B00010001, | |
759 | B00010001, | |
760 | B00010001, | |
761 | B00011111 }; | |
762 | int cX[] = { | |
763 | B00000100, | |
764 | B00001010, | |
765 | B00010001, | |
766 | B00010001, | |
767 | B00011111 }; | |
768 | int cY[] = { | |
769 | B00010011, | |
770 | B00010101, | |
771 | B00001010, | |
772 | B00001010, | |
773 | B00000100 }; | |
774 | int cZ[] = { | |
775 | B00010110, | |
776 | B00010101, | |
777 | B00010000, | |
778 | B00010001, | |
779 | B00011111 }; | |
780 | int cZZ[] = { | |
781 | B00000000, | |
782 | B00000000, | |
783 | B00000000, | |
784 | B00000000, | |
785 | B00000000 }; | |
786 | int co[] = { | |
787 | B01010101, | |
788 | B01010101, | |
789 | B01010101, | |
790 | B01010101, | |
791 | B01010101 }; | |
792 | void drawLetter(char let, int shift) { | |
793 | int *pLetter; | |
794 | switch (let) { | |
795 | case '2': pLetter=c2; break; | |
796 | case 'A': pLetter=cA; break; | |
797 | case 'B': pLetter=cB; break; | |
798 | case 'C': pLetter=cC; break; | |
799 | case 'D': pLetter=cD; break; | |
800 | case 'E': pLetter=cE; break; | |
801 | case 'F': pLetter=cF; break; | |
802 | case 'G': pLetter=cG; break; | |
803 | case 'H': pLetter=cH; break; | |
804 | case 'I': pLetter=cI; break; | |
805 | case 'J': pLetter=cJ; break; | |
806 | case 'K': pLetter=cK; break; | |
807 | case 'L': pLetter=cL; break; | |
808 | case 'M': pLetter=cM; break; | |
809 | case 'N': pLetter=cN; break; | |
810 | case 'O': pLetter=cO; break; | |
811 | case 'P': pLetter=cP; break; | |
812 | case 'Q': pLetter=cQ; break; | |
813 | case 'R': pLetter=cR; break; | |
814 | case 'S': pLetter=cS; break; | |
815 | case 'T': pLetter=cT; break; | |
816 | case 'U': pLetter=cU; break; | |
817 | case 'V': pLetter=cV; break; | |
818 | case 'W': pLetter=cW; break; | |
819 | case 'X': pLetter=cX; break; | |
820 | case 'Y': pLetter=cY; break; | |
821 | case 'Z': pLetter=cZ; break; | |
822 | case '_': pLetter=cZZ; break; | |
823 | default:return; | |
824 | } | |
825 | //loop thru rows of the letter | |
826 | for (int i=0; i<5; i++) { | |
827 | if (shift>0) //positive shift means letter is slid to the right on the display | |
828 | v_grid[i] += (long)pLetter[i] << shift; | |
829 | else //negative shift means letter is slid to the left so that only part of it is visible | |
830 | v_grid[i] += (long)pLetter[i] >> -shift; | |
831 | } | |
832 | } | |
833 | void scrollingText() { | |
834 | for (int i=0; i<strlen(text); i++) { | |
835 | drawLetter(text[i], i*5 + pixelPos); | |
836 | } | |
837 | pixelPos--; | |
838 | if (pixelPos < -5*(int)strlen(text)) { | |
839 | pixelPos=27; | |
840 | scrollCount++; | |
841 | } | |
842 | showGrid(); | |
843 | } | |
844 | ||
845 | // ======================================================================================= | |
846 | // this is the code to flash the Pro Micro's green and yellow LEDs back and fourth... | |
847 | #if (BOARDtype==2) | |
848 | int ledState = LOW; //initial state of our Pro Micro microPSI function | |
849 | void microPSI(unsigned long elapsed) { | |
850 | //blink the ProMicro's TX and RX LEDs back and forth | |
851 | static unsigned long timeLast=0; | |
852 | if ((elapsed - timeLast) < 2000) return; | |
853 | timeLast = elapsed; | |
854 | // if the LED is off turn it on and vice-versa: | |
855 | if (ledState == LOW) { | |
856 | ledState = HIGH; | |
857 | digitalWrite(17, HIGH); // set the RX LED on | |
858 | TXLED1; //TX LED is not tied to a normally controlled pin | |
859 | } | |
860 | else { | |
861 | ledState = LOW; | |
862 | digitalWrite(17, LOW); // set the RX LED off | |
863 | TXLED0; | |
864 | } | |
865 | } | |
866 | #endif | |
867 | // ======================================================================================= |