3000 page views!!
Yesterday I got the 3 Arduinos that I ordered from China - and they're the Atmega 328P-PU type - the same as all my others. I now have 7 Arduinos (8 if you count the Gertboard) and 2 Raspberry Pis. Maybe I should stop collecting them!
One of the earliest components I had was this bi-colour LED matrix. I actually had it wired up to display patterns with both the red and the green colours active, before I started this blog.
Dismantling it before I had it documented was one of my regrets which led to the making of this entire blog. The LED array has 64 red and 64 green LEDs, which is amazing in such a small space. There seems to be room for 4 LEDs in each dot, so presumably you could get red, green, blue and white LEDs - I must look out for this.
This time I followed an oomlout.com recipe for activating either the red or the green, or some of the red and some of the green LEDs, but not all at the same time. The pinout is completely different from the previous mono-colour 8 x 8 array. (ref http://smokespark.blogspot.co.uk/2013/08/30-multiplexing-8-x-8-led-array.html)
Here is the result of a sketch which is designed just to test the LEDs which have been activated by hardware configuration (I connected up the red LEDs for the top 4 rows, and the green LEDs for the lower 4 rows:
and running a scrolling text sketch, this time I connected up the green LEDs on the top 4 rows and the red LEDs on the bottom 4 rows. Here is the result:
oomlout.com provide a very useful sheet (ref http://oomlout.com/parts/LED-8X8M-03-guide.pdf) and here are some extracted diagrams:
Note that this is the common-anode type. Circuitry would have to be different for the common-cathode type.
This is a kit supplied by oomlout.com, but I used my own parts.
This is a very useful diagram, because without it, it's very easy to get the wiring wrong.
The code for testing the LEDs is here:
1: /*
2: * Example Code for an 8 x 8 LED Matrix
3: * For More Details Visit http://www.tinyurl.com/yhwxv6h
4: *
5: * Displays a test pattern lighting one LED after another
6: * To Play around with modifying the bitmap, un comment Example #2
7: */
8: int speed = 5; //the delay time in milliseconds
9: int pauseDelay = 1; //the number of milliseconds to display each scanned line
10: //Pin Definitions
11: int rowA[] = {9,8,7,6,5,4,3,2}; //An Array defining which pin each row is attached to
12: //(rows are common anode (drive HIGH))
13: int colA[] = {17,16,15,14,13,12,11,10}; //An Array defining which pin each column is attached to
14: //(columns are common cathode (drive LOW))
15: //The array used to hold a bitmap of the display
16: //(if you wish to do something other than scrolling marque change the data in this
17: //variable then display)
18: byte data[] = {0,0,0,0,0,0,0,0};
19: //Setup runs once when power is applied
20: void setup()
21: {
22: Serial.begin(9600); //Open the Serial port for debugging
23: for(int i = 0; i <8; i++){ //Set the 16 pins used to control the array as OUTPUTs
24: pinMode(rowA[i], OUTPUT);
25: pinMode(colA[i], OUTPUT);
26: }
27: }
28: //repeats
29: void loop()
30: {
31: //Example #1 - test pattern
32: //Run a small test program which lights up each light in time
33: test();
34: //Example #2 - static image
35: //Display a defined bitmap
36: /*
37: data[0] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
38: data[1] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
39: data[2] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
40: data[3] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
41: data[4] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
42: data[5] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
43: data[6] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
44: data[7] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
45: showSprite(speed);
46: */
47: }
48: //An array to store power values to act as bit masks
49: const int powers[] = {1,2,4,8,16,32,64,128};
50: //Runs a pattern where each LED is lit one after another
51: void test(){
52: for(int i = 0; i < 8; i++){
53: for(int ii = 0; ii< 8; ii++){
54: data[i] = data[i]+ powers[ii]; //Goes through each row of lights lighting each column one after another
55: showSprite(speed);
56: }
57: }
58: for(int i = 0; i < 8; i++){
59: for(int ii = 0; ii< 8; ii++){
60: data[i] = data[i] - powers[ii]; //Goes through each row of lights turning off each column one after another
61: showSprite(speed);
62: }
63: }
64: }
65: void showSprite(int speed2){
66: for(int iii = 0; iii < speed2; iii++){ //show the current frame speed2 times
67: for(int column = 0; column < 8; column++){ //iterate through each column
68: for(int i = 0; i < 8; i++){
69: digitalWrite(rowA[i], LOW); //turn off all row pins
70: }
71: for(int i = 0; i < 8; i++){ //Set only the one pin
72: if(i == column){ digitalWrite(colA[i], LOW);} //turns the current row on
73: else{ digitalWrite(colA[i], HIGH); }//turns the rest of the rows off
74: }
75: for(int row = 0; row < 8; row++){ //iterate through each pixel in the current column
76: int bit = (data[column] >> row) & 1;
77: if(bit == 1){
78: digitalWrite(rowA[row], HIGH); //if the bit in the data array is set turn the LED on
79: }
80: }
81: delay(pauseDelay); //leave the column on for pauseDelay microseconds (too high a delay causes flicker)
82: }
83: }
84: }
1: /*
2: * Example Code for an 8 x 8 LED Matrix
3: * For More Details Visit http://www.tinyurl.com/yhwxv6h
4: *
5: * Scrolls a message across an 8 x 8 LED Matrix
6: * To adjust the speed change the variable speed.
7: * The message is held in requestString[]
8: */
9: int speed = 20; //number of times to repeat each frame
10: int pauseDelay = 500; //microseconds to leave each row on before moving to the next
11: char requestString[] = " Hello World of Sparks N Smoke - - - "; //The string to display
12: //to change the message in code you right yourself simply
13: //change this data and reset index and offset to 0
14: //Variables used for scrolling (both start at 0
15: int index = 0; //this is the current character in the string being displayed
16: int offset = 0; //this is how many columns it is offset by
17: //Pin Definitions
18: int rowA[] = {9,8,7,6,5,4,3,2}; //An Array defining which pin each row is attached to
19: //(rows are common anode (drive HIGH))
20: int colA[] = {17,16,15,14,13,12,11,10}; //An Array defining which pin each column is attached to
21: //(columns are common cathode (drive LOW))
22: //Constants defining each characters position in an array of integer arrays
23: //Letters
24: const int A = 0; const int B = 1; const int C = 2; const int D = 3; const int E = 4;
25: const int F = 5; const int G = 6; const int H = 7; const int I = 8; const int J = 9;
26: const int K = 10; const int L =11; const int M = 12; const int N = 13; const int O = 14;
27: const int P = 15; const int Q =16; const int R = 17; const int S = 18; const int T = 19;
28: const int U = 20; const int V =21; const int W = 22; const int X = 23; const int Y = 24;
29: const int Z = 25;
30: //Punctuation
31: const int COL =26; const int DASH = 27; const int BRA2 = 28; const int _ = 29; const int LINE = 34;
32: const int DOT =36;
33: //Extra Charchters
34: const int FULL =30; const int CHECK = 31; const int B2 = 32; const int TEMP = 33;
35: const int SMILE =35; const int COLDOT = 36;
36: //The array used to hold a bitmap of the display
37: //(if you wish to do something other than scrolling marque change the data in this
38: //variable then display)
39: byte data[] = {0,0,0,0,0,0,0,0};
40: //The alphabet
41: //Each character is an 8 x 7 bitmap where 1 is on and 0 if off
42: const int _A[] = {B0111000,
43: B1100100,
44: B1100100,
45: B1100100,
46: B1111100,
47: B1100100,
48: B1100100,
49: B0000000};
50: const int _B[] = {B1111000,
51: B1101100,
52: B1101100,
53: B1111100,
54: B1101100,
55: B1101100,
56: B1111000,
57: B0000000};
58: const int _C[] = {B0111000,
59: B1100100,
60: B1100000,
61: B1100000,
62: B1100000,
63: B1100100,
64: B0111000,
65: B0000000};
66: const int _D[] = {B1111000,
67: B1100100,
68: B1100110,
69: B1100110,
70: B1100110,
71: B1100100,
72: B1111000,
73: B0000000};
74: const int _E[] = {B1111100,
75: B1100100,
76: B1100000,
77: B1111000,
78: B1100000,
79: B1100100,
80: B1111100,
81: B0000000};
82: const int _F[] = {B1111100,
83: B1100100,
84: B1100000,
85: B1111000,
86: B1100000,
87: B1100000,
88: B1100000,
89: B0000000};
90: const int _G[] = {B0111100,
91: B1100100,
92: B1100000,
93: B1101110,
94: B1100100,
95: B1100100,
96: B0111100,
97: B0000000};
98: const int _H[] = {B1100110,
99: B1100110,
100: B1100110,
101: B1111110,
102: B1100110,
103: B1100110,
104: B1100110,
105: B0000000};
106: const int _I[] = {B0111100,
107: B0011000,
108: B0011000,
109: B0011000,
110: B0011000,
111: B0011000,
112: B0111100,
113: B0000000};
114: const int _J[] = {B0011110,
115: B0001100,
116: B0001100,
117: B0001100,
118: B1101100,
119: B1101100,
120: B0111100,
121: B0000000};
122: const int _K[] = {B1100011,
123: B1100110,
124: B1101100,
125: B1111000,
126: B1101100,
127: B1100110,
128: B1100011,
129: B0000000};
130: const int _L[] = {B1111000,
131: B0110000,
132: B0110000,
133: B0110000,
134: B0110000,
135: B0110010,
136: B1111110,
137: B0000000};
138: const int _M[] = {B1000001,
139: B1100011,
140: B1110111,
141: B1101011,
142: B1100011,
143: B1100011,
144: B1100011,
145: B0000000};
146: const int _N[] = {B1100011,
147: B1110011,
148: B1110011,
149: B1101011,
150: B1100111,
151: B1100111,
152: B1100011,
153: B0000000};
154: const int _O[] = {B0111100,
155: B1100110,
156: B1100110,
157: B1100110,
158: B1100110,
159: B1100110,
160: B0111100,
161: B0000000};
162: const int _P[] = {B1111000,
163: B1101100,
164: B1101100,
165: B1111000,
166: B1100000,
167: B1100000,
168: B1100000,
169: B0000000};
170: const int _Q[] = {B0111100,
171: B1100110,
172: B1100110,
173: B1100110,
174: B1101110,
175: B1100100,
176: B0111010,
177: B0000001};
178: const int _R[] = {B1111000,
179: B1101100,
180: B1101100,
181: B1111000,
182: B1111000,
183: B1101100,
184: B1100110,
185: B0000000};
186: const int _S[] = {B0111100,
187: B1100010,
188: B1100000,
189: B0111100,
190: B0000110,
191: B1000110,
192: B0111100,
193: B0000000};
194: const int _T[] = {B1111110,
195: B1011010,
196: B0011000,
197: B0011000,
198: B0011000,
199: B0011000,
200: B0011000,
201: B0000000};
202: const int _U[] = {B1100110,
203: B1100110,
204: B1100110,
205: B1100110,
206: B1100110,
207: B1100110,
208: B0111100,
209: B0000000};
210: const int _V[] = {B1100011,
211: B1100011,
212: B1100011,
213: B1100011,
214: B0110110,
215: B0011100,
216: B0001000,
217: B0000000};
218: const int _W[] = {B1100011,
219: B1100011,
220: B1100011,
221: B1101011,
222: B1110111,
223: B1100011,
224: B1000001,
225: B0000000};
226: const int _X[] = {B1100011,
227: B0110110,
228: B0011100,
229: B0001000,
230: B0011100,
231: B0110110,
232: B1100011,
233: B0000000};
234: const int _Y[] = {B1100010,
235: B0110100,
236: B0011000,
237: B0011000,
238: B0011000,
239: B0011000,
240: B0011000,
241: B0000000};
242: const int _Z[] = {B1111111,
243: B1000111,
244: B0001100,
245: B0011000,
246: B0110000,
247: B1110001,
248: B1111111,
249: B0000000};
250: const int _COL[] = {B0000000,
251: B0011000,
252: B0011000,
253: B0000000,
254: B0011000,
255: B0011000,
256: B0000000,
257: B0000000};
258: const int _DASH[] = {B0000000,
259: B0000000,
260: B0000000,
261: B0111110,
262: B0111110,
263: B0000000,
264: B0000000,
265: B0000000};
266: const int _BRA2[] = {B0010000,
267: B0001000,
268: B0000100,
269: B0000100,
270: B0001000,
271: B0010000,
272: B0000000,
273: B0000000};
274: const int __[] = {B0000000,
275: B0000000,
276: B0000000,
277: B0000000,
278: B0000000,
279: B0000000,
280: B0000000,
281: B0000000};
282: const int _FULL[] = {B1111111,
283: B1111111,
284: B1111111,
285: B1111111,
286: B1111111,
287: B1111111,
288: B1111111,
289: B0000000};
290: const int _CHECK[] = {B1010101,
291: B0101010,
292: B1010101,
293: B0101010,
294: B1010101,
295: B0101010,
296: B1010101,
297: B0000000};
298: const int _B2[] = {B0111110,
299: B0000001,
300: B0000001,
301: B0001111,
302: B0000001,
303: B1000001,
304: B0111110,
305: B0000000};
306: const int _TEMP[] = {B0000011,
307: B0011111,
308: B0111111,
309: B1111110,
310: B1111111,
311: B0011111,
312: B0000011,
313: B0000000};
314: const int _LINE[] = {B0000001,
315: B0000001,
316: B0000001,
317: B0000001,
318: B0000001,
319: B0000001,
320: B0000001,
321: B0000000};
322: const int _SMILE[] = {B000000,
323: B1100100,
324: B1100010,
325: B0011001,
326: B1100010,
327: B1100100,
328: B0000000,
329: B0000000};
330: const int _DOT[] = {B0000000,
331: B0000000,
332: B0000000,
333: B0000000,
334: B1100000,
335: B1100000,
336: B0000000,
337: B0000000};
338: const int _COLDOT[] = {B0000000,
339: B0110000,
340: B0110000,
341: B0000000,
342: B0110011,
343: B0110011,
344: B0000000,
345: B0000000};
346: //Load the bitmap characters into an array (each characters position corresponds to its previously defined index (ie _A (a's bitmap)
347: //is at index 0 and A = 0 so letters[A] will return the 'A' bitmap)
348: const int* letters[] = {_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,_COL,_DASH,_BRA2,__, _FULL, _CHECK, _B2, _TEMP, _LINE, _SMILE, _DOT, _COLDOT};
349: //Setup runs once when power is applied
350: void setup()
351: {
352: for(int i = 0; i <8; i++){ //Set the 16 pins used to control the array as OUTPUTs
353: pinMode(rowA[i], OUTPUT);
354: pinMode(colA[i], OUTPUT);
355: }
356: }
357: //repeats
358: void loop()
359: {
360: updateMatrix();
361: }
362: void updateMatrix(){
363: loadSprite();
364: showSprite(speed);
365: }
366: //An array holding the powers of 2 these are used as bit masks when calculating what to display
367: const int powers[] = {1,2,4,8,16,32,64,128};
368: //Loads the current scroll state frame into the data[] display array
369: void loadSprite(){
370: int currentChar = getChar(requestString[index]);
371: int nextChar = getChar(requestString[index+1]);
372: for(int row=0; row < 8; row++){ //iterate through each row
373: data[row] = 0; //reset the row we're working on
374: for(int column=0; column < 8; column++){ //iterate through each column
375: data[row] = data[row] + ((powers[column] & (letters[currentChar][row] << offset))); //loads the current character offset by offset pixels
376: data[row] = data[row] + (powers[column] & (letters[nextChar][row] >> (8-offset) )); //loads the next character offset by offset pixels
377: }
378: }
379: offset++; //increment the offset by one row
380: if(offset==8){offset = 0; index++; if(index==sizeof(requestString)-2){index=0;}} //if offset is 8 load the next character pair for the next time through
381: }
382: void showSprite(int speed2){
383: for(int iii = 0; iii < speed2; iii++){ //show the current frame speed2 times
384: for(int column = 0; column < 8; column++){ //iterate through each column
385: for(int i = 0; i < 8; i++){
386: digitalWrite(rowA[i], LOW); //turn off all row pins
387: }
388: for(int i = 0; i < 8; i++){ //Set only the one pin
389: if(i == column){ digitalWrite(colA[i], LOW);} //turns the current row on
390: else{ digitalWrite(colA[i], HIGH); }//turns the rest of the rows off
391: }
392: for(int row = 0; row < 8; row++){ //iterate through each pixel in the current column
393: int bit = (data[column] >> row) & 1;
394: if(bit == 1){
395: digitalWrite(rowA[row], HIGH); //if the bit in the data array is set turn the LED on
396: }
397: }
398: delayMicroseconds(pauseDelay); //leave the column on for pauseDelay microseconds (too high a delay causes flicker)
399: }
400: }
401: }
402: //returns the index of a given character
403: //for converting from a string to a lookup in our array of character bitmaps
404: int getChar(char character){
405: int returnValue = Z;
406: switch(character){
407: case 'A': returnValue = A; break;
408: case 'a': returnValue = A; break;
409: case 'B': returnValue = B; break;
410: case 'b': returnValue = B; break;
411: case 'C': returnValue = C; break;
412: case 'c': returnValue = C; break;
413: case 'D': returnValue = D; break;
414: case 'd': returnValue = D; break;
415: case 'E': returnValue = E; break;
416: case 'e': returnValue = E; break;
417: case 'F': returnValue = F; break;
418: case 'f': returnValue = F; break;
419: case 'G': returnValue = G; break;
420: case 'g': returnValue = G; break;
421: case 'H': returnValue = H; break;
422: case 'h': returnValue = H; break;
423: case 'I': returnValue = I; break;
424: case 'i': returnValue = I; break;
425: case 'J': returnValue = J; break;
426: case 'j': returnValue = J; break;
427: case 'K': returnValue = K; break;
428: case 'k': returnValue = K; break;
429: case 'L': returnValue = L; break;
430: case 'l': returnValue = L; break;
431: case 'M': returnValue = M; break;
432: case 'm': returnValue = M; break;
433: case 'N': returnValue = N; break;
434: case 'n': returnValue = N; break;
435: case 'O': returnValue = O; break;
436: case 'o': returnValue = O; break;
437: case 'P': returnValue = P; break;
438: case 'p': returnValue = P; break;
439: case 'Q': returnValue = Q; break;
440: case 'q': returnValue = Q; break;
441: case 'R': returnValue = R; break;
442: case 'r': returnValue = R; break;
443: case 'S': returnValue = S; break;
444: case 's': returnValue = S; break;
445: case 'T': returnValue = T; break;
446: case 't': returnValue = T; break;
447: case 'U': returnValue = U; break;
448: case 'u': returnValue = U; break;
449: case 'V': returnValue = V; break;
450: case 'v': returnValue = V; break;
451: case 'W': returnValue = W; break;
452: case 'w': returnValue = W; break;
453: case 'X': returnValue = X; break;
454: case 'x': returnValue = X; break;
455: case 'Y': returnValue = Y; break;
456: case 'y': returnValue = Y; break;
457: case 'Z': returnValue = Z; break;
458: case 'z': returnValue = Z; break;
459: case ' ': returnValue = _; break;
460: case '3': returnValue = B2; break;
461: case '<': returnValue = TEMP; break;
462: case '*': returnValue = FULL; break;
463: case '|': returnValue = LINE; break;
464: case '_': returnValue = _; break;
465: case ':': returnValue = COL; break;
466: case '-': returnValue = DASH; break;
467: case ')': returnValue = BRA2; break;
468: case '%': returnValue = SMILE; break;
469: case '.': returnValue = DOT; break;
470: case '^': returnValue = COLDOT; break;
471: }
472: return returnValue;
473: }