Created
October 13, 2016 09:10
-
-
Save bkrepo/bb23045dceec98a866e80cfe54baa01e to your computer and use it in GitHub Desktop.
odlight: Ambilight for ODROID
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
| /*----------------------------------------------------------------------------*/ | |
| /* | |
| Ambilight Project : Arduino Uno Board with WS2801/WS2812B LED Strip | |
| Arduino Pin Connection | |
| - Mode 0 (1 wire) : | |
| Data Out Pin 6 | |
| - Mode 1 (3 wire : spi mode = 0, clk = 2Mhz) : | |
| Data Out Pin 11 | |
| Clock Out Pin 13 | |
| Connect to Board : H/W Serial (USB, ttyACM, Baud 1000000N81) | |
| Dev Board : ODROID-C2 | |
| WS2812B Spec : | |
| - Max Current : 60mA per 1 Cell (Max bright) | |
| - Data Transfer : 800Khz Serial(1 wire) Communication(1.25us) | |
| WS2801 Spec : | |
| - Max Current : 120mA per 1 Cell (Max bright) | |
| - Data Transfer : 2Mhz Serial(3 wire : spi mode) Communication | |
| Use Library : Install Arduino Library folder | |
| - Adafruit_NeoPixel : https://github.com/adafruit/Adafruit_NeoPixel | |
| - Git clone : https://github.com/adafruit/Adafruit_NeoPixel.git | |
| Protocol : | |
| Receive : HEADER[4] + (num_of_leds in HEADER) * 3 bytes | |
| Transceive : 'N' (Ack for Data received) | |
| Header Information | |
| 'o', 'd', num of leds(1byte), check sum(1byte) | |
| Check Sum Information | |
| HEADER[3] = 0; | |
| HEADER[3] ^= HEADER[0]; | |
| HEADER[3] ^= HEADER[1]; | |
| HEADER[3] ^= HEADER[2]; | |
| Serial Data send time : 10us/byte (Buad : 1000000 bps) | |
| SPI Data send time : 5us/byte (SCKL : 2000000 Hz) | |
| 1 wire data send time : 12.5us/byte (Freq : 800000 Hz) | |
| Hardkernel Co.,Ltd (2016/10/11) | |
| */ | |
| /*----------------------------------------------------------------------------*/ | |
| /* Include Adafruit NeoPixel library */ | |
| #include <Adafruit_NeoPixel.h> | |
| #include <SPI.h> | |
| /*----------------------------------------------------------------------------*/ | |
| /* Data Out PIN */ | |
| #define DOUT_PIN 6 | |
| #define MAX_LEDS 256 | |
| #define SERIAL_BAUD 1000000 | |
| #define HEADER_SIZE 4 | |
| /* Use LED type define */ | |
| #define LED_WS2801 | |
| #define LED_WS2812B | |
| #define TIMEOUT_MSEC 1000 | |
| /*----------------------------------------------------------------------------*/ | |
| /* LED color data struct */ | |
| struct led_data_t { | |
| uint8_t b; | |
| uint8_t g; | |
| uint8_t r; | |
| }; | |
| /*----------------------------------------------------------------------------*/ | |
| /* Create 'leds' object to drive LEDs */ | |
| Adafruit_NeoPixel leds = Adafruit_NeoPixel(MAX_LEDS, DOUT_PIN, NEO_GRB + NEO_KHZ800); | |
| /* Serial Data Receive buffer */ | |
| uint8_t SerialBuffer[sizeof(led_data_t) * MAX_LEDS]; | |
| /*----------------------------------------------------------------------------*/ | |
| void setup() { | |
| /* H/W Serial Init */ | |
| Serial.begin(SERIAL_BAUD); | |
| /* SPI Port Init for WS2801 LED, 80kbytes/sec */ | |
| SPI.setBitOrder(MSBFIRST); | |
| /* SPI Clock = 16 Mhz / 8 = 2 Mhz, 200kbytes/sec */ | |
| SPI.setClockDivider(SPI_CLOCK_DIV8); | |
| SPI.setDataMode(SPI_MODE0); | |
| SPI.begin(); | |
| SPCR |= _BV(MSTR); | |
| SPCR &= ~_BV(SPIE); | |
| SPSR; | |
| for(int i = 0; i < MAX_LEDS * sizeof(led_data_t); i++) | |
| SPI.transfer(0x00); | |
| /* NeoPixel Lib Init for WS2812B */ | |
| leds.begin(); | |
| leds.clear(); | |
| leds.show(); | |
| } | |
| /*----------------------------------------------------------------------------*/ | |
| uint8_t check_timeout(unsigned long current_time) | |
| { | |
| static unsigned long prev_time; | |
| unsigned long diff_time; | |
| if (current_time) { | |
| diff_time = current_time - prev_time; | |
| if (diff_time > TIMEOUT_MSEC) { | |
| prev_time = millis(); | |
| Serial.write("N"); | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| prev_time = millis(); | |
| return 0; | |
| } | |
| /*----------------------------------------------------------------------------*/ | |
| uint16_t check_header() { | |
| uint8_t header[4] = {0, }; | |
| uint16_t rx_cnt = 0; | |
| /* start time check */ | |
| check_timeout(0); | |
| while(true) { | |
| if (Serial.available()) { | |
| header[rx_cnt++] = Serial.read(); | |
| if (rx_cnt >= HEADER_SIZE) { | |
| if ((header[0] == 'o') && (header[1] == 'd')) { | |
| uint8_t check_sum = 0; | |
| check_sum ^= header[0]; | |
| check_sum ^= header[1]; | |
| check_sum ^= header[2]; | |
| /* Return num of leds */ | |
| if (check_sum == header[3]) | |
| return (uint16_t)header[2]; | |
| } | |
| rx_cnt -= 1; | |
| header[0] = header[1]; | |
| header[1] = header[2]; | |
| header[2] = header[3]; | |
| } | |
| } | |
| else | |
| check_timeout(millis()); | |
| } | |
| } | |
| /*----------------------------------------------------------------------------*/ | |
| void loop() { | |
| uint16_t rx_cnt, recv_data_size; | |
| while(true) { | |
| timeout_data: | |
| recv_data_size = check_header() * sizeof(led_data_t); | |
| /* rx buffer pointer init */ | |
| rx_cnt = 0; | |
| /* start time check */ | |
| check_timeout(0); | |
| while(true) { | |
| if (Serial.available()) | |
| SerialBuffer[rx_cnt++] = Serial.read(); | |
| else if (check_timeout(millis())) | |
| goto timeout_data; | |
| if (rx_cnt >= recv_data_size) | |
| break; | |
| } | |
| #if defined(LED_WS2801) | |
| /* WS2801 LED Update */ | |
| for (rx_cnt = 0; rx_cnt < recv_data_size; rx_cnt ++) | |
| SPI.transfer(SerialBuffer[rx_cnt]); | |
| #endif | |
| #if defined(LED_WS2812B) | |
| /* WS2812B LED Update */ | |
| recv_data_size /= sizeof(led_data_t); | |
| led_data_t *led_data = (led_data_t *)&SerialBuffer[0]; | |
| for (rx_cnt = 0; rx_cnt < recv_data_size; rx_cnt++) | |
| leds.setPixelColor(rx_cnt, leds.Color(led_data[rx_cnt].r, | |
| led_data[rx_cnt].g, | |
| led_data[rx_cnt].b)); | |
| leds.show(); | |
| #endif | |
| /* Ack Send for Data Received */ | |
| Serial.print("N"); | |
| } | |
| } | |
| /*----------------------------------------------------------------------------*/ | |
| /*----------------------------------------------------------------------------*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment