From fc4c478c300ff84524b3dfc49cb374693ef192d3 Mon Sep 17 00:00:00 2001 From: starcalc Date: Fri, 7 Dec 2018 00:38:58 +0100 Subject: [PATCH] =?UTF-8?q?Angepasstes=20Adafruit=5FNeomatrix,=20mit=20zus?= =?UTF-8?q?=C3=A4tzlichem=20Scrolltext=20als=20Effekt=20analog=20zu=20NeoP?= =?UTF-8?q?atterns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Adafruit_NeoMatrix.cpp | 262 +++++++++++++++++++++++++++++++++++++++++ Adafruit_NeoMatrix.h | 115 ++++++++++++++++++ gamma.h | 30 +++++ 3 files changed, 407 insertions(+) create mode 100644 Adafruit_NeoMatrix.cpp create mode 100644 Adafruit_NeoMatrix.h create mode 100644 gamma.h diff --git a/Adafruit_NeoMatrix.cpp b/Adafruit_NeoMatrix.cpp new file mode 100644 index 0000000..82860a2 --- /dev/null +++ b/Adafruit_NeoMatrix.cpp @@ -0,0 +1,262 @@ +/*------------------------------------------------------------------------- + Arduino library to control single and tiled matrices of WS2811- and + WS2812-based RGB LED devices such as the Adafruit NeoPixel Shield or + displays assembled from NeoPixel strips, making them compatible with + the Adafruit_GFX graphics library. Requires both the Adafruit_NeoPixel + and Adafruit_GFX libraries. + + Written by Phil Burgess / Paint Your Dragon for Adafruit Industries. + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing products + from Adafruit! + + ------------------------------------------------------------------------- + This file is part of the Adafruit NeoMatrix library. + + NeoMatrix is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + NeoMatrix is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with NeoMatrix. If not, see + . + -------------------------------------------------------------------------*/ + +#include +#include "Adafruit_NeoMatrix.h" +#include "gamma.h" +#ifdef __AVR__ +#include +#elif defined(ESP8266) +#include +#else +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#endif +#endif + +#ifndef _swap_uint16_t +#define _swap_uint16_t(a, b) { uint16_t t = a; a = b; b = t; } +#endif + +// Constructor for single matrix: +Adafruit_NeoMatrix::Adafruit_NeoMatrix(int w, int h, uint8_t pin, + uint8_t matrixType, neoPixelType ledType) : Adafruit_GFX(w, h), + Adafruit_NeoPixel(w * h, pin, ledType), type(matrixType), matrixWidth(w), + matrixHeight(h), tilesX(0), tilesY(0), remapFn(NULL) { } + +// Constructor for tiled matrices: +Adafruit_NeoMatrix::Adafruit_NeoMatrix(uint8_t mW, uint8_t mH, uint8_t tX, + uint8_t tY, uint8_t pin, uint8_t matrixType, neoPixelType ledType) : + Adafruit_GFX(mW * tX, mH * tY), Adafruit_NeoPixel(mW * mH * tX * tY, pin, + ledType), type(matrixType), matrixWidth(mW), matrixHeight(mH), tilesX(tX), + tilesY(tY), remapFn(NULL) { } + +// Expand 16-bit input color (Adafruit_GFX colorspace) to 24-bit (NeoPixel) +// (w/gamma adjustment) +static uint32_t expandColor(uint16_t color) { + return ((uint32_t)pgm_read_byte(&gamma5[ color >> 11 ]) << 16) | + ((uint32_t)pgm_read_byte(&gamma6[(color >> 5) & 0x3F]) << 8) | + pgm_read_byte(&gamma5[ color & 0x1F]); +} + +// Downgrade 24-bit color to 16-bit (add reverse gamma lookup here?) +uint16_t Adafruit_NeoMatrix::Color(uint8_t r, uint8_t g, uint8_t b) { + return ((uint16_t)(r & 0xF8) << 8) | + ((uint16_t)(g & 0xFC) << 3) | + (b >> 3); +} + +// Pass-through is a kludge that lets you override the current drawing +// color with a 'raw' RGB (or RGBW) value that's issued directly to +// pixel(s), side-stepping the 16-bit color limitation of Adafruit_GFX. +// This is not without some limitations of its own -- for example, it +// won't work in conjunction with the background color feature when +// drawing text or bitmaps (you'll just get a solid rect of color), +// only 'transparent' text/bitmaps. Also, no gamma correction. +// Remember to UNSET the passthrough color immediately when done with +// it (call with no value)! + +// Pass raw color value to set/enable passthrough +void Adafruit_NeoMatrix::setPassThruColor(uint32_t c) { + passThruColor = c; + passThruFlag = true; +} + +// Call without a value to reset (disable passthrough) +void Adafruit_NeoMatrix::setPassThruColor(void) { + passThruFlag = false; +} + +void Adafruit_NeoMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) { + + if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; + + int16_t t; + switch (rotation) { + case 1: + t = x; + x = WIDTH - 1 - y; + y = t; + break; + case 2: + x = WIDTH - 1 - x; + y = HEIGHT - 1 - y; + break; + case 3: + t = x; + x = y; + y = HEIGHT - 1 - t; + break; + } + + int tileOffset = 0, pixelOffset; + + if (remapFn) { // Custom X/Y remapping function + pixelOffset = (*remapFn)(x, y); + } else { // Standard single matrix or tiled matrices + + uint8_t corner = type & NEO_MATRIX_CORNER; + uint16_t minor, major, majorScale; + + if (tilesX) { // Tiled display, multiple matrices + uint16_t tile; + + minor = x / matrixWidth; // Tile # X/Y; presume row major to + major = y / matrixHeight, // start (will swap later if needed) + x = x - (minor * matrixWidth); // Pixel X/Y within tile + y = y - (major * matrixHeight); // (-* is less math than modulo) + + // Determine corner of entry, flip axes if needed + if (type & NEO_TILE_RIGHT) minor = tilesX - 1 - minor; + if (type & NEO_TILE_BOTTOM) major = tilesY - 1 - major; + + // Determine actual major axis of tiling + if ((type & NEO_TILE_AXIS) == NEO_TILE_ROWS) { + majorScale = tilesX; + } else { + _swap_uint16_t(major, minor); + majorScale = tilesY; + } + + // Determine tile number + if ((type & NEO_TILE_SEQUENCE) == NEO_TILE_PROGRESSIVE) { + // All tiles in same order + tile = major * majorScale + minor; + } else { + // Zigzag; alternate rows change direction. On these rows, + // this also flips the starting corner of the matrix for the + // pixel math later. + if (major & 1) { + corner ^= NEO_MATRIX_CORNER; + tile = (major + 1) * majorScale - 1 - minor; + } else { + tile = major * majorScale + minor; + } + } + + // Index of first pixel in tile + tileOffset = tile * matrixWidth * matrixHeight; + + } // else no tiling (handle as single tile) + + // Find pixel number within tile + minor = x; // Presume row major to start (will swap later if needed) + major = y; + + // Determine corner of entry, flip axes if needed + if (corner & NEO_MATRIX_RIGHT) minor = matrixWidth - 1 - minor; + if (corner & NEO_MATRIX_BOTTOM) major = matrixHeight - 1 - major; + + // Determine actual major axis of matrix + if ((type & NEO_MATRIX_AXIS) == NEO_MATRIX_ROWS) { + majorScale = matrixWidth; + } else { + _swap_uint16_t(major, minor); + majorScale = matrixHeight; + } + + // Determine pixel number within tile/matrix + if ((type & NEO_MATRIX_SEQUENCE) == NEO_MATRIX_PROGRESSIVE) { + // All lines in same order + pixelOffset = major * majorScale + minor; + } else { + // Zigzag; alternate rows change direction. + if (major & 1) pixelOffset = (major + 1) * majorScale - 1 - minor; + else pixelOffset = major * majorScale + minor; + } + } + + setPixelColor(tileOffset + pixelOffset, + passThruFlag ? passThruColor : expandColor(color)); +} + +void Adafruit_NeoMatrix::fillScreen(uint16_t color) { + uint16_t i, n; + uint32_t c; + + c = passThruFlag ? passThruColor : expandColor(color); + n = numPixels(); + for (i = 0; i < n; i++) setPixelColor(i, c); +} + +void Adafruit_NeoMatrix::setRemapFunction(uint16_t (*fn)(uint16_t, uint16_t)) { + remapFn = fn; +} + +void Adafruit_NeoMatrix::Update() { + if (active) + { + if ((millis() - lastUpdate) > Interval) // time to update + { + lastUpdate = millis(); + // Next Interval step for text scroll + Serial.print(scrolltextpos); + Serial.print(" - "); + Serial.println((8 * scrolltext.length() + 10)); + scrolltextpos--; + int16_t maxpos = 8 * scrolltext.length() + 10; + if (scrolltextpos < -(maxpos)) { + Serial.println(); + Serial.print(scrolltextpos); + Serial.print(" is smaller than: "); + Serial.println(-(maxpos)); + scrolltextpos = width(); + } + fillScreen(0); + setCursor(scrolltextpos, 0); + print(scrolltext); + show(); + + } else { + delay(1); + } + } +} + +void Adafruit_NeoMatrix::ScrollText(String text, uint16_t interval, String color) { + Serial.print("Scrolltext triggered: "); + Serial.println(text); + active = true; + Interval = interval; + scrolltext = text; + scrolltextpos = width(); + fillScreen(0); + setCursor(scrolltextpos, 0); + print(scrolltext); + if (--scrolltextpos < -(5 * scrolltext.length() + 10)) { + scrolltextpos = width(); + } + show(); +} + +void Adafruit_NeoMatrix::None() { + active = false; +} diff --git a/Adafruit_NeoMatrix.h b/Adafruit_NeoMatrix.h new file mode 100644 index 0000000..e3778a6 --- /dev/null +++ b/Adafruit_NeoMatrix.h @@ -0,0 +1,115 @@ +/*-------------------------------------------------------------------- + This file is part of the Adafruit NeoMatrix library. + + NeoMatrix is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + NeoMatrix is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with NeoMatrix. If not, see + . + --------------------------------------------------------------------*/ + +#ifndef _ADAFRUIT_NEOMATRIX_H_ +#define _ADAFRUIT_NEOMATRIX_H_ + +#if ARDUINO >= 100 + #include +#else + #include + #include +#endif +#include +#include + +// Matrix layout information is passed in the 'matrixType' parameter for +// each constructor (the parameter immediately following is the LED type +// from NeoPixel.h). + +// These define the layout for a single 'unified' matrix (e.g. one made +// from NeoPixel strips, or a single NeoPixel shield), or for the pixels +// within each matrix of a tiled display (e.g. multiple NeoPixel shields). + +#define NEO_MATRIX_TOP 0x00 // Pixel 0 is at top of matrix +#define NEO_MATRIX_BOTTOM 0x01 // Pixel 0 is at bottom of matrix +#define NEO_MATRIX_LEFT 0x00 // Pixel 0 is at left of matrix +#define NEO_MATRIX_RIGHT 0x02 // Pixel 0 is at right of matrix +#define NEO_MATRIX_CORNER 0x03 // Bitmask for pixel 0 matrix corner +#define NEO_MATRIX_ROWS 0x00 // Matrix is row major (horizontal) +#define NEO_MATRIX_COLUMNS 0x04 // Matrix is column major (vertical) +#define NEO_MATRIX_AXIS 0x04 // Bitmask for row/column layout +#define NEO_MATRIX_PROGRESSIVE 0x00 // Same pixel order across each line +#define NEO_MATRIX_ZIGZAG 0x08 // Pixel order reverses between lines +#define NEO_MATRIX_SEQUENCE 0x08 // Bitmask for pixel line order + +// These apply only to tiled displays (multiple matrices): + +#define NEO_TILE_TOP 0x00 // First tile is at top of matrix +#define NEO_TILE_BOTTOM 0x10 // First tile is at bottom of matrix +#define NEO_TILE_LEFT 0x00 // First tile is at left of matrix +#define NEO_TILE_RIGHT 0x20 // First tile is at right of matrix +#define NEO_TILE_CORNER 0x30 // Bitmask for first tile corner +#define NEO_TILE_ROWS 0x00 // Tiles ordered in rows +#define NEO_TILE_COLUMNS 0x40 // Tiles ordered in columns +#define NEO_TILE_AXIS 0x40 // Bitmask for tile H/V orientation +#define NEO_TILE_PROGRESSIVE 0x00 // Same tile order across each line +#define NEO_TILE_ZIGZAG 0x80 // Tile order reverses between lines +#define NEO_TILE_SEQUENCE 0x80 // Bitmask for tile line order + +class Adafruit_NeoMatrix : public Adafruit_GFX, public Adafruit_NeoPixel { + + public: + + // Constructor for single matrix: + Adafruit_NeoMatrix(int w, int h, uint8_t pin = 6, + uint8_t matrixType = NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS, + neoPixelType ledType = NEO_GRB + NEO_KHZ800); + + // Constructor for tiled matrices: + Adafruit_NeoMatrix(uint8_t matrixW, uint8_t matrixH, uint8_t tX, + uint8_t tY, uint8_t pin = 6, + uint8_t matrixType = NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + + NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS, + neoPixelType ledType = NEO_GRB + NEO_KHZ800); + + void + drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color), + setPassThruColor(uint32_t c), + setPassThruColor(void), + setRemapFunction(uint16_t (*fn)(uint16_t, uint16_t)), + Update(), + None(), + ScrollText(String text, uint16_t Interval = 60, String color); + + static uint16_t + Color(uint8_t r, uint8_t g, uint8_t b); + + boolean active = false; + + private: + + const uint8_t + type; + const uint8_t + matrixWidth, matrixHeight, tilesX, tilesY; + uint16_t + (*remapFn)(uint16_t x, uint16_t y); + + uint32_t passThruColor; + boolean passThruFlag = false; + String scrolltext; + int16_t scrolltextpos; + + uint16_t Interval; // milliseconds between updates + uint16_t lastUpdate; // last update of position + +}; + +#endif // _ADAFRUIT_NEOMATRIX_H_ diff --git a/gamma.h b/gamma.h new file mode 100644 index 0000000..0605c4e --- /dev/null +++ b/gamma.h @@ -0,0 +1,30 @@ +#ifndef _GAMMA_H_ +#define _GAMMA_H_ + +#ifdef __AVR + #include +#elif defined(ESP8266) + #include +#else + #ifndef PROGMEM + #define PROGMEM + #endif +#endif + +static const uint8_t PROGMEM + gamma5[] = { + 0x00,0x01,0x02,0x03,0x05,0x07,0x09,0x0b, + 0x0e,0x11,0x14,0x18,0x1d,0x22,0x28,0x2e, + 0x36,0x3d,0x46,0x4f,0x59,0x64,0x6f,0x7c, + 0x89,0x97,0xa6,0xb6,0xc7,0xd9,0xeb,0xff }, + gamma6[] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x08, + 0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x12,0x13, + 0x15,0x17,0x19,0x1b,0x1d,0x20,0x22,0x25, + 0x27,0x2a,0x2d,0x30,0x33,0x37,0x3a,0x3e, + 0x41,0x45,0x49,0x4d,0x52,0x56,0x5b,0x5f, + 0x64,0x69,0x6e,0x74,0x79,0x7f,0x85,0x8b, + 0x91,0x97,0x9d,0xa4,0xab,0xb2,0xb9,0xc0, + 0xc7,0xcf,0xd6,0xde,0xe6,0xee,0xf7,0xff }; + +#endif // _GAMMA_H_