first working sk6812 RGB output with color copy

This commit is contained in:
interfisch 2020-12-01 22:51:24 +01:00
parent fece9c9b61
commit 151f9e8c43
3 changed files with 204 additions and 81 deletions

17
platformio.ini Normal file
View File

@ -0,0 +1,17 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
lib_deps =
fastled/FastLED

65
src/FastLED_RGBW.h Normal file
View File

@ -0,0 +1,65 @@
/* FastLED_RGBW
*
* Hack to enable SK6812 RGBW strips to work with FastLED.
*
* Original code by Jim Bumgardner (http://krazydad.com).
* Modified by David Madison (http://partsnotincluded.com).
*
*/
#include <Arduino.h>
/*#ifndef fastled_h
#include <FastLED.h>
#endif
*/
#ifndef FastLED_RGBW_h
#define FastLED_RGBW_h
struct CRGBW {
union {
struct {
union {
uint8_t g;
uint8_t green;
};
union {
uint8_t r;
uint8_t red;
};
union {
uint8_t b;
uint8_t blue;
};
union {
uint8_t w;
uint8_t white;
};
};
uint8_t raw[4];
};
CRGBW(){}
CRGBW(uint8_t rd, uint8_t grn, uint8_t blu, uint8_t wht){
r = rd;
g = grn;
b = blu;
w = wht;
}
inline void operator = (const CRGB c) __attribute__((always_inline)){
this->r = c.r;
this->g = c.g;
this->b = c.b;
this->white = 0;
}
};
inline uint16_t getRGBWsize(uint16_t nleds){
uint16_t nbytes = nleds * 4;
if(nbytes % 3 > 0) return nbytes / 3 + 1;
else return nbytes / 3;
}
#endif

View File

