implement atmolight protocol for 60 leds

This commit is contained in:
King Kévin 2015-07-18 20:14:51 +02:00
parent ee5c26cf02
commit ad9747ba67
1 changed files with 30 additions and 41 deletions

View File

@ -31,12 +31,12 @@
#include "ws2812b.h" // to control WS2812B LEDs
/* global variables */
volatile uint8_t uart_in[19*2]; // input from USART, enough space for two atmolight messages (one as buffer)
volatile uint8_t uart_in[4]; // input from USART, enough space for RGB values
volatile uint8_t uart_in_i = 0; // UART input index
const uint8_t channels[] = {11,8,11,11,8,11}; // the number of LEDs for each channel
/* flags, set in the interrupts and handled in the main program */
volatile bool uart_flag = false; // data on UART has been received
volatile char uart_char = 0; // UART data
/* switch off LED */
void led_off(void)
@ -98,56 +98,45 @@ void io_init(void)
int main(void)
{
bool header = false; // has the atmolight message header been received
uint8_t channel = 0; // the current channel
uint8_t channel_led = 0; // the current LED on the current channel
io_init(); // initialize IOs
led_on();
printf(PSTR("welcome on the VLC+AtmoLight+WS2812B CuVoodoo AtmoLight\n"));
printf(PSTR("welcome to the CuVoodoo ScreenLight\n"));
led_off();
while (true) { // endless loop for micro-controller
while (uart_flag) {
uart_flag = false;
if (((uart_in_i==1) && !(uart_in[0]==0xff)) ||
((uart_in_i==2) && !(uart_in[1]==0x00)) ||
((uart_in_i==3) && !(uart_in[2]==0x00)) ||
((uart_in_i==4) && !(uart_in[3]==0x0f))) { // wait for start sequence
led_on(); // indicate something is wrong
uart_in_i = 0; // reset if start sequence is not detected
} else {
led_off();
/* process colors on channels */
if (uart_in_i==10) { // left atmolight channel received (WS2812B channel 2)
for (uint8_t led=0; led<11; led++) {
ws2812b_set_led_color(2,led,uart_in[7],uart_in[8],uart_in[9]);
}
} else if (uart_in_i==13) { // right atmolight channel received (WS2812B channel 5)
for (uint8_t led=0; led<11; led++) {
ws2812b_set_led_color(5,led,uart_in[10],uart_in[11],uart_in[12]);
}
} else if (uart_in_i==16) { // top atmolight channel received (WS2812B channel 0+1)
for (uint8_t led=0; led<11; led++) {
ws2812b_set_led_color(0,led,uart_in[13],uart_in[14],uart_in[15]);
}
for (uint8_t led=0; led<8; led++) {
ws2812b_set_led_color(1,led,uart_in[13],uart_in[14],uart_in[15]);
}
} else if (uart_in_i==19) { // bottom atmolight channel received (WS2812B channel 3+4)
for (uint8_t led=0; led<11; led++) {
ws2812b_set_led_color(3,led,uart_in[16],uart_in[17],uart_in[18]);
}
for (uint8_t led=0; led<8; led++) {
ws2812b_set_led_color(4,led,uart_in[16],uart_in[17],uart_in[18]);
}
if (!header) { // wait until atmolight header
if (((uart_in_i==1) && !(uart_in[0]==0xff)) ||
((uart_in_i==2) && !(uart_in[1]==0x00)) ||
((uart_in_i==3) && !(uart_in[2]==0x00)) ||
((uart_in_i==4) && !(uart_in[3]==3*60))) { // verify atmolight header
led_on(); // indicate something is wrong
uart_in_i = 0; // reset if start sequence is not detected
} else if (uart_in_i==4) { // atmolight header received
led_off(); // remove error indication
header = true; // remember header has been received
uart_in_i = 0; // reset to get values
}
if (uart_in_i>=19) { // end of message
ws2812b_show(); // show the new colors
if (uart_in_i>19) { // move buffered message
for (uint8_t i=19; i<uart_in_i; i++) {
uart_in[i-19] = uart_in[i];
}
} else { // receiving color values
if (uart_in_i>=3) { // RGB color values received
ws2812b_set_led_color(channel,channel_led,uart_in[0],uart_in[1],uart_in[2]); // set LED color
channel_led++; // go the next LED
if (channel_led>=channels[channel]) { // all LEDs of channel have been set
channel++; // got to next channel
channel_led = 0; // restart from first LED
}
uart_in_i -= 19; // start with next message
if (channel>=sizeof(channels)) { // all LEDs have been set
channel = 0; // restart from first channel
header = false; // wait for header
ws2812b_show(); // show the new colors
}
uart_in_i = 0; // get next color
}
}
}