Arduino Projekten

Sat 20-Apr-24
07:08:03


Interupted Wallpapers

Datum: Sun 16 March 2014
Samenvatting: Ge-interupt Behang op de panelen.


De twee vorige programma's ("Random Figuren" en "Interupt en 8 Led's") zijn met elkaar gecombineerd. Op zich duurde het combineren kort, maar wat een genot om trillingsvrij beeld te hebben EN een korte [loop()] funktie.

Het initialiseren van de timer is, om het overzichtelijk te houden, in een aparte funktie geplaatst, genaamd [InitTimer()]. Dit is dezelfde funktie als in het [Interupt en 8 Led's] projekt. En uiteraard is er geëxperimenteerd met de timer-waarde in de regel:
OCR1A = 5200; // set Output Compare Register 1 to the desired timer count

Wordt dit getal te klein, dan bljft er te weinig tijd over voor het hoofdprogramma vlot te laten lopen. Als dit getal veel te klein wordt, dan zou het hoofdprogramma helemaal geen tijd meer krijgen.

Wordt dit getal te groot, dan gaat het beeld weer (irritant) knipperen. Als dit getal echter veel te groot wordt, dan wordt het zichtbaar dat het beeld echt lijn voor lijn wordt getoond.

Experimenteel zijn de volgende getallen gevonden (afgerond op 100-tallen):
Prescaler = 1 (0b0000 0001)  
lager dan
3300
Stap voor stap opbouw van het behang.
3400
3300
Het behang wordt zichtbaar, doch vloeiend opgebouwd.
3600
5600
Opbouw in 1 keer, knippervrij beeld.
6000
en hoger
Knipperend beeld. Hoe hoger, hoe irritanter het knipperen wordt.
Geen grenswaarde bepaald
50000 en hoger
Het beeld wordt lijn voor lijn (per 2 lijnen) getoond.

De eigenlijke beeldopbouw funktie [IntOneRow()] heeft een andere naam moeten krijgen [ISR(TIMER1_COMPA_vect)]. Dezelfde naam als beschreven wordt in de vele voorbeelden.

Het programma

Voor veel funkties verwijs ik naar het project van Random Figuren. Er is hier wel wat bijgekomen.

Bgcolor - de achtergrondkleur

Voor de achtergrondkleur is de variabele [bgcolor] aangepast. De eigenlijke variabele heet nu [_bgcolor]. De inhoud ervan kan worden veranderd door de funktie [Setbgcolor] (en doet meteen een kleine controle). Deze kan worden uitgelezen met [bgcolor()].

Aanvullingen

Natuurlijk heb ik weer creatieve uitbreidingen aangebracht met de drie potmeters (nr 4, 5, 6).

  • Potmeter 6: is geprogrammeerd voor de wisselsnelheden van de wallpapers.
  • Potmeter 5: heeft de achtergrondkleur als funktie gekregen en wel in puur RGB/CYMW (dus inclusief de binaire mengkleuren van RGB: CYMW), inclusief hun 8 tinten (inclusief Zwart).
  • Potmeter 4: zorgt voor de achtergrond in 4 standen: wisselen, behang 1, behang 2, alleen achtergrondkleur.

Eind conclusie

Als eindconclusie is te stellen dat mijn einddoel wel gehaald is. De RGB-Panelen heb ik aangestuurd gekregen. En hierbij wordt een interupt gebruikt. Wat nu rest is het in een eigen library stoppen van deze aansturing.

Daarna zijn projekten te maken om de panelen nuttig in te zetten. Daar vallen ook character-schrijvende funkties onder.


Broncode: [1: Interupted Wallpapers]

1: De broncode van Interupted Wallpapers

(Sat 03 May 2014)
Deze broncode heeft 349 regels met programma-code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
//     ---------------------------------------------------------
//     |  Experimentation Kit for Arduino Example Code         |
//     |  RGBMatrix : RGB Matrix - Interupted WallPapers       |
//     ---------------------------------------------------------

// Some Pot-vars
word pot_del   = 0;
word pot_kleur = 0;
word pot_num   = 0;
byte wp_count  = 0;

void setup()
{ InitPan(0x0777);
  wp_count = 0;
  Serial.begin(115200);
}

void loop()
{ read_pots();
  switch (wp_count)
    { case 0 : Behang1();
               break;
      case 1 : Behang2();
               break;
      case 2 : ClrPan();
               break;
    }
  delay (pot_del);
  Setbgcolor (pot_kleur);

  switch (pot_num)
    { case 0 :  wp_count = wp_count + 1;
                if (wp_count > 1)
                  { wp_count=0; }
                break;
      case 1 :  wp_count = 0;
                break;
      case 2 :  wp_count = 1;
                break;
      case 3 :  wp_count = 2;
                break;
    }
}

void read_pots()
{ const word kleurwaaier [8] = {0x0000, 0x0001, 0x0010, 0x0011, 0x0100, 0x0101, 0x0110, 0x0111};
  word pot_kleur_hi = 0;
  word pot_kleur_lo = 0;
  pot_del   = analogRead(5) * 16;
  word pot_kleur_pot = analogRead(4) / 16;
  pot_kleur_lo = ( pot_kleur_pot & 0x0007 );      // 0b 0000 0111
  pot_kleur_hi = ( pot_kleur_pot & 0x0038 ) >> 3; // 0b 0011 1000
  while (pot_kleur_hi == 0)
    { // When main-color is black => take a random color
      pot_kleur_hi = random(7) +1;
    }
  pot_kleur = kleurwaaier[pot_kleur_hi] * pot_kleur_lo ;
  pot_num   = analogRead(3) / 256;
}

void Behang1()
{ for ( byte qy=0; qy<=15; qy=qy+1 )
    { for ( byte qx=0; qx<=63; qx=qx+2 )
        { word qk = Dec2RGB ( 8 * qx ) + qy );
          SetPoint (qx  ,qy, qk );
          SetPoint (qx+1,qy, qk );
        }
    }
}

void Behang2()
{
  // Zwart
  Cirkel (  0+ 0 ,  0+ 0 , 0x0000 );
  Cirkel (  0+ 4 ,  0+ 0 , 0x0000 );
  Cirkel (  0+ 8 ,  0+ 0 , 0x0000 );
  Cirkel (  0+12 ,  0+ 0 , 0x0000 );
  Cirkel (  0+ 0 ,  0+ 4 , 0x0000 );
  Cirkel (  0+ 4 ,  0+ 4 , 0x0000 );
  Cirkel (  0+ 8 ,  0+ 4 , 0x0000 );
  Cirkel (  0+12 ,  0+ 4 , 0x0000 );

  // Blauw
  Cirkel ( 16+ 0 ,  0+ 0 , 0x0000 );
  Cirkel ( 16+ 4 ,  0+ 0 , 0x0001 );
  Cirkel ( 16+ 8 ,  0+ 0 , 0x0002 );
  Cirkel ( 16+12 ,  0+ 0 , 0x0003 );
  Cirkel ( 16+ 0 ,  0+ 4 , 0x0004 );
  Cirkel ( 16+ 4 ,  0+ 4 , 0x0005 );
  Cirkel ( 16+ 8 ,  0+ 4 , 0x0006 );
  Cirkel ( 16+12 ,  0+ 4 , 0x0007 );

  // Groen
  Cirkel ( 32+ 0 ,  0+ 0 , 0x0000 );
  Cirkel ( 32+ 4 ,  0+ 0 , 0x0010 );
  Cirkel ( 32+ 8 ,  0+ 0 , 0x0020 );
  Cirkel ( 32+12 ,  0+ 0 , 0x0030 );
  Cirkel ( 32+ 0 ,  0+ 4 , 0x0040 );
  Cirkel ( 32+ 4 ,  0+ 4 , 0x0050 );
  Cirkel ( 32+ 8 ,  0+ 4 , 0x0060 );
  Cirkel ( 32+12 ,  0+ 4 , 0x0070 );

  // Cyan
  Cirkel ( 48+ 0 ,  0+ 0 , 0x0000 );
  Cirkel ( 48+ 4 ,  0+ 0 , 0x0011 );
  Cirkel ( 48+ 8 ,  0+ 0 , 0x0022 );
  Cirkel ( 48+12 ,  0+ 0 , 0x0033 );
  Cirkel ( 48+ 0 ,  0+ 4 , 0x0044 );
  Cirkel ( 48+ 4 ,  0+ 4 , 0x0055 );
  Cirkel ( 48+ 8 ,  0+ 4 , 0x0066 );
  Cirkel ( 48+12 ,  0+ 4 , 0x0077 );

  // Rood
  Cirkel (  0+ 0 ,  8+ 0 , 0x0000 );
  Cirkel (  0+ 4 ,  8+ 0 , 0x0100 );
  Cirkel (  0+ 8 ,  8+ 0 , 0x0200 );
  Cirkel (  0+12 ,  8+ 0 , 0x0300 );
  Cirkel (  0+ 0 ,  8+ 4 , 0x0400 );
  Cirkel (  0+ 4 ,  8+ 4 , 0x0500 );
  Cirkel (  0+ 8 ,  8+ 4 , 0x0600 );
  Cirkel (  0+12 ,  8+ 4 , 0x0700 );

  // Magenta
  Cirkel ( 16+ 0 ,  8+ 0 , 0x0000 );
  Cirkel ( 16+ 4 ,  8+ 0 , 0x0101 );
  Cirkel ( 16+ 8 ,  8+ 0 , 0x0202 );
  Cirkel ( 16+12 ,  8+ 0 , 0x0303 );
  Cirkel ( 16+ 0 ,  8+ 4 , 0x0404 );
  Cirkel ( 16+ 4 ,  8+ 4 , 0x0505 );
  Cirkel ( 16+ 8 ,  8+ 4 , 0x0606 );
  Cirkel ( 16+12 ,  8+ 4 , 0x0707 );

  // Geel
  Cirkel ( 32+ 0 ,  8+ 0 , 0x0000 );
  Cirkel ( 32+ 4 ,  8+ 0 , 0x0110 );
  Cirkel ( 32+ 8 ,  8+ 0 , 0x0220 );
  Cirkel ( 32+12 ,  8+ 0 , 0x0330 );
  Cirkel ( 32+ 0 ,  8+ 4 , 0x0440 );
  Cirkel ( 32+ 4 ,  8+ 4 , 0x0550 );
  Cirkel ( 32+ 8 ,  8+ 4 , 0x0660 );
  Cirkel ( 32+12 ,  8+ 4 , 0x0770 );

  // Wit
  Cirkel ( 48+ 0 ,  8+ 0 , 0x0000 );
  Cirkel ( 48+ 4 ,  8+ 0 , 0x0111 );
  Cirkel ( 48+ 8 ,  8+ 0 , 0x0222 );
  Cirkel ( 48+12 ,  8+ 0 , 0x0333 );
  Cirkel ( 48+ 0 ,  8+ 4 , 0x0444 );
  Cirkel ( 48+ 4 ,  8+ 4 , 0x0555 );
  Cirkel ( 48+ 8 ,  8+ 4 , 0x0666 );
  Cirkel ( 48+12 ,  8+ 4 , 0x0777 );
}

