From fdf60c2eb4c529f20725632966d7e082810c1d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Tue, 14 Jul 2015 09:54:54 +0200 Subject: [PATCH] add fnordlicht VLC atmolight implementation --- firmware/main.c | 108 +++++++++++++++++++++++++++++++++++++--- test.rb | 60 ++++++++++++++++++++++ vlc-fnordlicht-dump.txt | 40 +++++++++++++++ 3 files changed, 202 insertions(+), 6 deletions(-) create mode 100755 test.rb create mode 100644 vlc-fnordlicht-dump.txt diff --git a/firmware/main.c b/firmware/main.c index 0c3a470..41f99ed 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -26,8 +26,19 @@ #include // Program Space Utilities #include // Power Management and Sleep Modes -#include "uart.h" // basic UART functions #include "main.h" // main definitions +#include "uart.h" // basic UART functions +#include "ws2812b.h" // to control WS2812B LEDs + +/* global variables */ +const uint8_t leds_per_channel[WS2812B_NB_CHANNELS] = {11,8,11,11,8,11}; // 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 + +/* 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) @@ -57,6 +68,44 @@ void wdt_init(void) return; } +/* receive UART input */ +ISR(USART_RX_vect) { /* UART receive interrupt */ + uart_char = getchar(); // save current character + 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]=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 + led_off(); + } } return 0; } diff --git a/test.rb b/test.rb new file mode 100755 index 0000000..357cac4 --- /dev/null +++ b/test.rb @@ -0,0 +1,60 @@ +#!/usr/bin/env ruby +# encoding: utf-8 +# ruby: 1.9 +require 'serialport' + +atmolight = SerialPort.open("/dev/ttyUSB0",{ baud: 19200, databits: 8, parity: SerialPort::NONE, stop_bit: 1, flow_control: SerialPort::NONE}) + +# reset arduino +atmolight.dtr = 1 +sleep 0.5 +atmolight.dtr = 0 +sleep 0.5 +atmolight.flush_output +atmolight.flush_input +atmolight.baud = 19200 + +puts "waiting for welcome message" +puts atmolight.gets + +puts "sending test commands" +commands = [ + "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # start bootloader + "\x00\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # start application + "\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00", # sync sequence + "\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00", # too long sync sequence + "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # unhandled command +] +commands.each do |command| + sleep 0.5 + atmolight.write command + atmolight.flush_output +end + +# test all LEDs with red +puts "cycle LEDs" +60.times do |i| + atmolight.write [i,0x01,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00].pack("C*") # set LED to red + atmolight.flush_output + atmolight.write [0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00].pack("C*") # flush + atmolight.flush_output + sleep 0.25 + atmolight.write [i,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00].pack("C*") # switch off LED + atmolight.flush_output +end + +# increase white +puts "white fading" +atmolight.write "\x00\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +atmolight.flush_output +sleep 0.5 +white = 0 +while true do + start = Time.now + 61.times do |i| + atmolight.write [i,0x01,0x00,0x00,white,white,white,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00].pack("C*") # set LED to red + atmolight.flush_output + end + white = (white+10)%256 + puts "set white #{white} in #{Time.now-start} s" +end diff --git a/vlc-fnordlicht-dump.txt b/vlc-fnordlicht-dump.txt new file mode 100644 index 0000000..e2333bd --- /dev/null +++ b/vlc-fnordlicht-dump.txt @@ -0,0 +1,40 @@ +1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00 +ff0801000000000000000000000000 +000180011e1e1e0000000000000000 +010180011e1e1e0000000000000000 +020180011e1e1e0000000000000000 +030180011e1e1e0000000000000000 +040180011e1e1e0000000000000000 +050180011e1e1e0000000000000000 +060180011e1e1e0000000000000000 +070180011e1e1e0000000000000000 +ff0801000000000000000000000000 +1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00 +ff806b5627fc000000000000000000 +1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00 +ff0801000000000000000000000000 +000180018282820000000000000000 +01018001817f7c0000000000000000 +0201800183817e0000000000000000 +030180018686860000000000000000 +040180018c8c8c0000000000000000 +050180018c8c8c0000000000000000 +060180018a8a8a0000000000000000 +07018001817f7c0000000000000000 +000180018282820000000000000000 +01018001817f7c0000000000000000 +0201800183817e0000000000000000 +030180018686860000000000000000 +040180018c8c8c0000000000000000 +050180018c8c8c0000000000000000 +060180018a8a8a0000000000000000 +07018001817f7c0000000000000000 +ff0801000000000000000000000000 +1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00 +ff806b5627fc000000000000000000 +1b1b1b1b1b1b1b1b1b + + + +1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00 +ff0801000000000000000000000000