implement atmolight protocol
This commit is contained in:
parent
c2678063c8
commit
6b6589e93c
115
firmware/main.c
115
firmware/main.c
|
@ -31,14 +31,12 @@
|
|||
#include "ws2812b.h" // to control WS2812B LEDs
|
||||
|
||||
/* global variables */
|
||||
const uint8_t leds_per_channel[WS2812B_NB_CHANNELS] = {11,5,9,11,5,9}; // the led strips (top 1, top 2, left, bottom 1, bottom 2, right)
|
||||
uint8_t nb_leds = 0; // the total number of LEDs (will be calculated on the number of LEDs per channel)
|
||||
volatile uint8_t uart_in[16]; // input from USART, enough space for one fnordlight command or sync sequence
|
||||
volatile uint8_t uart_in[19]; // input from USART, enough space for one atmolight message
|
||||
volatile uint8_t uart_in_i = 0; // UART input index
|
||||
|
||||
/* 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
|
||||
volatile bool command_flag = false; // a command has been received
|
||||
|
||||
/* switch off LED */
|
||||
void led_off(void)
|
||||
|
@ -70,40 +68,11 @@ void wdt_init(void)
|
|||
|
||||
/* receive UART input */
|
||||
ISR(USART_RX_vect) { /* UART receive interrupt */
|
||||
uart_char = getchar(); // save current character
|
||||
if (uart_in_i<sizeof(uart_in)) {
|
||||
uart_in[uart_in_i] = getchar(); // save current character
|
||||
uart_in_i++; // got to next one
|
||||
uart_flag = true; // warm main programm
|
||||
}
|
||||
|
||||
/* process command */
|
||||
void command_action(void)
|
||||
{
|
||||
/* parse command */
|
||||
switch (uart_in[1]) {
|
||||
case 0x01: // set LED colors
|
||||
if (uart_in[0]<nb_leds) { // set LED color
|
||||
for (uint8_t channel = 0; channel<sizeof(leds_per_channel); channel++) { // find right channel
|
||||
if (uart_in[0]<leds_per_channel[channel]) { // find right LED
|
||||
ws2812b_set_led_color(channel,uart_in[0],uart_in[4],uart_in[5],uart_in[6]);
|
||||
break;
|
||||
} else {
|
||||
uart_in[0] -= leds_per_channel[channel]; // go to next channel
|
||||
}
|
||||
}
|
||||
} else { // use additional LED setting as signal to show the LEDs
|
||||
ws2812b_show();
|
||||
}
|
||||
break;
|
||||
case 0x08: // stop color changing
|
||||
ws2812b_show(); // use this as flush command
|
||||
break;
|
||||
case 0x80: // start bootloader
|
||||
case 0x87: // start application
|
||||
ws2812b_off();
|
||||
ws2812b_show();
|
||||
break;
|
||||
default:
|
||||
break; // all other commands are not relevant
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize GPIO */
|
||||
|
@ -129,53 +98,53 @@ void io_init(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t uart_in_i = 0; // UART input index
|
||||
uint8_t escape_count = 0; // number of escape bytes received
|
||||
|
||||
io_init(); // initialize IOs
|
||||
|
||||
/* count the total number of LEDs */
|
||||
for (uint8_t i=0; i<sizeof(leds_per_channel); i++) {
|
||||
nb_leds += leds_per_channel[i];
|
||||
}
|
||||
|
||||
led_on();
|
||||
printf(PSTR("welcome on the VLC+fnordlicht+WS2812B AtmoLight\n"));
|
||||
printf(PSTR("welcome on the VLC+AtmoLight+WS2812B CuVoodoo AtmoLight\n"));
|
||||
led_off();
|
||||
|
||||
while (true) { // endless loop for micro-controller
|
||||
while (uart_flag) {
|
||||
/* go to next character but next got pass the last
|
||||
* only sync sequences can be longer than 15, but should only be 16
|
||||
* but sometimes (bug) they are longer
|
||||
* then ignore the escape byte until the sequence ends
|
||||
*/
|
||||
uart_in[uart_in_i] = uart_char;
|
||||
if (uart_in_i<sizeof(uart_in)-1) {
|
||||
uart_in_i++;
|
||||
}
|
||||
|
||||
if (uart_char==0x1b) { // escape byte received
|
||||
if (escape_count<15) { // there should be maximum 15 escape bytes. ignore all additional
|
||||
escape_count++; // count number of escape bytes
|
||||
}
|
||||
} else {
|
||||
if (escape_count>=15) { // end of sync sequence
|
||||
uart_in_i = 0; // reset input but don't handle sync sequence
|
||||
}
|
||||
escape_count = 0; // restart count
|
||||
}
|
||||
if (uart_in_i>=15 && escape_count<15) { // end of command
|
||||
command_flag = true; // notify a command is ready
|
||||
uart_in_i = 0; // reset input
|
||||
}
|
||||
uart_flag = false;
|
||||
}
|
||||
while (command_flag) { // UART input command is ready
|
||||
led_on();
|
||||
command_action(); // process command
|
||||
command_flag = false; // clear flag
|
||||
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 (uart_in_i>=sizeof(uart_in)) { // end of message
|
||||
uart_in_i = 0; // start with next message
|
||||
ws2812b_show(); // show the new colors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue