diff options
Diffstat (limited to 'circuitpython/lib/protomatter/examples/doublebuffer_scrolltext')
-rw-r--r-- | circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino b/circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino new file mode 100644 index 0000000..03e2aa4 --- /dev/null +++ b/circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino @@ -0,0 +1,180 @@ +/* ---------------------------------------------------------------------- +Double-buffering (smooth animation) Protomatter library example. +PLEASE SEE THE "simple" EXAMPLE FOR AN INTRODUCTORY SKETCH. +Comments here pare down many of the basics and focus on the new concepts. + +This example is written for a 64x32 matrix but can be adapted to others. +------------------------------------------------------------------------- */ + +#include <Adafruit_Protomatter.h> +#include <Fonts/FreeSansBold18pt7b.h> // Large friendly font + +/* ---------------------------------------------------------------------- +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. +------------------------------------------------------------------------- */ + +#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 + +/* ---------------------------------------------------------------------- +Matrix initialization is explained EXTENSIVELY in "simple" example sketch! +It's very similar here, but we're passing "true" for the last argument, +enabling double-buffering -- this permits smooth animation by having us +draw in a second "off screen" buffer while the other is being shown. +------------------------------------------------------------------------- */ + +Adafruit_Protomatter matrix( + 64, // Matrix width in pixels + 6, // Bit depth -- 6 here provides maximum color options + 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 + true); // HERE IS THE MAGIG FOR DOUBLE-BUFFERING! + +// Sundry globals used for animation --------------------------------------- + +int16_t textX = matrix.width(), // Current text position (X) + textY, // Current text position (Y) + textMin, // Text pos. (X) when scrolled off left edge + hue = 0; +char str[50]; // Buffer to hold scrolling message text +int8_t ball[3][4] = { + { 3, 0, 1, 1 }, // Initial X,Y pos+velocity of 3 bouncy balls + { 17, 15, 1, -1 }, + { 27, 4, -1, 1 } +}; +uint16_t ballcolor[3]; // Colors for bouncy balls (init in setup()) + +// 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(;;); + } + + // Unlike the "simple" example, we don't do any drawing in setup(). + // But we DO initialize some things we plan to animate... + + // Set up the scrolling message... + sprintf(str, "Adafruit %dx%d RGB LED Matrix", + matrix.width(), matrix.height()); + matrix.setFont(&FreeSansBold18pt7b); // Use nice bitmap font + matrix.setTextWrap(false); // Allow text off edge + matrix.setTextColor(0xFFFF); // White + int16_t x1, y1; + uint16_t w, h; + matrix.getTextBounds(str, 0, 0, &x1, &y1, &w, &h); // How big is it? + textMin = -w; // All text is off left edge when it reaches this point + textY = matrix.height() / 2 - (y1 + h / 2); // Center text vertically + // Note: when making scrolling text like this, the setTextWrap(false) + // call is REQUIRED (to allow text to go off the edge of the matrix), + // AND it must be BEFORE the getTextBounds() call (or else that will + // return the bounds of "wrapped" text). + + // Set up the colors of the bouncy balls. + ballcolor[0] = matrix.color565(0, 20, 0); // Dark green + ballcolor[1] = matrix.color565(0, 0, 20); // Dark blue + ballcolor[2] = matrix.color565(20, 0, 0); // ark red +} + +// LOOP - RUNS REPEATEDLY AFTER SETUP -------------------------------------- + +void loop(void) { + // Every frame, we clear the background and draw everything anew. + // This happens "in the background" with double buffering, that's + // why you don't see everything flicker. It requires double the RAM, + // so it's not practical for every situation. + + matrix.fillScreen(0); // Fill background black + + // Draw the big scrolly text + matrix.setCursor(textX, textY); + matrix.print(str); + + // Update text position for next frame. If text goes off the + // left edge, reset its position to be off the right edge. + if((--textX) < textMin) textX = matrix.width(); + + // Draw the three bouncy balls on top of the text... + for(byte i=0; i<3; i++) { + // Draw 'ball' + matrix.fillCircle(ball[i][0], ball[i][1], 5, ballcolor[i]); + // Update ball's X,Y position for next frame + ball[i][0] += ball[i][2]; + ball[i][1] += ball[i][3]; + // Bounce off edges + if((ball[i][0] == 0) || (ball[i][0] == (matrix.width() - 1))) + ball[i][2] *= -1; + if((ball[i][1] == 0) || (ball[i][1] == (matrix.height() - 1))) + ball[i][3] *= -1; + } + + // AFTER DRAWING, A show() CALL IS REQUIRED TO UPDATE THE MATRIX! + + matrix.show(); + + delay(20); // 20 milliseconds = ~50 frames/second +} |