Arduino Projekten

Thu 23-May-19
01:34:08




Cbm-Font op het Megapaneel

Datum: Mon 16 February 2015
Samenvatting: Het omzetten van de Font-Functies voor het Megapaneel (met het CBM-Font)


Ook voor dit deel is het Uno-programma gebruikt. De directe poort programmering (DDRx en PORTx) is aangepast aan de juiste poort-letters en dan blijkt dat het programma meteen werkt ... althans het intro-deel.

Daarna bleef het zwart ... oorzaak hiervan zijn echter de stand van de potmeters geweest. Toendertijd voor de Uno had ik enkele geinige dingetjes ervoor ingedachten, die ik nu vergeten ben. Na wat puzzelen kwamen de letters weer op het display, zijn de kleurtjes te veranderen en de snelheid te variëren.

Het intro is veranderd van "CBM-Font" en "Hello World." in "Mega CBM-Font" en "Mega World.".

Maar de Leds en Display moeten meebranden in de interupt-routine ISR(TIMER1_COMPA_vect). Het principe is gebaseert op het Paneel, echter is de schaal nu kleiner. Een array van 8 bytes bevat de data voor de Displays in LedData[0] tot en met LedData[3] en voor de Leds in LedData[4] tot en met LedData[7].

In de interupt funktie wordt tijdens het afwerken van een regel voor het Paneel, tegelijk een byte vanuit het LedData[] naar de Led en Display aansturing gestuurd. Elke Paneel regel heeft zijn eigen Display en Led-rij nummer. Dit kost weinig extra tijd en de interupt wordt toch al uitgevoerd.

Funkties voor de Led en Display aansturing.

Net als het Paneel zijn eigen funkties heeft, hebben de Leds en Displays ook diverse eigen functies gekregen.

  • InitLed(): zorgt dat de LedData gevuld wordt met 0, of te wel alles is uit.
  • WriteLed(row,data): Toont de data direct op de Leds rij nummer row (bovenaan is nr.0, onderaan is nr.2 (nummer 3 staat in de toekomst planning). Hiermee is elk segment aan of uit te zetten, zodat eigen symbolen kunnen worden laten zien. Er hoeft geen rekening gehouden te worden dat de Leds eigenlijk 4 bytes verder staat.
  • WriteDisplay(row,data): Toont de data direct op het display nummer row (rechts is nr.0, links is nr.3).
  • PrintDisplay(row,data): Toont het cijfer nummer data uit het segment7 font op het display nummer row
  • ClrDisplay(): Zet alle displays Uit.
  • ClrLed(): Zet alle Leds uit.
  • DisplayHex(waarde): schrijft de waarde hexa-decimaal op de 4 displays.

Als resultaat van dit projekt gaan de standen van de potmeters 1, 2 en 3 naar de Leds toe. De laatste foto geeft de waardes %00000010, %00000100 en %00010101 voor deze potmeter standen.

Potmeter 4 heeft geen eigen funktie in dit programma, maar de stand van deze potmeter wordt rechtstreeks als hexadecimaal getal naar de 4 displays gestuurd, zoals te zien is op de laatste foto (02Eb => $02EB).


Broncode: [1: Cbm-Font op het Megapaneel]

1: De broncode van Cbm-Font op het Megapaneel

(Mon 16 February 2015) Het omzetten van de Font-Functies voor het Megapaneel (met het CBM-Font)

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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
//     ---------------------------------------------------------
//     |  RGBMatrix : RGB Matrix - Mega Font Functions         |
//     |              Arduino Mega                             |
//     ---------------------------------------------------------

//--------[ Needed Include Files ] -------------------------------------------
// Include the beautiful Font
#include "{Drive}:\{Directory}\cbmfont.c"
// Include 7-segment Font
#include "{Drive}:\{Directory}\segment7.c"
// Next line is needed for PROGMEM and pgm_read_byte_near-function
#include <avr/pgmspace.h>

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

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

void loop()
{
  PORTL = ( PORTL + 1 ) & 0xFF;
  read_pots();
  switch (wp_count)
    { case 0 : ClrPan();
               break;
      case 1 : Letters1();
               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(2) * 16;
  WriteLed(2,pot_del/64);
  word pot_kleur_pot = analogRead(1) / 16;
  WriteLed(1,pot_kleur_pot);
  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(0) / 256;
  WriteLed(0,pot_num);
  DisplayHex(analogRead(3));
}

void font_intro()
{ // Write "Mega" & "Cbm-Font"
  CharColor (0x0722);
  GotoXY ( 8,0);     WriteChar (    13);
  GotoXY (22,0);     WriteChar (128+ 5);
  GotoXY (34,0);     WriteChar (128+ 7);
  GotoXY (48,0);     WriteChar (128+ 1);
  CharColor (0x0227);
  GotoXY ( 0,8);     WriteChar (     3);
  GotoXY ( 8,8);     WriteChar (128+ 2);
  GotoXY (16,8);     WriteChar (128+13);
  GotoXY (24,8);     WriteChar (    45);
  GotoXY (32,8);     WriteChar (     6);
  GotoXY (40,8);     WriteChar (128+15);
  GotoXY (48,8);     WriteChar (128+14);
  GotoXY (56,8);     WriteChar (128+20);
  PrintDisplay (0,0);
  delay(1500);

  // Write "Cbm-Font" Horizontal
  CharColor (0x0272);
  GotoXY ( 0,4);
  TransparantChar();
  WriteChar (     3);
  WriteChar (128+ 2);
  WriteChar (128+13);
  WriteChar (    45);
  WriteChar (     6);
  WriteChar (128+15);
  WriteChar (128+14);
  WriteChar (128+20);
  PrintDisplay (1,1);
  delay(750);

  // Write 5 times "@"
  CharColor (0x0722);
  TransparantChar();
  GotoXY (-4,-4);    WriteChar (     0);
  GotoXY (60,-4);    WriteChar (     0);
  GotoXY (-4,12);    WriteChar (     0);
  GotoXY (60,12);    WriteChar (     0);
  SetTransparance(0x3C);
  GotoXY (28, 4);    WriteChar (     0);
  SolidChar();
  PrintDisplay (2,2);
  delay(750);

  // Write " Mega " & "World."
  CharColor (0x0616);
  ReverseChar();
  GotoXY ( 5,0);
  PrintChar (" Mega ");
  GotoXY (11,8);
  PrintChar ("World.");
  PrintDisplay (3,3);

  delay(2000);
  ClrDisplay();
}

void Letters1()
{ // Letters
  word xx = (char_count & 7) * 8;
  word yy = (char_count & 8);
  Setbgcolor(0x0000);
//  GotoXY (xx,yy);
  CharColor(pot_kleur);
  WriteChar (char_count);
  char_count = char_count + 1;
  if (char_count & 0x000F) == 0x0000)
     { delay(250);
     }
  if (char_count >= fontchars)
     { char_count = 0;
     }
}

//==============================================================================
//== Led & Display Vars and Functions                                         ==
//==============================================================================
// Led Vars
volatile byte LedData[8];    // [0..7]

void InitLed()
{ for (byte qq=0; qq<=7; qq=qq+1)
      { // Clear al the Led/Display Data
        LedData[qq] = 0;
      }
}

void WriteLed (byte row, int data)
{ row = ( row & 0x03 ) | 0x04;
  data = data & 0xFF;
  LedData[row] = data;
}

void WriteDisplay (byte row, int data)
{ row = ( row & 0x03 );
  data = data & 0xFF;
  LedData[row] = data;
}

void PrintDisplay (byte row, int data)
{ row = ( row & 0x03 );
  data = data & 0xFF;
  if ( data <= dispfontchars )
     { word dispbyte=pgm_read_byte_near(dispfont+data);
       LedData[row] = dispbyte;
     }
  else
     { LedData[row] = 0;
     }
}

void ClrDisplay()
{ LedData[0] = 0;
  LedData[1] = 0;
  LedData[2] = 0;
  LedData[3] = 0;
}

void ClrLed()
{ LedData[4] = 0;
  LedData[5] = 0;
  LedData[6] = 0;
  LedData[7] = 0;
}

void DisplayHex(word waarde)
{ // Display a 4-digit hexa-decimal number on the display
  PrintDisplay(0,( waarde & 0x000F ) );
  PrintDisplay(1,( waarde & 0x00F0 ) >>  4 );
  PrintDisplay(2,( waarde & 0x0F00 ) >>  8 );
  PrintDisplay(3,( waarde & 0xF000 ) >> 12 );
}

//==============================================================================
//==  Matrix Panel Vars and Functions                                         ==
//==============================================================================
// Paneel Vars.
const byte MaxCol = 64;
const byte MaxRow = 16;
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;
// Font Vars
const byte _bitjes[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
word _fontcolor = 0x0333;
byte _fontreverse = 0;
byte _fonttransparant = 0;
int _font_x = 0;
int _font_y = 0;

// RGB Pin Definitions - All Pins are hardcoded to speed things up.
// const int b1  = 24;  // Blue 1  - Port A
// const int g1  = 25;  // Green 1 - Port A
// const int r1  = 26;  // Red 1   - Port A
// const int b2  = 27;  // Blue 2  - Port A
// const int g2  = 28;  // Green 2 - Port A
// const int r2  = 29;  // Red 2   - Port A

// const int a   = 37;  // Address A (A0)  - Port C
// const int b   = 36;  // Address B (A1)  - Port C
// const int c   = 35;  // Address C (A2)  - Port C
// const int clk = 33;  // Clock panel     - Port C
// const int lat = 32;  // Latch Panel     - Port C
// const int oep = 31;  // outEnable Panel - Port C
// const int oel = 30;  // outEnable Leds  - Port C

void InitPan(word _k)
// Initializing the Panel
// Input: _k = BackGround-Color (format: 0x0RGB = B 0000 0RRR 0GGG 0BBB)
{ // Put Pins to Output
  DDRA = 0xFF;      // Panel Data All Output
  DDRL = 0xFF;      // Led Data   All Output
  DDRC = 0xFF;      // Addr Ctrl  All Output
  InitLed();
  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)
// Set the 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;
            }
      }