void Vierkant (byte x, byte y, word k)
{ SetPoint (x+0, y+0, k );
  SetPoint (x+0, y+1, k );
  SetPoint (x+0, y+2, k );
  SetPoint (x+0, y+3, k );
  SetPoint (x+1, y+0, k );
  SetPoint (x+1, y+1, k );
  SetPoint (x+1, y+2, k );
  SetPoint (x+1, y+3, k );
  SetPoint (x+2, y+0, k );
  SetPoint (x+2, y+1, k );
  SetPoint (x+2, y+2, k );
  SetPoint (x+2, y+3, k );
  SetPoint (x+3, y+0, k );
  SetPoint (x+3, y+1, k );
  SetPoint (x+3, y+2, k );
  SetPoint (x+3, y+3, k );
}

void Cirkel (byte x, byte y, word k )
{ SetPoint (x+0, y+0, bgcolor() );
  SetPoint (x+0, y+1, k );
  SetPoint (x+0, y+2, k );
  SetPoint (x+0, y+3, bgcolor() );
  SetPoint (x+1, y+0, k );
  SetPoint (x+1, y+1, k );
  SetPoint (x+1, y+2, k );
  SetPoint (x+1, y+3, k );
  SetPoint (x+2, y+0, k );
  SetPoint (x+2, y+1, k );
  SetPoint (x+2, y+2, k );
  SetPoint (x+2, y+3, k );
  SetPoint (x+3, y+0, bgcolor() );
  SetPoint (x+3, y+1, k );
  SetPoint (x+3, y+2, k );
  SetPoint (x+3, y+3, bgcolor() );
}


//==============================================================================
//==                                                                          ==
//==============================================================================
// Paneel Vars.
const byte MaxCol = 64;
volatile byte PanelData [MaxCol][8][3];   // = [00..63],[0..7],[0..2] of (Rl Gl Bl Ru Gu Bu 0 0)
volatile byte RowCount = 0;
// Brightness Vars.
const byte MaxBrightCount = 9;    // Count 1..MaxBrightCount
const byte BrightRow [MaxBrightCount]  = {0,2,2,1,2,2,1,2,2}; // Counter Conversion for Binairy Code Modulation.
volatile byte BrightCount =  0;
// BackGround-Color (format: 0x0RGB = B 0000 RRRR GGGG BBBB)
word _bgcolor = 0x0000;

// RGB Pin Definitions - All Pins are hardcoded to speed things up.
// const int a   = A0;  // Address A (A0)
// const int b   = A1;  // Address B (A1)
// const int c   = A2;  // Address C (A2)
// const int b1  =  2;  // Blue 1
// const int g1  =  3;  // Green 1
// const int r1  =  4;  // Red 1
// const int b2  =  5;  // Blue 2
// const int g2  =  6;  // Green 2
// const int r2  =  7;  // Red 2
// const int clk =  8;  // Clock
// const int oe  =  9;  // outEnable
// const int lat = 10;  // Latch

void InitPan(word _k)
// Initializing the Panel
// Input: _k = BackGround-Color (format: 0x0RGB = B 0000 0RRR 0GGG 0BBB)
{ // Put Pins to Output (A0 A1 A2 - D2 D3 D4 - D5 D6 D7 - D8 D9 D10)
  DDRC = DDRC | B00000111;    // pinMode(a  , OUTPUT); pinMode(b  , OUTPUT); pinMode(c  , OUTPUT);
  DDRD = DDRD | B11111100;    // pinMode(r1 , OUTPUT); pinMode(g1 , OUTPUT); pinMode(b1 , OUTPUT);
                              // pinMode(r2 , OUTPUT); pinMode(g2 , OUTPUT); pinMode(b2 , OUTPUT);
  DDRB = DDRB | B00000111;    // pinMode(clk, OUTPUT); pinMode(oe , OUTPUT); pinMode(lat, OUTPUT);
  Setbgcolor(_k);
  ClrPan();
  InitTimer();
}

void InitTimer()
{ // Initialize Timer1
  cli();                        // Disable Interrupts
  // Timer Counter Control Registers 1A & 1B
  TCCR1A = 0;                   // Make all bits of this register to 0
  TCCR1B = 0;                   // Make all bits of this register to 0

  OCR1A = 3900;                 // set Output Compare Register 1 to the desired timer count
  TCCR1B = TCCR1B | B00001000;  // turn on CTC mode (WGM12 = bit 3 - Waveform Generation Mode)
  TCCR1B = TCCR1B | B00000001;  // Set the Prescaler (CS12 CS11 CS10 = bit 2..0 - Clock Select)

  TIMSK1 = TIMSK1 | B00000010;  // set Timer Interupt MaSK 1 to compare interrupt
                                // (OCIE1A = bit 1 - Output Compare match Interrupt Enable 1A)
  sei();                        // Enable Interrupts
}

void Setbgcolor(word _k)
{ // BackGround-Color (format: 0x0RGB = B 0000 0RRR 0GGG 0BBB)
  _bgcolor = _k & 0x0777;
}

word bgcolor(void)
{ return _bgcolor;
}

void ClrPan()
// Clear the Panel with bgcolor
{ byte _lc = (  LowColor(bgcolor()) * 9 ) << 2;
  byte _mc = (  MidColor(bgcolor()) * 9 ) << 2;
  byte _hc = ( HighColor(bgcolor()) * 9 ) << 2;
  for (byte ww=0; ww<8; ww=ww+1)
  { for (byte qq=0; qq<MaxCol; qq=qq+1)
    { PanelData [qq][ww][0] = _lc;
      PanelData [qq][ww][1] = _mc;
      PanelData [qq][ww][2] = _hc;
    }
  }
}

byte LowColor (word _k)
// Get the LowColor rgb from 0000 0RRR 0GGG 0BBB
{ return (( _k & 0x0100 ) >> 6 ) + (( _k & 0x0010 ) >> 3 ) + (( _k & 0x0001 )      );
}

byte MidColor (word _k)
// Get the MidColor RGB from 0000 0RRR 0GGG 0BBB
{ return (( _k & 0x0200 ) >> 7 ) + (( _k & 0x0020 ) >> 4 ) + (( _k & 0x0002 ) >> 1 );
}

