Last active
August 25, 2023 02:20
-
-
Save tuxuser/45d06bfc2eb8b92de2f8c6fe0dded28d to your computer and use it in GitHub Desktop.
Adalight Neopixel implementation (SK6812 RGBW works)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Adafruit_NeoPixel.h> | |
#ifdef __AVR__ | |
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket | |
#endif | |
/************************************** | |
S E T U P | |
set following values to your needs | |
**************************************/ | |
#define INITIAL_LED_TEST_ENABLED true | |
#define INITIAL_LED_TEST_BRIGHTNESS 32 // 0..255 | |
#define INITIAL_LED_TEST_TIME_MS 500 // 10.. | |
#define MAX_LEDS 225 | |
// type of your led controller, possible values, see below | |
#define LED_TYPE NEO_GRBW | |
#define LED_FREQUENCY NEO_KHZ800 | |
#define LED_PINS 6 // 3 wire leds | |
#define OFF_TIMEOUT 15000 // ms to switch off after no data was received, set 0 to deactivate | |
#define BRIGHTNESS 255 // maximum brightness 0-255 | |
// Baudrate, higher rate allows faster refresh rate and more LEDs | |
//#define serialRate 460800 // use 115200 for ftdi based boards | |
#define serialRate 115200 // use 115200 for ftdi based boards | |
//#define serialRate 500000 // use 115200 for ftdi based boards | |
/************************************** | |
A D A L I G H T C O D E | |
no user changes needed | |
**************************************/ | |
// Adalight sends a "Magic Word" (defined in /etc/boblight.conf) before sending the pixel data | |
uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, chk, i; | |
unsigned long endTime; | |
// Define the array of leds | |
Adafruit_NeoPixel leds(MAX_LEDS, LED_PINS, LED_TYPE + LED_FREQUENCY); | |
// set color to all leds | |
void showColor(uint8_t r, uint8_t g, uint8_t b) { | |
#if MAX_LEDS > 1 | |
for (int led_pos=0; led_pos < MAX_LEDS; led_pos++) { | |
leds.setPixelColor(led_pos, leds.Color(r, g, b)); | |
} | |
leds.show(); | |
#endif | |
} | |
// switch of digital and analog leds | |
void switchOff() { | |
#if MAX_LEDS > 1 | |
leds.clear(); | |
leds.show(); | |
#endif | |
} | |
// function to check if serial data is available | |
// if timeout occured leds switch of, if configured | |
bool checkIncomingData() { | |
boolean dataAvailable = true; | |
while (!Serial.available()) { | |
if ( OFF_TIMEOUT > 0 && endTime < millis()) { | |
switchOff(); | |
dataAvailable = false; | |
endTime = millis() + OFF_TIMEOUT; | |
} | |
} | |
return dataAvailable; | |
} | |
// main function that setups and runs the code | |
void setup() { | |
Serial.begin(serialRate); | |
int ledCount = MAX_LEDS; | |
leds.begin(); | |
// color adjustments | |
leds.setBrightness ( BRIGHTNESS ); | |
// initial RGB flash | |
#if INITIAL_LED_TEST_ENABLED == true | |
for (int v=0;v<INITIAL_LED_TEST_BRIGHTNESS;v++) | |
{ | |
showColor(v,v,v); | |
delay(INITIAL_LED_TEST_TIME_MS/2/INITIAL_LED_TEST_BRIGHTNESS); | |
} | |
for (int v=0;v<INITIAL_LED_TEST_BRIGHTNESS;v++) | |
{ | |
showColor(v,v,v); | |
delay(INITIAL_LED_TEST_TIME_MS/2/INITIAL_LED_TEST_BRIGHTNESS); | |
} | |
#endif | |
showColor(0, 0, 0); | |
Serial.print("Ada\n"); // Send "Magic Word" string to host | |
Serial.println("Ada: LED num: " + String(MAX_LEDS)); //Return number of LEDs configured | |
boolean transmissionSuccess; | |
unsigned long sum_r, sum_g, sum_b; | |
// loop() is avoided as even that small bit of function overhead | |
// has a measurable impact on this code's overall throughput. | |
for(;;) { | |
// wait for first byte of Magic Word | |
for (i = 0; i < sizeof prefix; ++i) { | |
// If next byte is not in Magic Word, the start over | |
if (!checkIncomingData() || prefix[i] != Serial.read()) { | |
i = 0; | |
} | |
} | |
// Hi, Lo, Checksum | |
if (!checkIncomingData()) continue; | |
hi = Serial.read(); | |
if (!checkIncomingData()) continue; | |
lo = Serial.read(); | |
if (!checkIncomingData()) continue; | |
chk = Serial.read(); | |
// if checksum does not match go back to wait | |
if (chk != (hi ^ lo ^ 0x55)) continue; | |
leds.clear(); | |
transmissionSuccess = true; | |
sum_r = 0; | |
sum_g = 0; | |
sum_b = 0; | |
int num_leds = min ( MAX_LEDS, (hi<<8) + lo + 1 ); | |
// read the transmission data and set LED values | |
for (int idx = 0; idx < num_leds; idx++) { | |
byte r, g, b; | |
if (!checkIncomingData()) { | |
transmissionSuccess = false; | |
break; | |
} | |
r = Serial.read(); | |
if (!checkIncomingData()) { | |
transmissionSuccess = false; | |
break; | |
} | |
g = Serial.read(); | |
if (!checkIncomingData()) { | |
transmissionSuccess = false; | |
break; | |
} | |
b = Serial.read(); | |
leds.setPixelColor(idx, leds.Color(r, g, b)); | |
} | |
// shows new values | |
if (transmissionSuccess) { | |
endTime = millis() + OFF_TIMEOUT; | |
#if MAX_LEDS > 1 | |
leds.show(); | |
#endif | |
} | |
} | |
} // end of setup | |
void loop() { | |
// Not used. See note in setup() function. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment