123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- LED Matrix Display Driver
-
- Library doc
- https://majicdesigns.github.io/MD_MAX72XX/class_m_d___m_a_x72_x_x.html
- */
- #define FRAME_BUFFER_SIZE 64 //4(32 bits) x 16 bytes
- //SD error frame buffer. If animation read failed, this
- //will be copied to frame buffer insteads
- const unsigned char sd_error_fb[] = {
- 0x00, 0x00, 0x00, 0x00,
- 0x77, 0x3b, 0x9c, 0x00,
- 0x44, 0xa2, 0x52, 0x00,
- 0x74, 0xbb, 0x9c, 0x00,
- 0x14, 0xa2, 0x52, 0x00,
- 0x77, 0x3a, 0x52, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- //frame buffer, 32x16px
- //each LED is 1 bit
- unsigned char frame_buffer[] = {
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x22, 0x00, 0x00, 0x44,
- 0x44, 0x00, 0x00, 0x22,
- 0x89, 0x80, 0x01, 0x91,
- 0x92, 0x40, 0x02, 0x49,
- 0x82, 0x40, 0x02, 0x41,
- 0x81, 0x80, 0x01, 0x81,
- 0x80, 0x04, 0x40, 0x01,
- 0x80, 0x09, 0x20, 0x01,
- 0x87, 0x89, 0x21, 0xe1,
- 0x40, 0x06, 0xc0, 0x02,
- 0x27, 0x80, 0x01, 0xe4,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- //A combined function for read frame to framebuffer and render to display
- //Example usage: loadFrameAndRender("/a.bin");
- void loadFrameAndRender(String filepath) {
- readFrameToFrameBuffer(filepath);
- renderFrame();
- }
- //Load the SD read error message to framebuffer
- void loadSDErrorToFrameBuffer(){
- //sd_error_fb and frame_buffer should be the same
- size_t bufferSize = sizeof(sd_error_fb) / sizeof(sd_error_fb[0]);
- for (size_t i = 0; i < bufferSize; i++) {
- frame_buffer[i] = sd_error_fb[i];
- }
- }
- //Read a binary file from SD card to current framebuffer
- int readFrameToFrameBuffer(String filepath) {
- File file = SD.open(filepath, FILE_READ);
- if (!file) {
- Serial.println("Failed to open file for reading");
- return 1;
- }
- // Read file byte by byte
- size_t bytesRead = 0;
- while (file.available() && bytesRead < FRAME_BUFFER_SIZE) {
- frame_buffer[bytesRead] = file.read();
- bytesRead++;
- }
- // Close the file
- file.close();
- return 0;
- }
- /*
- * renderFrame render the frame buffer to display
- *
- * The display is an upside down two split LED grid matrix display
- * the render sequence (when viewed from front) is as follows
- * and each matrix module is upside down (row 0 on bottom)
- * [8][7][6][5]
- * [4][3][2][1]
- *
- */
- void renderFrame() {
- //Top half of the display
- int fsize = sizeof(frame_buffer);
- for (int i = 0; i < fsize / 2; i += 4) {
- for (int d = 0; d <= 3; d++) {
- //For each of the driver, from 0 to 3
- byte rowData = frame_buffer[i + d];
- mx.setRow(d, d, 7 - int(i / 4), fByte(rowData));
- }
- }
- //Bottom half of the display
- for (int i = fsize / 2; i < fsize; i += 4) {
- for (int d = 4; d <= 7; d++) {
- //For each of the driver, from 4 to 7
- byte rowData = frame_buffer[i + (d - 4)];
- mx.setRow(d, d, 7 - (int(i / 4) - 8), fByte(rowData));
- }
- }
- }
- //Clear the display to off state
- void clearFrame() {
- //Z is reserved for empty screen
- setAnimationCode('z');
- }
- /* Utilities Functions */
- //Set display brightness, from 0x0(min) to 0xF (max)
- void setDisplayBrightness(byte brightness) {
- for (int i = 0; i < MAX_DEVICES; i++) {
- mx.control(i, MD_MAX72XX::INTENSITY, brightness);
- }
- }
- //Helper function to reverse a byte in bits
- //e.g. 11011101 -> 10111011
- byte fByte(byte c) {
- char r = 0;
- for (byte i = 0; i < 8; i++) {
- r <<= 1;
- r |= c & 1;
- c >>= 1;
- }
- return r;
- }
|