byte HighColor (word _k)
// Get the HighColor RGB from 0000 0RRR 0GGG 0BBB
{ return (( _k & 0x0400 ) >> 8 ) + (( _k & 0x0040 ) >> 5 ) + (( _k & 0x0004 ) >> 2 );
}

word Dec2RGB (word _k)
// Convert a decimal color into a hex RGB-color 0000 0RRR 0GGG 0BBB
{ return (( _k & 0x01C0 ) << 2 ) + (( _k & 0x0038 ) << 1 ) + ( _k & 0x0007 );
}

void SetPoint (byte _x, byte _y, word _k)
// Let one Led lit at the (x;y) position
{ _x = ( _x & 0x3F );
  _y = ( _y & 0x0F ) ^ 0x0F;  // y = ( y and $0F ) xor $0F
  byte _y7 = _y & 0x07;
  _k = _k & 0x0777;
  byte _lc =  LowColor(_k);
  byte _mc =  MidColor(_k);
  byte _hc = HighColor(_k);
  // Put The Pixel On The Right Spot.
  if (( _y & 0x08 ) == 0 )
     { // This is the Upper-half
       PanelData[_x][_y7][0] = ( PanelData[_x][_y7][0] & B11100000 ) | ( _lc << 2 );
       PanelData[_x][_y7][1] = ( PanelData[_x][_y7][1] & B11100000 ) | ( _mc << 2 );
       PanelData[_x][_y7][2] = ( PanelData[_x][_y7][2] & B11100000 ) | ( _hc << 2 );
     }
  else
     { // This is the Lower half.
       PanelData[_x][_y7][0] = ( PanelData[_x][_y7][0] & B00011100 ) | ( _lc << 5 );
       PanelData[_x][_y7][1] = ( PanelData[_x][_y7][1] & B00011100 ) | ( _mc << 5 );
       PanelData[_x][_y7][2] = ( PanelData[_x][_y7][2] & B00011100 ) | ( _hc << 5 );
     }
}

ISR(TIMER1_COMPA_vect)
// De Interrupt Service Routine
// The main interupt-routine. Do One Row (at each Interupt)
{ byte rc = MaxCol;
  byte BrightLayer = BrightRow[BrightCount];
  byte _clock_rise = PORTB | B00000001;  // digitalWrite(clk, HIGH);
  byte _clock_fall = PORTB & B11111110;  // digitalWrite(clk, LOW );
  byte _data_serial = ( PORTD & B00000011 );
  do { rc=rc-1;
       // Send the RGB to the RGB-lines
       PORTD = _data_serial | PanelData[rc][RowCount][BrightLayer];
       // Clock the RGB
       PORTB = _clock_rise;
       PORTB = _clock_fall;
     } while (rc>0);
  // Make it Invisible
  PORTB = PORTB | B00000010;             // digitalWrite(oe , HIGH);
  // Select the Row on the panels.
  PORTC = ( PORTC & B11111000 ) | RowCount;
  // Latch the Data
  PORTB = PORTB | B00000100;             // digitalWrite(lat, HIGH);
  PORTB = PORTB & B11111011;             // digitalWrite(lat, LOW );
  // Make it Visible again
  PORTB = PORTB & B11111101;             // digitalWrite(oe , LOW );
  // Next Row
  RowCount = RowCount + 1;     // Count the Row
  if ( RowCount >= 8 )
     { RowCount = 0;
       BrightCount = BrightCount + 1;    // Inc the Brightness counter
       if ( BrightCount >= MaxBrightCount )
          { BrightCount = 0;
          }
     }

Broncode: [1: Interupted Wallpapers]

Afbeeldingen

intwalpa_1.jpg
1/2: intwalpa_1.jpg.
intwalpa_2.jpg
2/2: intwalpa_2.jpg.

De aansluitingen van Interupted Wallpapers

Arduino Uno

Pwr USB ?
 
?
aref
gnd Gnd's (4x)
? d13
ioreff d12
reset d11
+3.3v d10 Latch
+5v d9 Oe
Gnd's (4x) gnd d8 Clock
Gnd's (4x) gnd
Vin d7 R2
d6 G2
A  (A0) a0 d5 B2
B  (A1) a1 d4 R1
C  (A2) a2 d3 G1
Behangpot   (4) a3 d2 B1
Kleurpot    (5) a4 d1
Snelheidpot (6) a5 d0