From 5730b4f57d56f20dfd07fb87981f0d3d1788a6ea Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 14:56:47 -0500 Subject: [PATCH 01/10] newxie examples adding CP and arduino examples for vertical newxie display --- .../Newxie_Arduino/.uno.test.only | 0 .../Newxie_Arduino/Newxie_Arduino.ino | 676 ++++++++++++++++++ .../Helvetica-Bold-16.pcf | Bin 0 -> 145784 bytes .../Newxie_CircuitPython/adabot.bmp | Bin 0 -> 32780 bytes .../Newxie_CircuitPython/code.py | 326 +++++++++ 5 files changed, 1002 insertions(+) create mode 100644 Newxie_TFT_Examples/Newxie_Arduino/.uno.test.only create mode 100644 Newxie_TFT_Examples/Newxie_Arduino/Newxie_Arduino.ino create mode 100644 Newxie_TFT_Examples/Newxie_CircuitPython/Helvetica-Bold-16.pcf create mode 100644 Newxie_TFT_Examples/Newxie_CircuitPython/adabot.bmp create mode 100644 Newxie_TFT_Examples/Newxie_CircuitPython/code.py diff --git a/Newxie_TFT_Examples/Newxie_Arduino/.uno.test.only b/Newxie_TFT_Examples/Newxie_Arduino/.uno.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/Newxie_TFT_Examples/Newxie_Arduino/Newxie_Arduino.ino b/Newxie_TFT_Examples/Newxie_Arduino/Newxie_Arduino.ino new file mode 100644 index 000000000..6aa3604b6 --- /dev/null +++ b/Newxie_TFT_Examples/Newxie_Arduino/Newxie_Arduino.ino @@ -0,0 +1,676 @@ +// SPDX-FileCopyrightText: 2022 Phillip Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Graphics example for EYESPI-capable color displays. This code: +// - Functions as a "Hello World" to verify that microcontroller and screen +// are communicating. +// - Demonstrates most of the drawing commands of the Adafruit_GFX library. +// - Showcases some techniques that might not be obvious or that aren't +// built-in but can be handled with a little extra code. +// It DOES NOT: +// - Support all Adafruit screens, ONLY EYESPI products at the time this was +// written! But it's easily adapted by looking at other examples. +// - Demonstrate the Adafruit_GFX_Button class, as that's unique to +// touch-capable displays. Again, other examples may cover this topic. +// This sketch is long, but a lot of it is comments to explain each step. You +// can copy just the parts you need as a starting point for your own projects, +// and strip comments once understood. + +// CONSTANTS, HEADERS and GLOBAL VARIABLES --------------------------------- + +// *** EDIT THIS VALUE TO MATCH THE ADAFRUIT PRODUCT ID FOR YOUR DISPLAY: *** +#define SCREEN_PRODUCT_ID 6113 // Newxie 135x240 display +// You can find the product ID several ways: +// - "PID" accompanies each line-item on your receipt or order details page. +// - Visit adafruit.com and search for EYESPI displays. On product pages, +// PID is shown just below product title, and is at the end of URLs. +// - Check the comments in setup() later that reference various screens. + +// **** EDIT PINS TO MATCH YOUR WIRING **** +#define TFT_CS 10 // To display chip-select pin +#define TFT_RST -1 // To display reset pin +#define TFT_DC 8 // To display data/command pin +// For the remaining pins, this code assumes display is wired to hardware SPI +// on the dev board's primary SPI interface. The display libraries can support +// secondary SPI (if present) or bitbang (software) SPI, but that's not +// demonstrated here. See other examples for more varied interfacing options. +#include +#include // Core graphics library +#include // A custom font +#if (SCREEN_PRODUCT_ID == 1480) || (SCREEN_PRODUCT_ID == 2090) +#include // Library for ILI9341-based screens +Adafruit_ILI9341 display(TFT_CS, TFT_DC, TFT_RST); +#else +#include // Library for ST7789-based screens +Adafruit_ST7789 display(TFT_CS, TFT_DC, TFT_RST); +#endif + +#define PAUSE 3000 // Delay (millisecondss) between examples +uint8_t rotate = 0; // Current screen orientation (0-3) + +// setup() RUNS ONCE AT PROGRAM STARTUP ------------------------------------ + +void setup() { + // Initialize display hardware +#if (SCREEN_PRODUCT_ID == 5393) // 1.47" 320x172 round-rect TFT +#define CORNER_RADIUS 22 + display.init(172, 320); +#elif (SCREEN_PRODUCT_ID == 3787) // 1.54" 240x240 TFT + display.init(240, 240); +#elif (SCREEN_PRODUCT_ID == 5206) // 1.69" 280x240 round-rect TFT +#define CORNER_RADIUS 43 + display.init(240, 280); +#elif (SCREEN_PRODUCT_ID == 5394) // 1.9" 320x170 TFT + display.init(170, 320); +#elif (SCREEN_PRODUCT_ID == 6113) + display.init(135, 240); +#else // All ILI9341 TFTs (320x240) + display.begin(); +#endif +#if !defined(CORNER_RADIUS) +#define CORNER_RADIUS 0 +#endif + + // OPTIONAL: default TFT SPI speed is fairly conservative, you can try + // overriding here for faster screen updates. Actual SPI speed may be less + // depending on microcontroller's capabilities. Max reliable speed also + // depends on wiring length and tidyness. + //display.setSPISpeed(40000000); +} + +// MAIN LOOP, REPEATS FOREVER ---------------------------------------------- + +void loop() { + // Each of these functions demonstrates a different Adafruit_GFX concept: + show_shapes(); + show_charts(); + show_basic_text(); + show_char_map(); + show_custom_text(); + show_bitmap(); +#if !defined(AVR) + // The full set of examples (plus the custom font) won't fit on an 8-bit + // Arduino, something's got to go. You can try out this one IF the other + // examples are disabled instead. + show_canvas(); +#endif + + if (++rotate > 3) rotate = 0; // Cycle through screen rotations 0-3 + display.setRotation(rotate); // Takes effect on next drawing command +} + +// BASIC SHAPES EXAMPLE ---------------------------------------------------- + +void show_shapes() { + // Draw outlined and filled shapes. This demonstrates: + // - Enclosed shapes supported by GFX (points & lines are shown later). + // - Adapting to different-sized displays, and to rounded corners. + + const int16_t cx = display.width() / 2; // Center of screen = + const int16_t cy = display.height() / 2; // half of width, height + int16_t minor = min(cx, cy); // Lesser of half width or height + // Shapes will be drawn in a square region centered on the screen. But one + // particular screen -- rounded 240x280 ST7789 -- has VERY rounded corners + // that would clip a couple of shapes if drawn full size. If using that + // screen type, reduce area by a few pixels to avoid drawing in corners. + if (CORNER_RADIUS > 40) minor -= 4; + const uint8_t pad = 5; // Space between shapes is 2X this + const int16_t size = minor - pad; // Shapes are this width & height + const int16_t half = size / 2; // 1/2 of shape size + + display.fillScreen(0); // Start by clearing the screen; color 0 = black + + // Draw outline version of basic shapes: rectangle, triangle, circle and + // rounded rectangle in different colors. Rather than hardcoded numbers + // for position and size, some arithmetic helps adapt to screen dimensions. + display.drawRect(cx - minor, cy - minor, size, size, 0xF800); + display.drawTriangle(cx + pad, cy - pad, cx + pad + half, cy - minor, + cx + minor - 1, cy - pad, 0x07E0); + display.drawCircle(cx - pad - half, cy + pad + half, half, 0x001F); + display.drawRoundRect(cx + pad, cy + pad, size, size, size / 5, 0xFFE0); + delay(PAUSE); + + // Draw same shapes, same positions, but filled this time. + display.fillRect(cx - minor, cy - minor, size, size, 0xF800); + display.fillTriangle(cx + pad, cy - pad, cx + pad + half, cy - minor, + cx + minor - 1, cy - pad, 0x07E0); + display.fillCircle(cx - pad - half, cy + pad + half, half, 0x001F); + display.fillRoundRect(cx + pad, cy + pad, size, size, size / 5, 0xFFE0); + delay(PAUSE); +} // END SHAPE EXAMPLE + +// CHART EXAMPLES ---------------------------------------------------------- + +void show_charts() { + // Draw some graphs and charts. GFX library doesn't handle these as native + // object types, but it only takes a little code to build them from simple + // shapes. This demonstrates: + // - Drawing points and horizontal, vertical and arbitrary lines. + // - Adapting to different-sized displays. + // - Graphics being clipped off edge. + // - Use of negative values to draw shapes "backward" from an anchor point. + // - C technique for finding array size at runtime (vs hardcoding). + + display.fillScreen(0); // Clear screen + + const int16_t cx = display.width() / 2; // Center of screen = + const int16_t cy = display.height() / 2; // half of width, height + const int16_t minor = min(cx, cy); // Lesser of half width or height + const int16_t major = max(cx, cy); // Greater of half width or height + + // Let's start with a relatively simple sine wave graph with axes. + // Draw graph axes centered on screen. drawFastHLine() and drawFastVLine() + // need fewer arguments than normal 2-point line drawing shown later. + display.drawFastHLine(0, cy, display.width(), 0x0210); // Dark blue + display.drawFastVLine(cx, 0, display.height(), 0x0210); + + // Then draw some tick marks along the axes. To keep this code simple, + // these aren't to any particular scale, but a real program may want that. + // The loop here draws them from the center outward and pays no mind + // whether the screen is rectangular; any ticks that go off-screen will + // be clipped by the library. + for (uint8_t i=1; i<=10; i++) { + // The Arduino map() function scales an input value (e.g. "i") from an + // input range (0-10 here) to an output range (0 to major-1 here). + // Very handy for making graphics adjust to different screens! + int16_t n = map(i, 0, 10, 0, major - 1); // Tick offset relative to center point + display.drawFastVLine(cx - n, cy - 5, 11, 0x210); + display.drawFastVLine(cx + n, cy - 5, 11, 0x210); + display.drawFastHLine(cx - 5, cy - n, 11, 0x210); + display.drawFastHLine(cx - 5, cy + n, 11, 0x210); + } + + // Then draw sine wave over this using GFX drawPixel() function. + for (int16_t x=0; x(str.c_str())); +} + +// TEXT EXAMPLES ----------------------------------------------------------- + +// This section demonstrates: +// - Using the default 5x7 built-in font, including scaling in each axis. +// - How to access all characters of this font, including symbols. +// - Using a custom font, including alignment techniques that aren't a normal +// part of the GFX library (uses functions above). + +void show_basic_text() { + // Show text scaling with built-in font. + display.fillScreen(0); + display.setFont(); // Use default font + display.setCursor(0, CORNER_RADIUS); // Initial cursor position + display.setTextSize(1); // Default size + display.println(F("Standard built-in font")); + display.setTextSize(2); + display.println(F("BIG TEXT")); + display.setTextSize(3); + // "BIGGER TEXT" won't fit on narrow screens, so abbreviate there. + display.println((display.width() >= 200) ? F("BIGGER TEXT") : F("BIGGER")); + display.setTextSize(2, 4); + display.println(F("TALL and")); + display.setTextSize(4, 2); + display.println(F("WIDE")); + + delay(PAUSE); +} // END BASIC TEXT EXAMPLE + +void show_char_map() { + // "Code Page 437" is a name given to the original IBM PC character set. + // Despite age and limited language support, still seen in small embedded + // settings as it has some useful symbols and accented characters. The + // default 5x7 pixel font of Adafruit_GFX is modeled after CP437. This + // function draws a table of all the characters & explains some issues. + + // There are 256 characters in all. Draw table as 16 rows of 16 columns, + // plus hexadecimal row & column labels. How big can each cell be drawn? + const int cell_size = min(display.width(), display.height()) / 17; + if (cell_size < 8) return; // Screen is too small for table, skip example. + const int total_size = cell_size * 17; // 16 cells + 1 row or column label + + // Set up for default 5x7 font at 1:1 scale. Custom fonts are NOT used + // here as most are only 128 characters to save space (the "7b" at the + // end of many GFX font names means "7 bits," i.e. 128 characters). + display.setFont(); + display.setTextSize(1); + + // Early Adafruit_GFX was missing one symbol, throwing off some indices! + // But fixing the library would break MANY existing sketches that relied + // on the degrees symbol and others. The default behavior is thus "broken" + // to keep older code working. New code can access the CORRECT full CP437 + // table by calling this function like so: + display.cp437(true); + + display.fillScreen(0); + + const int16_t x = (display.width() - total_size) / 2; // Upper left corner of + int16_t y = (display.height() - total_size) / 2; // table centered on screen + if (y >= 4) { // If there's a little extra space above & below, scoot table + y += 4; // down a few pixels and show a message centered at top. + display.setCursor((display.width() - 114) / 2, 0); // 114 = pixel width + display.print(F("CP437 Character Map")); // of this message + } + + const int16_t inset_x = (cell_size - 5) / 2; // To center each character within cell, + const int16_t inset_y = (cell_size - 8) / 2; // compute X & Y offset from corner. + + for (uint8_t row=0; row<16; row++) { // 16 down... + // Draw row and columm headings as hexadecimal single digits. To get the + // hex value for a specific character, combine the left & top labels, + // e.g. Pi symbol is row E, column 3, thus: display.print((char)0xE3); + display.setCursor(x + (row + 1) * cell_size + inset_x, y + inset_y); + display.print(row, HEX); // This actually draws column labels + display.setCursor(x + inset_x, y + (row + 1) * cell_size + inset_y); + display.print(row, HEX); // and THIS is the row labels + for (uint8_t col=0; col<16; col++) { // 16 across... + if ((row + col) & 1) { // Fill alternating cells w/gray + display.fillRect(x + (col + 1) * cell_size, y + (row + 1) * cell_size, + cell_size, cell_size, 0x630C); + } + // drawChar() bypasses usual cursor positioning to go direct to an X/Y + // location. If foreground & background match, it's drawn transparent. + display.drawChar(x + (col + 1) * cell_size + inset_x, + y + (row + 1) * cell_size + inset_y, row * 16 + col, + 0xFFFF, 0xFFFF, 1); + } + } + + delay(PAUSE * 2); +} // END CHAR MAP EXAMPLE + +void show_custom_text() { + // Show use of custom fonts, plus how to do center or right alignment + // using some additional functions provided earlier. + + display.fillScreen(0); + display.setFont(&FreeSansBold18pt7b); + display.setTextSize(1); + display.setTextWrap(false); // Allow text off edges + + // Get "M height" of custom font and move initial base line there: + uint16_t w, h; + int16_t x, y; + display.getTextBounds("M", 0, 0, &x, &y, &w, &h); + // On rounded 240x280 display in tall orientation, "Custom Font" gets + // clipped by top corners. Scoot text down a few pixels in that one case. + if (CORNER_RADIUS && (display.height() == 280)) h += 20; + display.setCursor(display.width() / 2, h); + + if (display.width() >= 200) { + print_aligned(display, F("Custom Font"), GFX_ALIGN_CENTER); + display.setCursor(0, display.getCursorY() + 10); + print_aligned(display, F("Align Left"), GFX_ALIGN_LEFT); + display.setCursor(display.width() / 2, display.getCursorY()); + print_aligned(display, F("Centered"), GFX_ALIGN_CENTER); + // Small rounded screen, when oriented the wide way, "Right" gets + // clipped by bottom right corner. Scoot left to compensate. + int16_t x_offset = (CORNER_RADIUS && (display.height() < 200)) ? 15 : 0; + display.setCursor(display.width() - x_offset, display.getCursorY()); + print_aligned(display, F("Align Right"), GFX_ALIGN_RIGHT); + } else { + // On narrow screens, use abbreviated messages + print_aligned(display, F("Font &"), GFX_ALIGN_CENTER); + print_aligned(display, F("Align"), GFX_ALIGN_CENTER); + display.setCursor(0, display.getCursorY() + 10); + print_aligned(display, F("Left"), GFX_ALIGN_LEFT); + display.setCursor(display.width() / 2, display.getCursorY()); + print_aligned(display, F("Center"), GFX_ALIGN_CENTER); + display.setCursor(display.width(), display.getCursorY()); + print_aligned(display, F("Right"), GFX_ALIGN_RIGHT); + } + + delay(PAUSE); +} // END CUSTOM FONT EXAMPLE + +// BITMAP EXAMPLE ---------------------------------------------------------- + +// This section demonstrates: +// - Embedding a small bitmap in the code (flash memory). +// - Drawing that bitmap in various colors, and transparently (only '1' bits +// are drawn; '0' bits are skipped, leaving screen contents in place). +// - Use of the color565() function to decimate 24-bit RGB to 16 bits. + +#define HEX_WIDTH 16 // Bitmap width in pixels +#define HEX_HEIGHT 16 // Bitmap height in pixels +// Bitmap data. PROGMEM ensures it's in flash memory (not RAM). And while +// it would be valid to leave the brackets empty here (i.e. hex_bitmap[]), +// having dimensions with a little math makes the compiler verify the +// correct number of bytes are present in the list. +PROGMEM const uint8_t hex_bitmap[(HEX_WIDTH + 7) / 8 * HEX_HEIGHT] = { + 0b00000001, 0b10000000, + 0b00000111, 0b11100000, + 0b00011111, 0b11111000, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b01111111, 0b11111110, + 0b00011111, 0b11111000, + 0b00000111, 0b11100000, + 0b00000001, 0b10000000, +}; +#define Y_SPACING (HEX_HEIGHT - 2) // Used by code below for positioning + +void show_bitmap() { + display.fillScreen(0); + + // Not screen center, but UL coordinates of center hexagon bitmap + const int16_t center_x = (display.width() - HEX_WIDTH) / 2; + const int16_t center_y = (display.height() - HEX_HEIGHT) / 2; + const uint8_t steps = min((display.height() - HEX_HEIGHT) / Y_SPACING, + display.width() / HEX_WIDTH - 1) / 2; + + display.drawBitmap(center_x, center_y, hex_bitmap, HEX_WIDTH, HEX_HEIGHT, + 0xFFFF); // Draw center hexagon in white + + // Tile the hexagon bitmap repeatedly in a range of hues. Don't mind the + // bit of repetition in the math, the optimizer easily picks this up. + // Also, if math looks odd, keep in mind "PEMDAS" operator precedence; + // multiplication and division occur before addition and subtraction. + for (uint8_t a=0; a<=steps; a++) { + for (uint8_t b=1; b<=steps; b++) { + display.drawBitmap( // Right section centered red: a = green, b = blue + center_x + (a + b) * HEX_WIDTH / 2, + center_y + (a - b) * Y_SPACING, + hex_bitmap, HEX_WIDTH, HEX_HEIGHT, + display.color565(255, 255 - 255 * a / steps, 255 - 255 * b / steps)); + display.drawBitmap( // UL section centered green: a = blue, b = red + center_x - b * HEX_WIDTH + a * HEX_WIDTH / 2, + center_y - a * Y_SPACING, + hex_bitmap, HEX_WIDTH, HEX_HEIGHT, + display.color565(255 - 255 * b / steps, 255, 255 - 255 * a / steps)); + display.drawBitmap( // LL section centered blue: a = red, b = green + center_x - a * HEX_WIDTH + b * HEX_WIDTH / 2, + center_y + b * Y_SPACING, + hex_bitmap, HEX_WIDTH, HEX_HEIGHT, + display.color565(255 - 255 * a / steps, 255 - 255 * b / steps, 255)); + } + } + + delay(PAUSE); +} // END BITMAP EXAMPLE + +// CANVAS EXAMPLE ---------------------------------------------------------- + +// This section demonstrates: +// - How to refresh changing values onscreen without erase/redraw flicker. +// - Using an offscreen canvas. It's similar to a bitmap above, but rather +// than a fixed pattern in flash memory, it's drawable like the screen. +// - More tips on text alignment, and adapting to different screen sizes. + +#define PADDING 6 // Pixels between axis label and value + +void show_canvas() { + // For this example, let's suppose we want to display live readings from a + // sensor such as a three-axis accelerometer, something like: + // X: (number) + // Y: (number) + // Z: (number) + // To look extra classy, we want a custom font, and the labels for each + // axis are right-aligned so the ':' characters line up... + + display.setFont(&FreeSansBold18pt7b); // Use a custom font + display.setTextSize(1); // and reset to 1:1 scale + + const char *label[] = { "X:", "Y:", "Z:" }; // Labels for each axis + const uint16_t color[] = { 0xF800, 0x07E0, 0x001F }; // Colors for each value + + // To get the labels right-aligned, one option would be simple trial and + // error to find a column that looks good and doesn't clip anything off. + // Let's do this dynamically though, so it adapts to any font or labels! + // Start by finding the widest of the label strings: + uint16_t w, h, max_w = 0; + int16_t x, y; + for (uint8_t i=0; i<3; i++) { // For each label... + display.getTextBounds(label[i], 0, 0, &x, &y, &w, &h); + if (w > max_w) max_w = w; // Keep track of widest label + } + + // Rounded corners throwing us a curve again. If needed, scoot everything + // to the right a bit on wide displays, down a bit on tall ones. + int16_t y_offset = 0; + if (display.width() > display.height()) max_w += CORNER_RADIUS; + else y_offset = CORNER_RADIUS; + + // Now we have max_w for right-aligning the labels. Before we draw them + // though...in order to perform flicker-free updates, the numbers we show + // will be rendered in either a GFXcanvas1 or GFXcanvas16 object; a 1-bit + // or 16-bit offscreen bitmap, RAM permitting. The correct size for this + // canvas could also be trial-and-errored, but again let's make this adapt + // automatically. The width of the canvas will span from max_w (plus a few + // pixels for padding) to the right edge. But the height? Looking at an + // uppercase 'M' can work in many situations, but some fonts have ascenders + // and descenders on digits, and in some locales a comma (extending below + // the baseline) is the decimal separator. Feed ALL the numeric chars into + // getTextBounds() for a cumulative height: + display.setTextWrap(false); // Keep on one line + display.getTextBounds(F("0123456789.,-"), 0, 0, &x, &y, &w, &h); + + // Now declare a GFXcanvas16 object based on the computed width & height: + GFXcanvas16 canvas16(display.width() - max_w - PADDING, h); + + // Small devices (e.g. ATmega328p) will almost certainly lack enough RAM + // for the canvas. Check if canvas buffer exists. If not, fall back on + // using a 1-bit (rather than 16-bit) canvas. Much more RAM friendly, but + // not as fast to draw. If a project doesn't require super interactive + // updates, consider just going straight for the more compact Canvas1. + if (canvas16.getBuffer()) { + // If here, 16-bit canvas allocated successfully! Point of interest, + // only one canvas is needed for this example, we can reuse it for all + // three numbers because the regions are the same size. + + // display and canvas are independent drawable objects; must explicitly + // set the same custom font to use on the canvas now: + canvas16.setFont(&FreeSansBold18pt7b); + + // Clear display and print labels. Once drawn, these remain untouched. + display.fillScreen(0); + display.setCursor(max_w, -y + y_offset); // Set baseline for first row + for (uint8_t i=0; i<3; i++) print_aligned(display, label[i], GFX_ALIGN_RIGHT); + + // Last part now is to print numbers on the canvas and copy the canvas to + // the display, repeating for several seconds... + uint32_t elapsed, startTime = millis(); + while ((elapsed = (millis() - startTime)) <= PAUSE * 2) { + for (uint8_t i=0; i<3; i++) { // For each label... + canvas16.fillScreen(0); // fillScreen() in this case clears canvas + canvas16.setCursor(0, -y); // Reset baseline for custom font + canvas16.setTextColor(color[i]); + // These aren't real accelerometer readings, just cool-looking numbers. + // Notice we print to the canvas, NOT the display: + canvas16.print(sin(elapsed / 200.0 + (float)i * M_PI * 2.0 / 3.0), 5); + // And HERE is the secret sauce to flicker-free updates. Canvas details + // can be passed to the drawRGBBitmap() function, which fully overwrites + // prior screen contents in that area. yAdvance is font line spacing. + display.drawRGBBitmap(max_w + PADDING, i * FreeSansBold18pt7b.yAdvance + + y_offset, canvas16.getBuffer(), canvas16.width(), + canvas16.height()); + } + } + } else { + // Insufficient RAM for Canvas16. Try declaring a 1-bit canvas instead... + GFXcanvas1 canvas1(display.width() - max_w - PADDING, h); + // If even this smaller object fails, can't proceed, cancel this example. + if (!canvas1.getBuffer()) return; + + // Remainder here is nearly identical to the code above, simply using a + // different canvas type. It's stripped of most comments for brevity. + canvas1.setFont(&FreeSansBold18pt7b); + display.fillScreen(0); + display.setCursor(max_w, -y + y_offset); + for (uint8_t i=0; i<3; i++) print_aligned(display, label[i], GFX_ALIGN_RIGHT); + uint32_t elapsed, startTime = millis(); + while ((elapsed = (millis() - startTime)) <= PAUSE * 2) { + for (uint8_t i=0; i<3; i++) { + canvas1.fillScreen(0); + canvas1.setCursor(0, -y); + canvas1.print(sin(elapsed / 200.0 + (float)i * M_PI * 2.0 / 3.0), 5); + // Here's the secret sauce to flicker-free updates with GFXcanvas1. + // Canvas details can be passed to the drawBitmap() function, and by + // specifying both a foreground AND BACKGROUND color (0), this will fully + // overwrite/erase prior screen contents in that area (vs transparent). + display.drawBitmap(max_w + PADDING, i * FreeSansBold18pt7b.yAdvance + + y_offset, canvas1.getBuffer(), canvas1.width(), + canvas1.height(), color[i], 0); + } + } + } + + // Because canvas object was declared locally to this function, it's freed + // automatically when the function returns; no explicit delete needed. +} // END CANVAS EXAMPLE diff --git a/Newxie_TFT_Examples/Newxie_CircuitPython/Helvetica-Bold-16.pcf b/Newxie_TFT_Examples/Newxie_CircuitPython/Helvetica-Bold-16.pcf new file mode 100644 index 0000000000000000000000000000000000000000..deb9092d11e0e0c9c4367805319f72ef3a01681d GIT binary patch literal 145784 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 literal 0 HcmV?d00001 diff --git a/Newxie_TFT_Examples/Newxie_CircuitPython/adabot.bmp b/Newxie_TFT_Examples/Newxie_CircuitPython/adabot.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1d24f8dcc0071546e8e7e62dac73394d3b68a1db GIT binary patch literal 32780 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 Date: Mon, 6 Jan 2025 17:28:21 -0500 Subject: [PATCH 02/10] fastled CI for DiscoBandCamp --- GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index d72f53196..b715c8ed2 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT // Selection of effects from the FastLED library & Macetech RGB Shades - +#include "XYmap.h" // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index b41f5b7ed..b5b7206f3 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT // Assorted useful functions and variables - +#include "XYmap.h" // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched uint16_t effectDelay = 0; // time between automatic effect changes From 091bead2f8669fcb1d5cd905bf9cc6f45ff54dd7 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 17:43:36 -0500 Subject: [PATCH 03/10] rework xymap --- .../DiscoBandCamp/DiscoBandCamp.ino | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp | 53 +++++++++++++++++++ GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 21 +++++++- 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index 828d99035..5e6d1381c 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -96,7 +96,7 @@ void loop() } // run a fade effect too if the confetti or myConfetti is running: - if (effectList[currentEffect] == confetti or myConfetti) fadeAll(1); + if (effectList[currentEffect] == confetti || effectList[currentEffect] == myConfetti) fadeAll(1); FastLED.show(); // send the contents of the led memory to the LEDs } diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp new file mode 100644 index 000000000..6c24be58e --- /dev/null +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp @@ -0,0 +1,53 @@ +#include +#include "XYmap.h" + +CRGB leds[ NUM_LEDS ]; + +#define LAST_VISIBLE_LED 119 +uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) +{ + (void)width; + (void)height; + // any out of bounds address maps to the first hidden pixel + if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { + return (LAST_VISIBLE_LED + 1); + } + +// On the visual left of DiscoBandCamp, wearers right +// +------------------------------------------ +// | 10 9 8 7 6 5 4 3 2 1 0 +// | . 20 19 18 17 16 15 14 13 12 11 +// | . . 29 28 27 26 25 24 23 22 21 +// | . . . 37 36 35 34 33 32 31 30 +// | . . . . 44 43 42 41 40 39 38 +// | . . . . . 50 49 48 47 46 45 +// | . . . . . . 55 54 53 52 51 +// | . . . . . . . 59 58 57 56 + +//this is how DiscoBandCamp works + const uint8_t JacketTable[] = { +10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, +153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, +120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, +154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, +121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, +155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, +122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, +156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, +123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, +157,104,103,102,101,100,99, 98, 167,172,178,185, +124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, +158,110,109,108,107,106,105,164,168,173,179,186, +125,131,134,137,140,142,51, 52, 53, 54, 55, 151, +159,115,114,113,112,111,162,165,169,174,180,187, +126,132,134,138,141,143,144,56, 57, 58, 59, 152, +160,119,118,117,116,161,163,166,170,175,181,188, + }; + + uint8_t i = (y * kMatrixWidth) + x; + uint8_t j = JacketTable[i]; + return j; +} + +// Instantiate an XYMap object +XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 1355be492..75fe0360c 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -23,15 +23,34 @@ // XY(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XY(x,y) ] == CRGB::Red; +#ifndef XYMAP_H +#define XYMAP_H + #include +// Parameters for width and height +const uint8_t kMatrixWidth = 24; +const uint8_t kMatrixHeight = 8; +const uint8_t kBorderWidth = 2; + +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) +extern CRGB leds[NUM_LEDS]; + +// XY Function +uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + +// Declare XYMap +extern XYMap myXYMap; + +#endif // XYMAP_H + // Parameters for width and height const uint8_t kMatrixWidth = 24; const uint8_t kMatrixHeight = 8; const uint8_t kBorderWidth = 2; //for swirly #define NUM_LEDS (kMatrixWidth * kMatrixHeight) -CRGB leds[ NUM_LEDS ]; +extern CRGB leds[ NUM_LEDS ]; // This function will return the right 'led index number' for // a given set of X and Y coordinates on DiscoBandCamp From 30e081c593ea5a2482e8b07a3e8546c3d73c5428 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 17:53:49 -0500 Subject: [PATCH 04/10] Revert "rework xymap" This reverts commit 091bead2f8669fcb1d5cd905bf9cc6f45ff54dd7. --- .../DiscoBandCamp/DiscoBandCamp.ino | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp | 53 ------------------- GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 21 +------- 3 files changed, 2 insertions(+), 74 deletions(-) delete mode 100644 GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index 5e6d1381c..828d99035 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -96,7 +96,7 @@ void loop() } // run a fade effect too if the confetti or myConfetti is running: - if (effectList[currentEffect] == confetti || effectList[currentEffect] == myConfetti) fadeAll(1); + if (effectList[currentEffect] == confetti or myConfetti) fadeAll(1); FastLED.show(); // send the contents of the led memory to the LEDs } diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp deleted file mode 100644 index 6c24be58e..000000000 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include "XYmap.h" - -CRGB leds[ NUM_LEDS ]; - -#define LAST_VISIBLE_LED 119 -uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) -{ - (void)width; - (void)height; - // any out of bounds address maps to the first hidden pixel - if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { - return (LAST_VISIBLE_LED + 1); - } - -// On the visual left of DiscoBandCamp, wearers right -// +------------------------------------------ -// | 10 9 8 7 6 5 4 3 2 1 0 -// | . 20 19 18 17 16 15 14 13 12 11 -// | . . 29 28 27 26 25 24 23 22 21 -// | . . . 37 36 35 34 33 32 31 30 -// | . . . . 44 43 42 41 40 39 38 -// | . . . . . 50 49 48 47 46 45 -// | . . . . . . 55 54 53 52 51 -// | . . . . . . . 59 58 57 56 - -//this is how DiscoBandCamp works - const uint8_t JacketTable[] = { -10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, -153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, -154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, -121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, -155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, -122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, -156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, -123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, -157,104,103,102,101,100,99, 98, 167,172,178,185, -124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, -158,110,109,108,107,106,105,164,168,173,179,186, -125,131,134,137,140,142,51, 52, 53, 54, 55, 151, -159,115,114,113,112,111,162,165,169,174,180,187, -126,132,134,138,141,143,144,56, 57, 58, 59, 152, -160,119,118,117,116,161,163,166,170,175,181,188, - }; - - uint8_t i = (y * kMatrixWidth) + x; - uint8_t j = JacketTable[i]; - return j; -} - -// Instantiate an XYMap object -XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 75fe0360c..1355be492 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -23,34 +23,15 @@ // XY(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XY(x,y) ] == CRGB::Red; -#ifndef XYMAP_H -#define XYMAP_H - #include -// Parameters for width and height -const uint8_t kMatrixWidth = 24; -const uint8_t kMatrixHeight = 8; -const uint8_t kBorderWidth = 2; - -#define NUM_LEDS (kMatrixWidth * kMatrixHeight) -extern CRGB leds[NUM_LEDS]; - -// XY Function -uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height); - -// Declare XYMap -extern XYMap myXYMap; - -#endif // XYMAP_H - // Parameters for width and height const uint8_t kMatrixWidth = 24; const uint8_t kMatrixHeight = 8; const uint8_t kBorderWidth = 2; //for swirly #define NUM_LEDS (kMatrixWidth * kMatrixHeight) -extern CRGB leds[ NUM_LEDS ]; +CRGB leds[ NUM_LEDS ]; // This function will return the right 'led index number' for // a given set of X and Y coordinates on DiscoBandCamp From 27427735ee58aa08471de23e615e51bb2f64ca1d Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 18:00:11 -0500 Subject: [PATCH 05/10] CI extern --- GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino | 1 + GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 6 +++++- GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index 828d99035..dc1c44516 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -42,6 +42,7 @@ #include "utils.h" #include "effects.h" #include "buttons.h" +extern XYMap myXYMap; // list of Functions: functionList effectList[] = {SolidRed, //all pixels solid red diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 1355be492..3178e2e98 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -23,6 +23,9 @@ // XY(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XY(x,y) ] == CRGB::Red; +#ifndef XYMAP_H +#define XYMAP_H + #include // Parameters for width and height @@ -31,7 +34,7 @@ const uint8_t kMatrixHeight = 8; const uint8_t kBorderWidth = 2; //for swirly #define NUM_LEDS (kMatrixWidth * kMatrixHeight) -CRGB leds[ NUM_LEDS ]; +extern CRGB leds[ NUM_LEDS ]; // This function will return the right 'led index number' for // a given set of X and Y coordinates on DiscoBandCamp @@ -82,6 +85,7 @@ uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) uint8_t j = JacketTable[i]; return j; } +#endif // Instantiate an XYMap object XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index b715c8ed2..709ac2172 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -4,7 +4,7 @@ // Selection of effects from the FastLED library & Macetech RGB Shades #include "XYmap.h" - +extern XYMap myXYMap; // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index b5b7206f3..378a3d039 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries // // SPDX-License-Identifier: MIT - -// Assorted useful functions and variables #include "XYmap.h" +extern XYMap myXYMap; +// Assorted useful functions and variables // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched uint16_t effectDelay = 0; // time between automatic effect changes From 9b50b43d89b74661a30f9166b9d480264628ea0e Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 18:10:53 -0500 Subject: [PATCH 06/10] move defines to ino --- .../DiscoBandCamp/DiscoBandCamp.ino | 49 +++++++++++++++++++ GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 49 +------------------ GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 2 +- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index dc1c44516..da0b39899 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -44,6 +44,55 @@ #include "buttons.h" extern XYMap myXYMap; +CRGB leds[ NUM_LEDS ]; + +uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) +{ + (void)width; + (void)height; + // any out of bounds address maps to the first hidden pixel + if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { + return (LAST_VISIBLE_LED + 1); + } + +// On the visual left of DiscoBandCamp, wearers right +// +------------------------------------------ +// | 10 9 8 7 6 5 4 3 2 1 0 +// | . 20 19 18 17 16 15 14 13 12 11 +// | . . 29 28 27 26 25 24 23 22 21 +// | . . . 37 36 35 34 33 32 31 30 +// | . . . . 44 43 42 41 40 39 38 +// | . . . . . 50 49 48 47 46 45 +// | . . . . . . 55 54 53 52 51 +// | . . . . . . . 59 58 57 56 + +//this is how DiscoBandCamp works + const uint8_t JacketTable[] = { +10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, +153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, +120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, +154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, +121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, +155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, +122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, +156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, +123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, +157,104,103,102,101,100,99, 98, 167,172,178,185, +124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, +158,110,109,108,107,106,105,164,168,173,179,186, +125,131,134,137,140,142,51, 52, 53, 54, 55, 151, +159,115,114,113,112,111,162,165,169,174,180,187, +126,132,134,138,141,143,144,56, 57, 58, 59, 152, +160,119,118,117,116,161,163,166,170,175,181,188, + }; + + uint8_t i = (y * kMatrixWidth) + x; + uint8_t j = JacketTable[i]; + return j; +} +// Instantiate an XYMap object +XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); + // list of Functions: functionList effectList[] = {SolidRed, //all pixels solid red swirly, //glittery swirly patterns diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 3178e2e98..cf0e38083 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -41,51 +41,6 @@ extern CRGB leds[ NUM_LEDS ]; // This code, plus the supporting 80-byte table is much smaller // and much faster than trying to calculate the pixel ID with code. #define LAST_VISIBLE_LED 119 -uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) -{ - (void)width; - (void)height; - // any out of bounds address maps to the first hidden pixel - if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { - return (LAST_VISIBLE_LED + 1); - } - -// On the visual left of DiscoBandCamp, wearers right -// +------------------------------------------ -// | 10 9 8 7 6 5 4 3 2 1 0 -// | . 20 19 18 17 16 15 14 13 12 11 -// | . . 29 28 27 26 25 24 23 22 21 -// | . . . 37 36 35 34 33 32 31 30 -// | . . . . 44 43 42 41 40 39 38 -// | . . . . . 50 49 48 47 46 45 -// | . . . . . . 55 54 53 52 51 -// | . . . . . . . 59 58 57 56 - -//this is how DiscoBandCamp works - const uint8_t JacketTable[] = { -10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, -153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, -154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, -121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, -155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, -122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, -156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, -123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, -157,104,103,102,101,100,99, 98, 167,172,178,185, -124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, -158,110,109,108,107,106,105,164,168,173,179,186, -125,131,134,137,140,142,51, 52, 53, 54, 55, 151, -159,115,114,113,112,111,162,165,169,174,180,187, -126,132,134,138,141,143,144,56, 57, 58, 59, 152, -160,119,118,117,116,161,163,166,170,175,181,188, - }; - - uint8_t i = (y * kMatrixWidth) + x; - uint8_t j = JacketTable[i]; - return j; -} +uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height); +extern XYMap myXYMap; #endif - -// Instantiate an XYMap object -XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index 709ac2172..b715c8ed2 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -4,7 +4,7 @@ // Selection of effects from the FastLED library & Macetech RGB Shades #include "XYmap.h" -extern XYMap myXYMap; + // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index 378a3d039..c473c8f1c 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT #include "XYmap.h" -extern XYMap myXYMap; + // Assorted useful functions and variables // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched From 86f10f190fbac104760c490e788273ddd4523a23 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 18:26:06 -0500 Subject: [PATCH 07/10] Revert "move defines to ino" This reverts commit 9b50b43d89b74661a30f9166b9d480264628ea0e. --- .../DiscoBandCamp/DiscoBandCamp.ino | 49 ------------------- GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 49 ++++++++++++++++++- GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 2 +- 4 files changed, 49 insertions(+), 53 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index da0b39899..dc1c44516 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -44,55 +44,6 @@ #include "buttons.h" extern XYMap myXYMap; -CRGB leds[ NUM_LEDS ]; - -uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) -{ - (void)width; - (void)height; - // any out of bounds address maps to the first hidden pixel - if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { - return (LAST_VISIBLE_LED + 1); - } - -// On the visual left of DiscoBandCamp, wearers right -// +------------------------------------------ -// | 10 9 8 7 6 5 4 3 2 1 0 -// | . 20 19 18 17 16 15 14 13 12 11 -// | . . 29 28 27 26 25 24 23 22 21 -// | . . . 37 36 35 34 33 32 31 30 -// | . . . . 44 43 42 41 40 39 38 -// | . . . . . 50 49 48 47 46 45 -// | . . . . . . 55 54 53 52 51 -// | . . . . . . . 59 58 57 56 - -//this is how DiscoBandCamp works - const uint8_t JacketTable[] = { -10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, -153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, -154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, -121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, -155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, -122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, -156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, -123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, -157,104,103,102,101,100,99, 98, 167,172,178,185, -124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, -158,110,109,108,107,106,105,164,168,173,179,186, -125,131,134,137,140,142,51, 52, 53, 54, 55, 151, -159,115,114,113,112,111,162,165,169,174,180,187, -126,132,134,138,141,143,144,56, 57, 58, 59, 152, -160,119,118,117,116,161,163,166,170,175,181,188, - }; - - uint8_t i = (y * kMatrixWidth) + x; - uint8_t j = JacketTable[i]; - return j; -} -// Instantiate an XYMap object -XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); - // list of Functions: functionList effectList[] = {SolidRed, //all pixels solid red swirly, //glittery swirly patterns diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index cf0e38083..3178e2e98 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -41,6 +41,51 @@ extern CRGB leds[ NUM_LEDS ]; // This code, plus the supporting 80-byte table is much smaller // and much faster than trying to calculate the pixel ID with code. #define LAST_VISIBLE_LED 119 -uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height); -extern XYMap myXYMap; +uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) +{ + (void)width; + (void)height; + // any out of bounds address maps to the first hidden pixel + if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) { + return (LAST_VISIBLE_LED + 1); + } + +// On the visual left of DiscoBandCamp, wearers right +// +------------------------------------------ +// | 10 9 8 7 6 5 4 3 2 1 0 +// | . 20 19 18 17 16 15 14 13 12 11 +// | . . 29 28 27 26 25 24 23 22 21 +// | . . . 37 36 35 34 33 32 31 30 +// | . . . . 44 43 42 41 40 39 38 +// | . . . . . 50 49 48 47 46 45 +// | . . . . . . 55 54 53 52 51 +// | . . . . . . . 59 58 57 56 + +//this is how DiscoBandCamp works + const uint8_t JacketTable[] = { +10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 145, +153,60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, +120,11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 146, +154,80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 182, +121,127,21, 22, 23, 24, 25, 26, 27, 28, 29, 147, +155,89, 88, 87, 86, 85, 84, 83, 82, 81, 176,183, +122,128,133,30, 31, 32, 33, 34, 35, 36, 37, 148, +156,97, 96, 95, 94, 93, 92, 91, 90, 171,177,184, +123,129,134,135,38, 39, 40, 41, 42, 43, 44, 149, +157,104,103,102,101,100,99, 98, 167,172,178,185, +124,130,134,136,139,45, 46, 47, 48, 49, 50, 150, +158,110,109,108,107,106,105,164,168,173,179,186, +125,131,134,137,140,142,51, 52, 53, 54, 55, 151, +159,115,114,113,112,111,162,165,169,174,180,187, +126,132,134,138,141,143,144,56, 57, 58, 59, 152, +160,119,118,117,116,161,163,166,170,175,181,188, + }; + + uint8_t i = (y * kMatrixWidth) + x; + uint8_t j = JacketTable[i]; + return j; +} #endif + +// Instantiate an XYMap object +XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index b715c8ed2..709ac2172 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -4,7 +4,7 @@ // Selection of effects from the FastLED library & Macetech RGB Shades #include "XYmap.h" - +extern XYMap myXYMap; // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index c473c8f1c..378a3d039 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT #include "XYmap.h" - +extern XYMap myXYMap; // Assorted useful functions and variables // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched From 1b9f08dad789e87b7f2656cef6b9145169414bf5 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 18:26:16 -0500 Subject: [PATCH 08/10] Revert "CI extern" This reverts commit 27427735ee58aa08471de23e615e51bb2f64ca1d. --- GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino | 1 - GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 6 +----- GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 4 ++-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino index dc1c44516..828d99035 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/DiscoBandCamp.ino @@ -42,7 +42,6 @@ #include "utils.h" #include "effects.h" #include "buttons.h" -extern XYMap myXYMap; // list of Functions: functionList effectList[] = {SolidRed, //all pixels solid red diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 3178e2e98..1355be492 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -23,9 +23,6 @@ // XY(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XY(x,y) ] == CRGB::Red; -#ifndef XYMAP_H -#define XYMAP_H - #include // Parameters for width and height @@ -34,7 +31,7 @@ const uint8_t kMatrixHeight = 8; const uint8_t kBorderWidth = 2; //for swirly #define NUM_LEDS (kMatrixWidth * kMatrixHeight) -extern CRGB leds[ NUM_LEDS ]; +CRGB leds[ NUM_LEDS ]; // This function will return the right 'led index number' for // a given set of X and Y coordinates on DiscoBandCamp @@ -85,7 +82,6 @@ uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) uint8_t j = JacketTable[i]; return j; } -#endif // Instantiate an XYMap object XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index 709ac2172..b715c8ed2 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -4,7 +4,7 @@ // Selection of effects from the FastLED library & Macetech RGB Shades #include "XYmap.h" -extern XYMap myXYMap; + // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index 378a3d039..b5b7206f3 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries // // SPDX-License-Identifier: MIT -#include "XYmap.h" -extern XYMap myXYMap; + // Assorted useful functions and variables +#include "XYmap.h" // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched uint16_t effectDelay = 0; // time between automatic effect changes From a26563c8d13bed0f04720392fd0c957e1366a662 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 18:35:49 -0500 Subject: [PATCH 09/10] use xymap from fl namespace --- GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h | 2 +- GemmaM0_Band_Jacket/DiscoBandCamp/effects.h | 1 - GemmaM0_Band_Jacket/DiscoBandCamp/utils.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h index 1355be492..17949194f 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/XYmap.h @@ -84,4 +84,4 @@ uint16_t XY(uint16_t x, uint16_t y, uint16_t width, uint16_t height) } // Instantiate an XYMap object -XYMap myXYMap = XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); +fl::XYMap myXYMap = fl::XYMap::constructWithUserFunction(kMatrixWidth, kMatrixHeight, XY); diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h index b715c8ed2..bef1f729d 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/effects.h @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT // Selection of effects from the FastLED library & Macetech RGB Shades -#include "XYmap.h" // Triple Sine Waves void threeSine() { diff --git a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h index b5b7206f3..7c97afc23 100644 --- a/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h +++ b/GemmaM0_Band_Jacket/DiscoBandCamp/utils.h @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT // Assorted useful functions and variables -#include "XYmap.h" // Global variables boolean effectInit = false; // indicates if a pattern has been recently switched uint16_t effectDelay = 0; // time between automatic effect changes From fbf893bdab5bc4661b81be18316a91cf1f3c5f04 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 6 Jan 2025 20:04:42 -0500 Subject: [PATCH 10/10] adding cpython example --- .../Newxie_Python_Pi/adabot.jpg | Bin 0 -> 13362 bytes Newxie_TFT_Examples/Newxie_Python_Pi/code.py | 70 ++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Newxie_TFT_Examples/Newxie_Python_Pi/adabot.jpg create mode 100644 Newxie_TFT_Examples/Newxie_Python_Pi/code.py diff --git a/Newxie_TFT_Examples/Newxie_Python_Pi/adabot.jpg b/Newxie_TFT_Examples/Newxie_Python_Pi/adabot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8b196dc74e67f400bbfea99c41550a9ae0ded13f GIT binary patch literal 13362 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 literal 0 HcmV?d00001 diff --git a/Newxie_TFT_Examples/Newxie_Python_Pi/code.py b/Newxie_TFT_Examples/Newxie_Python_Pi/code.py new file mode 100644 index 000000000..5f2d29ee0 --- /dev/null +++ b/Newxie_TFT_Examples/Newxie_Python_Pi/code.py @@ -0,0 +1,70 @@ +# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries +# SPDX-FileCopyrightText: Adapted from Melissa LeBlanc-Williams's Pi Demo Code +# +# SPDX-License-Identifier: MIT + +'''Raspberry Pi Graphics example for the Vertical Newxie TFT''' + +import time +import digitalio +import board +from PIL import Image, ImageDraw, ImageFont +from adafruit_rgb_display import st7789 + +BORDER = 20 +FONTSIZE = 24 + +cs_pin = digitalio.DigitalInOut(board.CE0) +dc_pin = digitalio.DigitalInOut(board.D25) +reset_pin = digitalio.DigitalInOut(board.D24) + +BAUDRATE = 24000000 + +spi = board.SPI() + +disp = st7789.ST7789(spi, rotation=180, + width=135, height=240, + x_offset=53, y_offset=40, + cs=cs_pin, + dc=dc_pin, + rst=reset_pin, + baudrate=BAUDRATE, +) + +width = disp.width +height = disp.height + +# -------TEXT AND SHAPES--------- +image1 = Image.new("RGB", (width, height)) +draw1 = ImageDraw.Draw(image1) +draw1.rectangle((0, 0, width, height), fill=(0, 255, 0)) # Green background + +draw1.rectangle( + (BORDER, BORDER, width - BORDER - 1, height - BORDER - 1), fill=(170, 0, 136) +) +font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", FONTSIZE) +text = "Hello\nWorld!" +(font_width, font_height) = font.getsize(text) +draw1.text( + (30, height // 2 - font_height // 2-12), + text, + font=font, + fill=(255, 255, 0), +) + +# ------ADABOT JPEG DISPLAY---------- +image2 = Image.open("adabot.jpg") +image_ratio = image2.width / image2.height +screen_ratio = width / height +scaled_width = width +scaled_height = image2.height * width // image2.width +image2 = image2.resize((scaled_width, scaled_height), Image.BICUBIC) +x = scaled_width // 2 - width // 2 +y = scaled_height // 2 - height // 2 +image2 = image2.crop((x, y, x + width, y + height)) + +while True: + disp.image(image1) # show text + time.sleep(2) + disp.image(image2) # show adabot + time.sleep(2)