/* ---------------------------------------------------------------------- "Simple" Protomatter library example sketch (once you get past all the various pin configurations at the top, and all the comments). Shows basic use of Adafruit_Protomatter library with different devices. This example is written for a 64x32 matrix but can be adapted to others. Once the RGB matrix is initialized, most functions of the Adafruit_GFX library are available for drawing -- code from other projects that use LCDs or OLEDs can be easily adapted, or may be insightful for reference. GFX library is documented here: https://learn.adafruit.com/adafruit-gfx-graphics-library ------------------------------------------------------------------------- */ #include /* ---------------------------------------------------------------------- The RGB matrix must be wired to VERY SPECIFIC pins, different for each microcontroller board. This first section sets that up for a number of supported boards. Notes have been moved to the bottom of the code. ------------------------------------------------------------------------- */ #if defined(_VARIANT_MATRIXPORTAL_M4_) // MatrixPortal M4 uint8_t rgbPins[] = {7, 8, 9, 10, 11, 12}; uint8_t addrPins[] = {17, 18, 19, 20}; uint8_t clockPin = 14; uint8_t latchPin = 15; uint8_t oePin = 16; #elif defined(_VARIANT_FEATHER_M4_) // Feather M4 + RGB Matrix FeatherWing uint8_t rgbPins[] = {6, 5, 9, 11, 10, 12}; uint8_t addrPins[] = {A5, A4, A3, A2}; uint8_t clockPin = 13; uint8_t latchPin = 0; uint8_t oePin = 1; #elif defined(__SAMD51__) // M4 Metro Variants (Express, AirLift) uint8_t rgbPins[] = {6, 5, 9, 11, 10, 12}; uint8_t addrPins[] = {A5, A4, A3, A2}; uint8_t clockPin = 13; uint8_t latchPin = 0; uint8_t oePin = 1; #elif defined(_SAMD21_) // Feather M0 variants uint8_t rgbPins[] = {6, 7, 10, 11, 12, 13}; uint8_t addrPins[] = {0, 1, 2, 3}; uint8_t clockPin = SDA; uint8_t latchPin = 4; uint8_t oePin = 5; #elif defined(NRF52_SERIES) // Special nRF52840 FeatherWing pinout uint8_t rgbPins[] = {6, A5, A1, A0, A4, 11}; uint8_t addrPins[] = {10, 5, 13, 9}; uint8_t clockPin = 12; uint8_t latchPin = PIN_SERIAL1_RX; uint8_t oePin = PIN_SERIAL1_TX; #elif defined(ESP32) // 'Safe' pins, not overlapping any peripherals: // GPIO.out: 4, 12, 13, 14, 15, 21, 27, GPIO.out1: 32, 33 // Peripheral-overlapping pins, sorted from 'most expendible': // 16, 17 (RX, TX) // 25, 26 (A0, A1) // 18, 5, 9 (MOSI, SCK, MISO) // 22, 23 (SCL, SDA) uint8_t rgbPins[] = {4, 12, 13, 14, 15, 21}; uint8_t addrPins[] = {16, 17, 25, 26}; uint8_t clockPin = 27; // Must be on same port as rgbPins uint8_t latchPin = 32; uint8_t oePin = 33; #elif defined(ARDUINO_TEENSY40) uint8_t rgbPins[] = {15, 16, 17, 20, 21, 22}; // A1-A3, A6-A8, skip SDA,SCL uint8_t addrPins[] = {2, 3, 4, 5}; uint8_t clockPin = 23; // A9 uint8_t latchPin = 6; uint8_t oePin = 9; #elif defined(ARDUINO_TEENSY41) uint8_t rgbPins[] = {26, 27, 38, 20, 21, 22}; // A12-14, A6-A8 uint8_t addrPins[] = {2, 3, 4, 5}; uint8_t clockPin = 23; // A9 uint8_t latchPin = 6; uint8_t oePin = 9; #endif /* ---------------------------------------------------------------------- Okay, here's where the RGB LED matrix is actually declared... First argument is the matrix width, in pixels. Usually 32 or 64, but might go larger if you're chaining multiple matrices. Second argument is the "bit depth," which determines color fidelity, applied to red, green and blue (e.g. "4" here means 4 bits red, 4 green, 4 blue = 2^4 x 2^4 x 2^4 = 4096 colors). There is a trade-off between bit depth and RAM usage. Most programs will tend to use either 1 (R,G,B on/off, 8 colors, best for text, LED sand, etc.) or the maximum of 6 (best for shaded images...though, because the GFX library was designed for LCDs, only 5 of those bits are available for red and blue. Third argument is the number of concurrent (parallel) matrix outputs. THIS SHOULD ALWAYS BE "1" FOR NOW. Fourth is a uint8_t array listing six pins: red, green and blue data out for the top half of the display, and same for bottom half. There are hard constraints as to which pins can be used -- they must all be on the same PORT register, ideally all within the same byte of that PORT. Fifth argument is the number of "address" (aka row select) pins, from which the matrix height is inferred. "4" here means four address lines, matrix height is then (2 x 2^4) = 32 pixels. 16-pixel-tall matrices will have 3 pins here, 32-pixel will have 4, 64-pixel will have 5. Sixth argument is a uint8_t array listing those pin numbers. No PORT constraints here. Next three arguments are pin numbers for other RGB matrix control lines: clock, latch and output enable (active low). Clock pin MUST be on the same PORT register as RGB data pins (and ideally in same byte). Other pins have no special rules. Last argument is a boolean (true/false) to enable double- buffering for smooth animation (requires 2X the RAM). See the "doublebuffer" example for a demonstration. ------------------------------------------------------------------------- */ Adafruit_Protomatter matrix( 64, // Width of matrix (or matrix chain) in pixels 4, // Bit depth, 1-6 1, rgbPins, // # of matrix chains, array of 6 RGB pins for each 4, addrPins, // # of address pins (height is inferred), array of pins clockPin, latchPin, oePin, // Other matrix control pins false); // No double-buffering here (see "doublebuffer" example) // SETUP - RUNS ONCE AT PROGRAM START -------------------------------------- void setup(void) { Serial.begin(9600); // Initialize matrix... ProtomatterStatus status = matrix.begin(); Serial.print("Protomatter begin() status: "); Serial.println((int)status); if(status != PROTOMATTER_OK) { // DO NOT CONTINUE if matrix setup encountered an error. for(;;); } // Since this is a simple program with no animation, all the // drawing can be done here in setup() rather than loop(): // Make four color bars (red, green, blue, white) with brightness ramp: for(int x=0; x