aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/lib/protomatter/examples/doublebuffer_scrolltext
diff options
context:
space:
mode:
Diffstat (limited to 'circuitpython/lib/protomatter/examples/doublebuffer_scrolltext')
-rw-r--r--circuitpython/lib/protomatter/examples/doublebuffer_scrolltext/doublebuffer_scrolltext.ino180
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
+}