display.ino 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. LED Matrix Display Driver
  3. Library doc
  4. https://majicdesigns.github.io/MD_MAX72XX/class_m_d___m_a_x72_x_x.html
  5. */
  6. #define FRAME_BUFFER_SIZE 64 //4(32 bits) x 16 bytes
  7. //SD error frame buffer. If animation read failed, this
  8. //will be copied to frame buffer insteads
  9. const unsigned char sd_error_fb[] = {
  10. 0x00, 0x00, 0x00, 0x00,
  11. 0x77, 0x3b, 0x9c, 0x00,
  12. 0x44, 0xa2, 0x52, 0x00,
  13. 0x74, 0xbb, 0x9c, 0x00,
  14. 0x14, 0xa2, 0x52, 0x00,
  15. 0x77, 0x3a, 0x52, 0x00,
  16. 0x00, 0x00, 0x00, 0x00,
  17. 0x00, 0x00, 0x00, 0x00,
  18. 0x00, 0x00, 0x00, 0x00,
  19. 0x00, 0x00, 0x00, 0x00,
  20. 0x00, 0x00, 0x00, 0x00,
  21. 0x00, 0x00, 0x00, 0x00,
  22. 0x00, 0x00, 0x00, 0x00,
  23. 0x00, 0x00, 0x00, 0x00,
  24. 0x00, 0x00, 0x00, 0x00,
  25. 0x00, 0x00, 0x00, 0x00
  26. };
  27. //frame buffer, 32x16px
  28. //each LED is 1 bit
  29. unsigned char frame_buffer[] = {
  30. 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x00, 0x00,
  32. 0x00, 0x00, 0x00, 0x00,
  33. 0x22, 0x00, 0x00, 0x44,
  34. 0x44, 0x00, 0x00, 0x22,
  35. 0x89, 0x80, 0x01, 0x91,
  36. 0x92, 0x40, 0x02, 0x49,
  37. 0x82, 0x40, 0x02, 0x41,
  38. 0x81, 0x80, 0x01, 0x81,
  39. 0x80, 0x04, 0x40, 0x01,
  40. 0x80, 0x09, 0x20, 0x01,
  41. 0x87, 0x89, 0x21, 0xe1,
  42. 0x40, 0x06, 0xc0, 0x02,
  43. 0x27, 0x80, 0x01, 0xe4,
  44. 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x00, 0x00
  46. };
  47. //A combined function for read frame to framebuffer and render to display
  48. //Example usage: loadFrameAndRender("/a.bin");
  49. void loadFrameAndRender(String filepath) {
  50. readFrameToFrameBuffer(filepath);
  51. renderFrame();
  52. }
  53. //Load the SD read error message to framebuffer
  54. void loadSDErrorToFrameBuffer(){
  55. //sd_error_fb and frame_buffer should be the same
  56. size_t bufferSize = sizeof(sd_error_fb) / sizeof(sd_error_fb[0]);
  57. for (size_t i = 0; i < bufferSize; i++) {
  58. frame_buffer[i] = sd_error_fb[i];
  59. }
  60. }
  61. //Read a binary file from SD card to current framebuffer
  62. int readFrameToFrameBuffer(String filepath) {
  63. File file = SD.open(filepath, FILE_READ);
  64. if (!file) {
  65. Serial.println("Failed to open file for reading");
  66. return 1;
  67. }
  68. // Read file byte by byte
  69. size_t bytesRead = 0;
  70. while (file.available() && bytesRead < FRAME_BUFFER_SIZE) {
  71. frame_buffer[bytesRead] = file.read();
  72. bytesRead++;
  73. }
  74. // Close the file
  75. file.close();
  76. return 0;
  77. }
  78. /*
  79. * renderFrame render the frame buffer to display
  80. *
  81. * The display is an upside down two split LED grid matrix display
  82. * the render sequence (when viewed from front) is as follows
  83. * and each matrix module is upside down (row 0 on bottom)
  84. * [8][7][6][5]
  85. * [4][3][2][1]
  86. *
  87. */
  88. void renderFrame() {
  89. //Top half of the display
  90. int fsize = sizeof(frame_buffer);
  91. for (int i = 0; i < fsize / 2; i += 4) {
  92. for (int d = 0; d <= 3; d++) {
  93. //For each of the driver, from 0 to 3
  94. byte rowData = frame_buffer[i + d];
  95. mx.setRow(d, d, 7 - int(i / 4), fByte(rowData));
  96. }
  97. }
  98. //Bottom half of the display
  99. for (int i = fsize / 2; i < fsize; i += 4) {
  100. for (int d = 4; d <= 7; d++) {
  101. //For each of the driver, from 4 to 7
  102. byte rowData = frame_buffer[i + (d - 4)];
  103. mx.setRow(d, d, 7 - (int(i / 4) - 8), fByte(rowData));
  104. }
  105. }
  106. }
  107. //Clear the display to off state
  108. void clearFrame() {
  109. //Z is reserved for empty screen
  110. setAnimationCode('z');
  111. }
  112. /* Utilities Functions */
  113. //Set display brightness, from 0x0(min) to 0xF (max)
  114. void setDisplayBrightness(byte brightness) {
  115. for (int i = 0; i < MAX_DEVICES; i++) {
  116. mx.control(i, MD_MAX72XX::INTENSITY, brightness);
  117. }
  118. }
  119. //Helper function to reverse a byte in bits
  120. //e.g. 11011101 -> 10111011
  121. byte fByte(byte c) {
  122. char r = 0;
  123. for (byte i = 0; i < 8; i++) {
  124. r <<= 1;
  125. r |= c & 1;
  126. c >>= 1;
  127. }
  128. return r;
  129. }