View difference between Paste ID: RYP1qmWH and 3Vyc9Htb
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
// =======================================================================================