LEDMatrix.cpp


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
}