Commit 187149a4 authored by Frank Radzio 's avatar Frank Radzio

Neopixel lib add

parent c9baaaa3
......@@ -96,7 +96,7 @@ function Decoder(b, port)
* GPS Definitionen
************************************************************/
static const int RXPin = 9, TXPin = 8; //GPS PIN
static const uint32_t GPSBaud = 9600; //GPS Baud
static const uint32_t GPSBaud = 4800; //GPS Baud
uint8_t coords[10]; //Array für die Koordinaten
/********************************************************
......@@ -135,9 +135,9 @@ static const u1_t NWKSKEY[16] = NWKSKEY1;
static const u1_t APPSKEY[16] = APPSKEY1;
static const u4_t DEVADDR = DEVADDR1;
#else
static const PROGMEM u1_t NWKSKEY[16] = { ...... }; // LoRaWAN NwkSKey, network session key
static const u1_t PROGMEM APPSKEY[16] = { ... }; // LoRaWAN AppSKey, application session key
static const u4_t DEVADDR = 0x26... ; // LoRaWAN end-device address (DevAddr)
static const PROGMEM u1_t NWKSKEY[16] = { 0x63, 0x7B, 0x0D, 0x9E, 0xDF, 0x0F, 0xC2, 0x24, 0x1A, 0x00, 0x8C, 0x8E, 0x4D, 0x8C, 0x4D, 0xDB }; // LoRaWAN NwkSKey, network session key
static const u1_t PROGMEM APPSKEY[16] = { 0xB8, 0x24, 0x48, 0x9D, 0xAD, 0xB5, 0xE1, 0xD5, 0x27, 0xAB, 0x9F, 0x04, 0xCE, 0x16, 0xE6, 0xED }; // LoRaWAN AppSKey, application session key
static const u4_t DEVADDR = 0x260110D2 ; // LoRaWAN end-device address (DevAddr)
#endif
/****************************************************
* OTAA
......
#ifndef _ADAFRUIT_NEOPIXEL_ZERODMA_H_
#define _ADAFRUIT_NEOPIXEL_ZERODMA_H_
#include <Adafruit_NeoPixel.h>
#include <Adafruit_ZeroDMA.h>
#include <SPI.h>
class Adafruit_NeoPixel_ZeroDMA : public Adafruit_NeoPixel {
public:
Adafruit_NeoPixel_ZeroDMA(uint16_t n, uint8_t p=6, neoPixelType t=NEO_GRB);
Adafruit_NeoPixel_ZeroDMA(void);
~Adafruit_NeoPixel_ZeroDMA();
boolean begin(SERCOM *sercom, Sercom *sercomBase, uint8_t dmacID, uint8_t mosi, uint8_t miso, uint8_t sck, SercomSpiTXPad padTX, SercomRXPad padRX, EPioType pinFunc);
boolean begin(void);
void show(),
setBrightness(uint8_t);
uint8_t getBrightness() const;
inline bool canShow(void) { return true; }
protected:
Adafruit_ZeroDMA dma;
SPIClass *spi;
uint8_t *dmaBuf;
uint16_t brightness;
#ifdef __SAMD51__
// Hacky stuff for Trellis M4: PA27 (to NeoPixel matrix) is not on a
// SERCOM, nor a pattern generator pin (which would work with NeoPXL8),
// so we use the PORT toggle register to DMA NeoPixel data out. This is
// not RAM-efficient but we're just looking to control the 32 pixels of
// that matrix, not arbitrary-length strips, so the waste is localized.
uint8_t toggleMask; // Port bit to toggle
#endif
};
#endif // _ADAFRUIT_NEOPIXEL_ZERODMA_H_
The MIT License (MIT)
Copyright (c) 2018 Adafruit Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Adafruit_NeoPixel_ZeroDMA
DMA-based NeoPixel library for M0 microcontrollers (Feather M0, Arduino Zero, etc.) Doesn't require stopping interrupts, so millis() & micros() don't lose time, soft PWM (for servos, etc.) still operate normally, etc.
Requires LATEST Adafruit_NeoPixel and Adafruit_ZeroDMA libraries also be installed.
THIS IS A WORK-IN-PROGRESS AND NOT 100% THERE YET.
THIS ONLY WORKS ON CERTAIN PINS. THIS IS NORMAL. Library uses SERCOM peripherals for SPI output, and the hardware only supports this on specific pins (plus, some SERCOMs are in use for Serial, I2C, etc.).
On Circuit Playground Express: 8, A2 and A7 (TX) are valid.
On Feather M0, Arduino Zero, etc.: 5, 11, A5 and 23 (SPI MOSI).
On GEMMA M0: pin 0.
OTHER THINGS TO KNOW:
DMA NeoPixels use a LOT of RAM: 12 bytes/pixel for RGB, 16 bytes/pixel for RGBW, about 4X as much as regular NeoPixel library (plus a little bit extra for structures & stuff).
0/1 bit timing does not precisely match NeoPixel/WS2812/SK6812 datasheet specs, but it seems to work well enough. Use at your own peril.
Have not tested this yet with multiple instances (DMA-driven NeoPixels on multiple pins), but in theory it should work. Should also be OK mixing DMA and non-DMA NeoPixels in same sketch (just use different constructor and pins for each).
Currently this only supports strip declaration with length & pin known at compile time, so it's not a 100% drop-in replacement for all NeoPixel code right now. But probably 99%+ of all sketches are written that way, so it's perfectly usable for most. The stock NeoPixel library has the option of setting the length & pin number at run-time (so these can be stored in a config file or in EEPROM)...this is entirely possible here, just hasn't been written yet.
#ifndef _BITTABLE_H_
#define _BITTABLE_H_
const uint32_t bitExpand[256] = {
0b100100100100100100100100,
0b100100100100100100100110,
0b100100100100100100110100,
0b100100100100100100110110,
0b100100100100100110100100,
0b100100100100100110100110,
0b100100100100100110110100,
0b100100100100100110110110,
0b100100100100110100100100,
0b100100100100110100100110,
0b100100100100110100110100,
0b100100100100110100110110,
0b100100100100110110100100,
0b100100100100110110100110,
0b100100100100110110110100,
0b100100100100110110110110,
0b100100100110100100100100,
0b100100100110100100100110,
0b100100100110100100110100,
0b100100100110100100110110,
0b100100100110100110100100,
0b100100100110100110100110,
0b100100100110100110110100,
0b100100100110100110110110,
0b100100100110110100100100,
0b100100100110110100100110,
0b100100100110110100110100,
0b100100100110110100110110,
0b100100100110110110100100,
0b100100100110110110100110,
0b100100100110110110110100,
0b100100100110110110110110,
0b100100110100100100100100,
0b100100110100100100100110,
0b100100110100100100110100,
0b100100110100100100110110,
0b100100110100100110100100,
0b100100110100100110100110,
0b100100110100100110110100,
0b100100110100100110110110,
0b100100110100110100100100,
0b100100110100110100100110,
0b100100110100110100110100,
0b100100110100110100110110,
0b100100110100110110100100,
0b100100110100110110100110,
0b100100110100110110110100,
0b100100110100110110110110,
0b100100110110100100100100,
0b100100110110100100100110,
0b100100110110100100110100,
0b100100110110100100110110,
0b100100110110100110100100,
0b100100110110100110100110,
0b100100110110100110110100,
0b100100110110100110110110,
0b100100110110110100100100,
0b100100110110110100100110,
0b100100110110110100110100,
0b100100110110110100110110,
0b100100110110110110100100,
0b100100110110110110100110,
0b100100110110110110110100,
0b100100110110110110110110,
0b100110100100100100100100,
0b100110100100100100100110,
0b100110100100100100110100,
0b100110100100100100110110,
0b100110100100100110100100,
0b100110100100100110100110,
0b100110100100100110110100,
0b100110100100100110110110,
0b100110100100110100100100,
0b100110100100110100100110,
0b100110100100110100110100,
0b100110100100110100110110,
0b100110100100110110100100,
0b100110100100110110100110,
0b100110100100110110110100,
0b100110100100110110110110,
0b100110100110100100100100,
0b100110100110100100100110,
0b100110100110100100110100,
0b100110100110100100110110,
0b100110100110100110100100,
0b100110100110100110100110,
0b100110100110100110110100,
0b100110100110100110110110,
0b100110100110110100100100,
0b100110100110110100100110,
0b100110100110110100110100,
0b100110100110110100110110,
0b100110100110110110100100,
0b100110100110110110100110,
0b100110100110110110110100,
0b100110100110110110110110,
0b100110110100100100100100,
0b100110110100100100100110,
0b100110110100100100110100,
0b100110110100100100110110,
0b100110110100100110100100,
0b100110110100100110100110,
0b100110110100100110110100,
0b100110110100100110110110,
0b100110110100110100100100,
0b100110110100110100100110,
0b100110110100110100110100,
0b100110110100110100110110,
0b100110110100110110100100,
0b100110110100110110100110,
0b100110110100110110110100,
0b100110110100110110110110,
0b100110110110100100100100,
0b100110110110100100100110,
0b100110110110100100110100,
0b100110110110100100110110,
0b100110110110100110100100,
0b100110110110100110100110,
0b100110110110100110110100,
0b100110110110100110110110,
0b100110110110110100100100,
0b100110110110110100100110,
0b100110110110110100110100,
0b100110110110110100110110,
0b100110110110110110100100,
0b100110110110110110100110,
0b100110110110110110110100,
0b100110110110110110110110,
0b110100100100100100100100,
0b110100100100100100100110,
0b110100100100100100110100,
0b110100100100100100110110,
0b110100100100100110100100,
0b110100100100100110100110,
0b110100100100100110110100,
0b110100100100100110110110,
0b110100100100110100100100,
0b110100100100110100100110,
0b110100100100110100110100,
0b110100100100110100110110,
0b110100100100110110100100,
0b110100100100110110100110,
0b110100100100110110110100,
0b110100100100110110110110,
0b110100100110100100100100,
0b110100100110100100100110,
0b110100100110100100110100,
0b110100100110100100110110,
0b110100100110100110100100,
0b110100100110100110100110,
0b110100100110100110110100,
0b110100100110100110110110,
0b110100100110110100100100,
0b110100100110110100100110,
0b110100100110110100110100,
0b110100100110110100110110,
0b110100100110110110100100,
0b110100100110110110100110,
0b110100100110110110110100,
0b110100100110110110110110,
0b110100110100100100100100,
0b110100110100100100100110,
0b110100110100100100110100,
0b110100110100100100110110,
0b110100110100100110100100,
0b110100110100100110100110,
0b110100110100100110110100,
0b110100110100100110110110,
0b110100110100110100100100,
0b110100110100110100100110,
0b110100110100110100110100,
0b110100110100110100110110,
0b110100110100110110100100,
0b110100110100110110100110,
0b110100110100110110110100,
0b110100110100110110110110,
0b110100110110100100100100,
0b110100110110100100100110,
0b110100110110100100110100,
0b110100110110100100110110,
0b110100110110100110100100,
0b110100110110100110100110,
0b110100110110100110110100,
0b110100110110100110110110,
0b110100110110110100100100,
0b110100110110110100100110,
0b110100110110110100110100,
0b110100110110110100110110,
0b110100110110110110100100,
0b110100110110110110100110,
0b110100110110110110110100,
0b110100110110110110110110,
0b110110100100100100100100,
0b110110100100100100100110,
0b110110100100100100110100,
0b110110100100100100110110,
0b110110100100100110100100,
0b110110100100100110100110,
0b110110100100100110110100,
0b110110100100100110110110,
0b110110100100110100100100,
0b110110100100110100100110,
0b110110100100110100110100,
0b110110100100110100110110,
0b110110100100110110100100,
0b110110100100110110100110,
0b110110100100110110110100,
0b110110100100110110110110,
0b110110100110100100100100,
0b110110100110100100100110,
0b110110100110100100110100,
0b110110100110100100110110,
0b110110100110100110100100,
0b110110100110100110100110,
0b110110100110100110110100,
0b110110100110100110110110,
0b110110100110110100100100,
0b110110100110110100100110,
0b110110100110110100110100,
0b110110100110110100110110,
0b110110100110110110100100,
0b110110100110110110100110,
0b110110100110110110110100,
0b110110100110110110110110,
0b110110110100100100100100,
0b110110110100100100100110,
0b110110110100100100110100,
0b110110110100100100110110,
0b110110110100100110100100,
0b110110110100100110100110,
0b110110110100100110110100,
0b110110110100100110110110,
0b110110110100110100100100,
0b110110110100110100100110,
0b110110110100110100110100,
0b110110110100110100110110,
0b110110110100110110100100,
0b110110110100110110100110,
0b110110110100110110110100,
0b110110110100110110110110,
0b110110110110100100100100,
0b110110110110100100100110,
0b110110110110100100110100,
0b110110110110100100110110,
0b110110110110100110100100,
0b110110110110100110100110,
0b110110110110100110110100,
0b110110110110100110110110,
0b110110110110110100100100,
0b110110110110110100100110,
0b110110110110110100110100,
0b110110110110110100110110,
0b110110110110110110100100,
0b110110110110110110100110,
0b110110110110110110110100,
0b110110110110110110110110
};
#endif // _BITTABLE_H_
// This is a PARED-DOWN NeoPixel example for the Adafruit_NeoPixel_ZeroDMA
// library, demonstrating pin declarations, etc. For more complete examples
// of NeoPixel operations, see the examples included with the 'regular'
// Adafruit_NeoPixel library.
// Also requires LATEST Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.
#include <Adafruit_NeoPixel_ZeroDMA.h>
// DMA NeoPixels work ONLY on SPECIFIC PINS.
// On Circuit Playground Express: 8, A2 and A7 (TX) are valid.
// On Feather M0, Arduino Zero, etc.: 5, 11, A5 and 23 (SPI MOSI).
// On GEMMA M0: pin 0.
// On Trinket M0: pin 4.
// On Metro M4: 3, 6, 8, 11, A3 and MOSI
#define PIN 8
#define NUM_PIXELS 10
Adafruit_NeoPixel_ZeroDMA strip(NUM_PIXELS, PIN, NEO_GRB);
void setup() {
strip.begin();
strip.setBrightness(32);
strip.show();
}
void loop() {
uint16_t i;
// 'Color wipe' across all pixels
for(uint32_t c = 0xFF0000; c; c >>= 8) { // Red, green, blue
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(50);
}
}
// Rainbow cycle
uint32_t elapsed, t, startTime = micros();
for(;;) {
t = micros();
elapsed = t - startTime;
if(elapsed > 5000000) break; // Run for 5 seconds
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((uint8_t)(
(elapsed * 256 / 1000000) + i * 256 / strip.numPixels())));
}
strip.show();
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
#######################################
# Syntax Coloring Map For Adafruit_NeoPixel_ZeroDMA
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
Adafruit_NeoPixel_ZeroDMA KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
show KEYWORD2
setBrightness KEYWORD2
getBrightness KEYWORD2
canShow KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################
name=Adafruit DMA neopixel library
version=1.0.8
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Arduino library for neopixel DMA on samd21 microcontroller
paragraph=Arduino library for neopixel DMA on samd21 microcontroller
category=Display
url=https://github.com/adafruit/Adafruit_NeoPixel_ZeroDMA
architectures=samd
This diff is collapsed.
#ifndef _ADAFRUIT_NEOPXL8_H_
#define _ADAFRUIT_NEOPXL8_H_
#include <Adafruit_NeoPixel.h>
#include <Adafruit_ZeroDMA.h>
class Adafruit_NeoPXL8 : public Adafruit_NeoPixel {
public:
Adafruit_NeoPXL8(uint16_t n, int8_t *p=NULL, neoPixelType t=NEO_GRB);
~Adafruit_NeoPXL8();
boolean begin(void),
canStage(void),
canShow(void);
void show(),
stage(),
setBrightness(uint8_t);
uint8_t getBrightness() const;
protected:
Adafruit_ZeroDMA dma;
int8_t pins[8]; // Pin list for 8 NeoPixel strips
uint8_t bitmask[8], // Pattern generator bitmask for each pin
*dmaBuf; // Allocated buffer for pixel data + extra
uint32_t *alignedAddr; // long-aligned ptr into dmaBuf (see code)
uint16_t brightness;
boolean staged; // If set, data is ready for DMA trigger
};
#endif // _ADAFRUIT_NEOPXL8_H_
# Adafruit_NeoPXL8
DMA-driven 8-way concurrent NeoPixel driver for SAMD21 (M0+) boards.
Requires latest Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.
(Pronounced "NeoPixelate")
Constructor is slightly different from Adafruit_NeoPixel. Rather than a pin number, this accepts an array of 8 signed bytes corresponding to pins for data outputs 0-7 (very specific rules apply here, more on this in a moment). Can also pass NULL to use the default pin assignments (digital pins 0-7 on Adafruit Metro Express or Arduino Zero):
`Adafruit_NeoPXL8 strip(NUM_LED, NULL, NEO_GRB);`
The first argument, strand length, applies to EACH strand. Total NeoPixel count is 8X this. Pixels are addressed (via setPixelColor()) as a single sequential strand. Supposing NUM_LED is 20, the first physical strand would be pixels 0-19, second strand is 20-39, third is 40-59 and so forth, up to pixel #159 on the eighth strand.
## Logic Levels
The SAMD21 is a 3.3V device, while NeoPixels ideally want 5V logic. One solution is a logic level converter such as the 74HCT125N. Alternately, just powering the NeoPixels from a slightly lower voltage (e.g. 4.5V) is sometimes all it takes!
## Pin MUXing
Because this library relies on the SAMD21's TCC0 "pattern generator" peripheral, outputs can only be assigned to very specific pins. Fortunately most provide alternate options if the default layout doesn't meet your needs (e.g. on Feather boards).
Pin 0 alternate is 12
Pin 1 alternate is 10
Pin 2 alternates are MOSI or SDA
Pin 3 alternate is A4
Pin 4 alternate is A3
Pin 5 alternates are SCK or SCL
Pin 6 alternates are 11 or MISO
Pin 7 alternate is 13
On the Metro Express and Arduino Zero boards, some of these pins (MOSI, MISO and SCK) are on the 6-pin ICSP header.
Because Feather boards have a pared-down pinout, some of the alternates need to be used. One possible layout might be:
`int8_t pins[] = { 13, 12, 11, 10, 5, SDA, A3, A4 };`
This keeps the Serial1 and SPI peripherals available, but prevents using I2C. A different arrangement would keep I2C free at the expense of one NeoPixel output:
`int8_t pins[] = { 13, 12, 11, 10, 5, -1, A3, A4 };`
The '-1' for a pin assignment disables that NeoPixel output (so this would have only 7 concurrent strands), but those pixels still take up memory and positions among the pixel indices.
Pin MUXing is a hairy thing and over time we'll try to build up some ready-to-use examples for different boards and peripherals. You can also try picking your way through the SAMD21 datasheet or the NeoPXL8 source code for pin/peripheral assignments.
// Example/diagnostic for the Adafruit_NeoPXL8 library. Each of 8 strands
// is a distinct color, helps identify which pin goes to which strand.
// For more complete usage of NeoPixel operations, see the examples
// included with the 'regular' Adafruit_NeoPixel library.
// Also requires LATEST Adafruit_NeoPixel, Adafruit_ZeroDMA and
// Adafruit_ASFcore libraries.
// May require a logic level shifter (e.g. 75HCT245) for 5V pixels,
// or use NeoPXL8 Featherwing for Adafruit Feather M0 boards.
#include <Adafruit_NeoPXL8.h>
#define NUM_LED 64 // Per strand. Total number of pixels is 8X this!
// Second argument to constructor is an optional 8-byte pin list,
// or pass NULL to use pins 0-7 on Metro Express, Arduino Zero, etc.
Adafruit_NeoPXL8 leds(NUM_LED, NULL, NEO_GRB);
// Here's a pinout that works with the Feather M0. These are the
// default connections for the 2x8 header on the NeoPXL8 Featherwing,
// which is 1:1 compatible with Fadecandy cabling:
//int8_t pins[8] = { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 };
//Adafruit_NeoPXL8 leds(NUM_LED, pins, NEO_GRB);
// If using the Featherwing RJ45 connections, the pin order can be
// reversed if 1:1 compatibility with OctoWS2811 cabling is desired:
// int8_t pins[8] = { A3, A4, SDA, 5, 13, MISO, PIN_SERIAL1_TX, PIN_SERIAL1_RX };
// 5 pins on the Featherwing have reconfigurable jumpers, in case the
// default pin connections interfere with a needed peripheral (Serial1,
// I2C or SPI). You do NOT need to use all 5 alternates; you can pick
// and choose as needed! But if changing all 5, they would be:
//int8_t pins[8] = { 12, 10, 11, 13, SCK, MOSI, A4, A3 };
// And again, reverse the order for OctoWS2811-compatible cabling:
// int8_t pins[8] = { A3, A4, MOSI, SCK, 13, 11, 10, 12 };
// Here's a pinout that works on the Metro M4:
//int8_t pins[8] = { 7, 4, 5, 6, 3, 2, 10, 11 };
// Alternate pins on Metro M4:
//int8_t pins[8] = { 9, 8, 0, 1, 13, 12, -1, SCK };
// MOSI *should* work for bit 6, but does not. Datasheet error?
void setup() {
leds.begin();
leds.setBrightness(32);
}
uint8_t frame = 0;
void loop() {
for(uint8_t r=0; r<8; r++) { // For each row...
for(int p=0; p<NUM_LED; p++) { // For each pixel of row...
leds.setPixelColor(r * NUM_LED + p, rain(r, p));
}
}
leds.show();
frame++;
}
uint8_t colors[8][3] = { // RGB colors for the 8 rows...
255, 0, 0, // Row 0: Red
255, 160, 0, // Row 1: Orange
255, 255, 0, // Row 2: Yellow
0, 255, 0, // Row 3: Green
0, 255, 255, // Row 4: Cyan
0, 0, 255, // Row 5: Blue
192, 0, 255, // Row 6: Purple
255, 0, 255 // Row 7: Magenta
};
// Gamma-correction table improves the appearance of midrange colors
#define _GAMMA_ 2.6
const int _GBASE_ = __COUNTER__ + 1; // Index of 1st __COUNTER__ ref below
#define _G1_ (uint8_t)(pow((__COUNTER__ - _GBASE_) / 255.0, _GAMMA_) * 255.0 + 0.5),
#define _G2_ _G1_ _G1_ _G1_ _G1_ _G1_ _G1_ _G1_ _G1_ // Expands to 8 lines
#define _G3_ _G2_ _G2_ _G2_ _G2_ _G2_ _G2_ _G2_ _G2_ // Expands to 64 lines
const uint8_t gamma8[] = { _G3_ _G3_ _G3_ _G3_ }; // 256 lines
// Given row number (0-7) and pixel number along row (0 - (NUM_LED-1)),
// first calculate brightness (b) of pixel, then multiply row color by
// this and run it through gamma-correction table.
uint32_t rain(uint8_t row, int pixelNum) {
uint16_t b = 256 - ((frame - row * 32 + pixelNum * 256 / NUM_LED) & 0xFF);
return ((uint32_t)gamma8[(colors[row][0] * b) >> 8] << 16) |
((uint32_t)gamma8[(colors[row][1] * b) >> 8] << 8) |
gamma8[(colors[row][2] * b) >> 8];
}