_fontreverse = 0;
_fonttransparant = 0;
_font_x = 0;
_font_y = 0;
}

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 (int _x, int _y, word _k)
// Let one Led lit at the (x;y) position
{ if (( _x < 0 ) || ( _x >= MaxCol ))   { return; }   // _x is outside the panel
  if (( _y < 0 ) || ( _y >= MaxRow ))   { return; }   // _y is outside the panel
  _y = _y ^ 0x0F;
  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 );
     }
}

//--------[ Font Functions ]---------------------------------------------------

void GotoXY (int _x, int _y)
{ _font_x = _x;
  _font_y = _y;
}

void NextXY ()
{ // Set the (_font_x;_font_y) to the next char-position.
  // Do an <LF><CR> at the end of the line;
  _font_x = _font_x + 8;
  if ( _font_x >= MaxCol )
     { _font_x = _font_x - MaxCol;
       _font_y = _font_y + charbytes;
       if (_font_y >= MaxRow)
          { _font_y = _font_y - MaxRow;
          }
     }
}

void ReverseChar ()
{ _fontreverse = 0xFF;
}

void NormalChar ()
{ _fontreverse = 0;
}

void SetReverse (byte _bits)
{ _fontreverse = (_bits & 0xFF);
}

void TransparantChar ()
{ _fonttransparant = 0xFF;
}

void SolidChar ()
{ _fonttransparant = 0;
}

void SetTransparance (byte _bits)
{ _fonttransparant = (_bits & 0xFF);
}

void CharColor (word _kk)
{ _fontcolor = _kk;
}

void WriteChar (word ch)
{ // Writes 1 character ch at position (_font_x;_font_y) in the color _fontcolor
  // If nescesary, xor it with _fontreverse
  // move _font_x to 8 point to the right
  if ( ch>=fontchars )
     { return; }    // Char does not exist in font.
  word _ch=ch*charbytes;
  for (byte qy=0; qy<charbytes; qy=qy+1)
      { word charbyte=pgm_read_byte_near(font+_ch+qy) xor _fontreverse;
        for (byte qx=0; qx<8; qx=qx+1)
            { if ((charbyte & 128)>0)        // Look at MSB-point of charbyte
                 { // if (1) then draw pixel
                   SetPoint (_font_x+qx,_font_y+qy,_fontcolor);
                 }
              else
                 { // if (0) then draw bgcolor
                   if (_fonttransparant & _bitjes[qx]) == 0)
                      { // But only if not Transparant (= 0)
                        SetPoint (_font_x+qx,_font_y+qy,_bgcolor);
                      }
                 }
              charbyte=charbyte<<1;
            }
      }
  NextXY();
}

void PrintChar(char* ss)
{ // Print a character, after conversing it from ascii to font-character
  byte qq = 0;
  while ( ss[qq] != '\0' )
    { // chech every char if it is in the table.
      char cc=ss[qq];
      if (( cc>=asctableshift ) &&         // Char is above the bottom
          ( cc< asctablechars+asctableshift ) // Char is below the top
         )

         { // Find the char in the ascii-table to get the right number in the font.
           word _cc=pgm_read_byte_near(asc2font+cc - asctableshift);
           WriteChar (_cc);
         }
      qq=qq+1;
    }
}

//--------[ The Interupt Function ]--------------------------------------------

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 = PORTC | B00010000;  // value for Clk HIGH
  byte _clock_fall = PORTC & B11101111;  // value for Clk LOW
  byte _data_serial = ( PORTA & B00000011 );
  do { rc=rc-1;
       // Send the RGB to the RGB-lines
       PORTA = _data_serial | PanelData[rc][RowCount][BrightLayer];
       // Clock the RGB
       PORTC = _clock_rise;
       PORTC = _clock_fall;
     }
  while (rc>0);
  // Make it Invisible
  PORTC = PORTC | B11000000;             // OeP & OeL HIGH
  // Display Led & Display data
  PORTL = LedData[RowCount];
  // Select the Row on the panels.
  PORTC = ( PORTC & B11111000 ) | RowCount;
  // Latch the Data
  PORTC = PORTC | B00100000;             // Latch HIGH
  PORTC = PORTC & B11011111;             // Latch LOW
  // Make it Visible again
  PORTC = PORTC & B00111111;             // OeP & OeL 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: Cbm-Font op het Megapaneel]

Afbeeldingen

paneel02_font_1.jpg
1/3: paneel02_font_1.jpg.
paneel02_font_2.jpg
2/3: paneel02_font_2.jpg.
paneel02_font_3.jpg
3/3: paneel02_font_3.jpg.

De aansluitingen van Cbm-Font op het Megapaneel

Het omzetten van de Font-Functies voor het Megapaneel (met het CBM-Font)

Arduino Mega

Pwr USB ?
 
?
aref
gnd Gnd's
? d13
ioreff d12
Reset reset d11
+3.3v d10
+5V +5v d9
Gnd's gnd d8
Gnd's gnd
Vin d7
d6
SnelheidPot (1) a0 d5
KleurPot (2) a1 d4
BehangPot (3) a2 d3
7segmentPot (4) a3 d2
a4 d1 Tx
a5 d0 Rx
a6
a7 d14
d15
a8 d16
a9 d17
a10 d18 Tx1 Midi Out
a11 d19 Rx1 Midi In
a12 d20
a13 d21
a14 /~\
a15 \_/
Onderconnector
d22 | d23
R1 |A2 d24 | d25 A3| G1
B1 |A4 d26 | d27 A5| R2
G2 |A6 d28 | d29 A7| B2
 | 
Oe Led & Display |C7 d30 | d31 C6| Oe Paneel
Latch Paneel |C5 d32 | d33 C4| Clock Paneel
|C3 d34 | d35 C2| C (A2)
B (A1) |C1 d36 | d37 C0| A (A0)
 | 
d39 | d39
d40 | d41
 | 
Led Display |L7 d42 | d43 L6| Led Display
Led Display |L5 d44 | d45 L4| Led Display
Led Display |L3 d46 | d47 L2| Led Display
Led Display |L1 d48 | d49 L0| Led Display
 | 
d50 | d51
d52 | d53