@ -1,11 +1,9 @@
/* LEDstream_FastLED
*
* Modified version of Adalight that uses the FastLED
* library (http://fastled.io) for driving led strips.
*
* http://github.com/dmadison/Adalight-FastLED
/*
* Project Adalight FastLED
* @author David Madison
* @link github.com/dmadison/Adalight-FastLED
* @license LGPL - Copyright (c) 2017 David Madison
*
* --------------------------------------------------------------------
* This program 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
@ -18,43 +16,69 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* --------------------------------------------------------------------
*
*/
#define SK6812RGBW
#include <Arduino.h>
// --- General Settings
static const uint16_t
Num_Leds = 80; // strip length
static const uint8_t
Brightness = 255; // maximum brightness
const uint16_t
Num_Leds = 112; // strip length
const uint8_t
Brightness = 255; // maximum brightness
// --- FastLED Setings
#define LED_TYPE WS2812B // led strip type for FastLED
#define COLOR_ORDER GRB // color order for bitbang
#define PIN_DATA 6 // led data output pin
//#define PIN_CLOCK 7 // led data clock pin (uncomment if you're using a 4-wire LED type)
#if defined(SK6812RGBW)
#define LED_TYPE SK6812 // led strip type for FastLED
#define COLOR_ORDER RGB // color order for bitbang
#else
#define LED_TYPE WS2812B // led strip type for FastLED
#define COLOR_ORDER GRB // color order for bitbang
#endif
#define PIN_DATA D2 // led data output pin
// #define PIN_CLOCK 7 // led data clock pin (uncomment if you're using a 4-wire LED type)
// --- Serial Settings
static const unsigned long
SerialSpeed = 115200; // serial port speed
static const uint16_t
SerialTimeout = 60; // time before LEDs are shut off if no data (in seconds), 0 to disable
const unsigned long
SerialSpeed = 115200; // serial port speed
const uint16_t
SerialTimeout = 60; // time before LEDs are shut off if no data (in seconds), 0 to disable
// --- Optional Settings (uncomment to add)
#define SERIAL_FLUSH // Serial buffer cleared on LED latch
//#define CLEAR_ON_START // LEDs are cleared on reset
//#define GROUND_PIN 10 // additional grounding pin (optional)
//#define CALIBRATE // sets all LEDs to the color of the first
#define SERIAL_FLUSH // Serial buffer cleared on LED latch
#define CLEAR_ON_START // LEDs are cleared on reset
// --- Debug Settings (uncomment to add)
//#define DEBUG_LED 13 // toggles the Arduino's built-in LED on header match
//#define DEBUG_FPS 8 // enables a pulse on LED latch
#define DEBUG_LED LED_BUILTIN // toggles the Arduino's built-in LED on header match
// #define DEBUG_FPS 8 // enables a pulse on LED latch
// --------------------------------------------------------------------
#include <FastLED.h>
CRGB leds[Num_Leds];
uint8_t * ledsRaw = (uint8_t *)leds;
#if defined(SK6812RGBW)
#include "FastLED_RGBW.h" //rgbw
#endif
//
// FastLED with RGBW
#if defined(SK6812RGBW)
CRGBW send_leds[Num_Leds];
CRGB *send_ledsRaw = (CRGB *) &send_leds[0];
CRGB leds[Num_Leds];
uint8_t * ledsRaw = (uint8_t *)leds;
#else
CRGB leds[Num_Leds];
uint8_t * ledsRaw = (uint8_t *)leds;
#endif
// A 'magic word' (along with LED count & checksum) precedes each block
// of LED data; this assists the microcontroller in syncing up with the
@ -70,7 +94,7 @@ uint8_t * ledsRaw = (uint8_t *)leds;
// XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B,
// where 0 = off and 255 = max brightness.
static const uint8_t magic[] = {
const uint8_t magic[] = {
'A','d','a'};
#define MAGICSIZE sizeof(magic)
@ -81,18 +105,23 @@ static const uint8_t magic[] = {
enum processModes_t {Header, Data} mode = Header;
static int16_t
c;
static uint16_t
outPos;
static uint32_t
bytesRemaining;
static unsigned long
t,
lastByteTime,
lastAckTime;
int16_t c; // current byte, must support -1 if no data available
uint16_t outPos; // current byte index in the LED array
uint32_t bytesRemaining; // count of bytes yet received, set by checksum
unsigned long t, lastByteTime, lastAckTime; // millisecond timestamps
void headerMode();
void dataMode();
void timeouts();
// Macros initialized
#ifdef SERIAL_FLUSH
#undef SERIAL_FLUSH
#define SERIAL_FLUSH while(Serial.available() > 0) { Serial.read(); }
#else
#define SERIAL_FLUSH
#endif
// Debug macros initialized
#ifdef DEBUG_LED
#define ON 1
#define OFF 0
@ -109,11 +138,6 @@ static unsigned long
#endif
void setup(){
#ifdef GROUND_PIN
pinMode(GROUND_PIN, OUTPUT);
digitalWrite(GROUND_PIN, LOW);
#endif
#ifdef DEBUG_LED
pinMode(DEBUG_LED, OUTPUT);
digitalWrite(DEBUG_LED, LOW);
@ -123,10 +147,18 @@ void setup(){
pinMode(DEBUG_FPS, OUTPUT);
#endif
#ifdef PIN_CLOCK
#if defined(PIN_CLOCK) && defined(PIN_DATA)
FastLED.addLeds<LED_TYPE, PIN_DATA, PIN_CLOCK, COLOR_ORDER>(leds, Num_Leds);
#elif defined(PIN_DATA)
#if defined(SK6812RGBW)
//FastLED with RGBW
FastLED.addLeds<LED_TYPE, PIN_DATA, COLOR_ORDER>(send_ledsRaw, getRGBWsize(Num_Leds));
#else
FastLED.addLeds<LED_TYPE, PIN_DATA, COLOR_ORDER>(leds, Num_Leds);
#endif
#else
FastLED.addLeds<LED_TYPE, PIN_DATA, COLOR_ORDER>(leds, Num_Leds);
#error "No LED output pins defined. Check your settings at the top."
#endif
FastLED.setBrightness(Brightness);
@ -141,11 +173,7 @@ void setup(){
lastByteTime = lastAckTime = millis(); // Set initial counters
}
void loop(){
adalight();
}
void adalight(){
void loop(){
t = millis(); // Save current time
// If there is new serial data
@ -193,11 +221,19 @@ void headerMode(){
if(chk == (hi ^ lo ^ 0x55)) {
// Checksum looks valid. Get 16-bit LED count, add 1
// (# LEDs is always > 0) and multiply by 3 for R,G,B.
D_LED(ON);
bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
outPos = 0;
memset(leds, 0, Num_Leds * sizeof(struct CRGB));
mode = Data; // Proceed to latch wait mode
#if defined(SK6812RGBW)
D_LED(ON);
bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
outPos = 0;
memset(leds, 0, Num_Leds * sizeof(struct CRGB));
mode = Data; // Proceed to latch wait mode
#else
D_LED(ON);
bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
outPos = 0;
memset(leds, 0, Num_Leds * sizeof(struct CRGB));
mode = Data; // Proceed to latch wait mode
#endif
}
headPos = 0; // Reset header position regardless of checksum result
break;
@ -208,35 +244,34 @@ void headerMode(){
void dataMode(){
// If LED data is not full
if (outPos < sizeof(leds)){
dataSet();
#if defined(SK6812RGBW)
ledsRaw[outPos++] = c; // Issue next byte
#else
ledsRaw[outPos++] = c; // Issue next byte
#endif
}
bytesRemaining--;
if(bytesRemaining == 0) {
// End of data -- issue latch:
mode = Header; // Begin next header search
#if defined(SK6812RGBW)
//Copy data over
for(int i = 0; i < Num_Leds; i++){
//send_leds[i] = CRGBW(0, 0, 0, 50);
send_leds[i] = CRGBW(leds[i].r, leds[i].g, leds[i].b, 0);
}
#endif
FastLED.show();
D_FPS;
D_LED(OFF);
#ifdef SERIAL_FLUSH
serialFlush();
#endif
SERIAL_FLUSH;
}
}
void dataSet(){
#ifdef CALIBRATE
if(outPos < 3)
ledsRaw[outPos++] = c;
else{
ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color
outPos++;
}
#else
ledsRaw[outPos++] = c; // Issue next byte
#endif
}
void timeouts(){
// No data received. If this persists, send an ACK packet
// to host once every second to alert it to our presence.
@ -246,16 +281,22 @@ void timeouts(){
// If no data received for an extended time, turn off all LEDs.
if(SerialTimeout != 0 && (t - lastByteTime) >= (uint32_t) SerialTimeout * 1000) {
memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes
#if defined(SK6812RGBW)
memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes
#else
memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes
#endif
#if defined(SK6812RGBW)
//All Black
for(int i = 0; i < Num_Leds; i++){
send_leds[i] = CRGBW(0, 0, 0, 0);
}
#endif
FastLED.show();
mode = Header;
lastByteTime = t; // Reset counter
}
}
}
void serialFlush(){
while(Serial.available() > 0) {
Serial.read();
}
}