1 | /**
|
2 | * LED Matrix library for http://www.seeedstudio.com/depot/ultrathin-16x32-red-led-matrix-panel-p-1582.html
|
3 | * The LED Matrix panel has 32x16 pixels. Several panel can be combined together as a large screen.
|
4 | *
|
5 | * Coordinate & Connection (Arduino -> panel 0 -> panel 1 -> ...)
|
6 | * (0, 0) (0, 0)
|
7 | * +--------+--------+--------+ +--------+--------+
|
8 | * | 5 | 4 | 3 | | 1 | 0 |
|
9 | * | | | | | | |<----- Arduino
|
10 | * +--------+--------+--------+ +--------+--------+
|
11 | * | 2 | 1 | 0 | (64, 16)
|
12 | * | | | |<----- Arduino
|
13 | * +--------+--------+--------+
|
14 | * (96, 32)
|
15 | * Copyright (c) 2013 Seeed Technology Inc.
|
16 | * @auther Yihui Xiong
|
17 | * @date Nov 8, 2013
|
18 | * @license MIT
|
19 | */
|
20 |
|
21 | #include "LEDMatrix.h"
|
22 | #include "Arduino.h"
|
23 |
|
24 | #if 0
|
25 | #define ASSERT(e) if (!(e)) { Serial.println(#e); while (1); }
|
26 | #else
|
27 | #define ASSERT(e)
|
28 | #endif
|
29 |
|
30 | LEDMatrix::LEDMatrix(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t oe, uint8_t r1, uint8_t r2, uint8_t stb, uint8_t clk)
|
31 | {
|
32 | this->clk = clk;
|
33 | this->r1 = r1;
|
34 | this->r2 = r2;
|
35 | this->stb = stb;
|
36 | this->oe = oe;
|
37 | this->a = a;
|
38 | this->b = b;
|
39 | this->c = c;
|
40 | this->d = d;
|
41 |
|
42 | mask = 0xff;
|
43 | state = 0;
|
44 | }
|
45 |
|
46 | void LEDMatrix::begin(uint8_t *displaybuf)
|
47 | {
|
48 | this->displaybuf = displaybuf;
|
49 |
|
50 | pinMode(a, OUTPUT);
|
51 | pinMode(b, OUTPUT);
|
52 | pinMode(c, OUTPUT);
|
53 | pinMode(d, OUTPUT);
|
54 | pinMode(oe, OUTPUT);
|
55 | pinMode(r1, OUTPUT);
|
56 | pinMode(r2, OUTPUT);
|
57 | pinMode(clk, OUTPUT);
|
58 | pinMode(stb, OUTPUT);
|
59 |
|
60 | state = 1;
|
61 | }
|
62 |
|
63 | void LEDMatrix::drawPoint(uint16_t x, uint16_t y, uint8_t pixel)
|
64 | {
|
65 | ASSERT(64 > x);
|
66 | ASSERT(32 > y);
|
67 |
|
68 | uint8_t *byte = displaybuf + x / 8 + y * 64 / 8;
|
69 | uint8_t bit = x % 8;
|
70 |
|
71 | if (pixel) {
|
72 | *byte |= 0x80 >> bit;
|
73 | } else {
|
74 | *byte &= ~(0x80 >> bit);
|
75 | }
|
76 | }
|
77 |
|
78 | void LEDMatrix::drawRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t pixel)
|
79 | {
|
80 | for (uint16_t x = x1; x < x2; x++) {
|
81 | for (uint16_t y = y1; y < y2; y++) {
|
82 | drawPoint(x, y, pixel);
|
83 | }
|
84 | }
|
85 | }
|
86 |
|
87 | void LEDMatrix::drawImage(uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height, const uint8_t *image)
|
88 | {
|
89 | for (uint16_t y = 0; y < height; y++) {
|
90 | for (uint16_t x = 0; x < width; x++) {
|
91 | const uint8_t *byte = image + (x + y * width) / 8;
|
92 | uint8_t bit = 7 - x % 8;
|
93 | uint8_t pixel = (*byte >> bit) & 1;
|
94 |
|
95 | drawPoint(x + xoffset, y + yoffset, pixel);
|
96 | }
|
97 | }
|
98 | }
|
99 |
|
100 | void LEDMatrix::clear()
|
101 | {
|
102 | uint8_t *ptr = displaybuf;
|
103 | for (uint16_t i = 0; i < (64 * 32 / 8); i++) {
|
104 | *ptr = 0x00;
|
105 | ptr++;
|
106 | }
|
107 | }
|
108 |
|
109 | void LEDMatrix::reverse()
|
110 | {
|
111 | mask = ~mask;
|
112 | }
|
113 |
|
114 | uint8_t LEDMatrix::isReversed()
|
115 | {
|
116 | return mask;
|
117 | }
|
118 |
|
119 | void LEDMatrix::scan()
|
120 | {
|
121 | static uint8_t row = 0; // from 0 to 15
|
122 |
|
123 | if (!state) {
|
124 | return;
|
125 | }
|
126 |
|
127 | uint8_t *head = displaybuf + row * (64 / 8);
|
128 | for (uint8_t line = 0; line < (16 / 16); line++) {
|
129 | uint8_t *ptr = head;
|
130 | uint8_t *ptr2 = head + (64 * 16)/8;
|
131 |
|
132 | head += 64 * 2; // width * 16 / 8
|
133 |
|
134 | for (uint8_t byte = 0; byte < (64 / 8); byte++) {
|
135 | uint8_t pixels = *ptr;
|
136 | uint8_t pixels2 = *ptr2;
|
137 |
|
138 | ptr++;
|
139 | ptr2++;
|
140 | pixels = pixels ^ mask; // reverse: mask = 0xff, normal: mask =0x00
|
141 | pixels2 = pixels2 ^ mask;
|
142 | for (uint8_t bit = 0; bit < 8; bit++) {
|
143 | digitalWrite(clk, LOW);
|
144 | digitalWrite(r1, pixels & (0x80 >> bit));
|
145 | digitalWrite(r2, pixels2 & (0x80 >> bit));
|
146 | digitalWrite(clk, HIGH);
|
147 | }
|
148 | }
|
149 | }
|
150 |
|
151 | digitalWrite(oe, HIGH);
|
152 |
|
153 | // select row
|
154 | digitalWrite(a, (row & 0x01));
|
155 | digitalWrite(b, (row & 0x02));
|
156 | digitalWrite(c, (row & 0x04));
|
157 | digitalWrite(d, (row & 0x08));
|
158 |
|
159 | // latch data
|
160 | digitalWrite(stb, LOW);
|
161 | digitalWrite(stb, HIGH);
|
162 | digitalWrite(stb, LOW);
|
163 |
|
164 | digitalWrite(oe, LOW);
|
165 |
|
166 |
|
167 | row = (row + 1) & 0x0F;
|
168 | }
|
169 |
|
170 | void LEDMatrix::on()
|
171 | {
|
172 | state = 1;
|
173 | }
|
174 |
|
175 | void LEDMatrix::off()
|
176 | {
|
177 | state = 0;
|
178 | digitalWrite(oe, HIGH);
|
179 | }
|