Skip to content

Instantly share code, notes, and snippets.

@tuxuser
Last active August 25, 2023 02:20
Show Gist options
  • Save tuxuser/45d06bfc2eb8b92de2f8c6fe0dded28d to your computer and use it in GitHub Desktop.
Save tuxuser/45d06bfc2eb8b92de2f8c6fe0dded28d to your computer and use it in GitHub Desktop.
Adalight Neopixel implementation (SK6812 RGBW works)
#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