Jackson Lv / ChainableLED

Dependents:   BLENano_RGB_Demo BLENano_RGB_Demo_DAP ble-devicelink-example connected-lights

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ChainableLED.cpp Source File

ChainableLED.cpp

00001 /*
00002  * Copyright (C) 2013 Seeed Technology Inc.
00003  * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com)
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a copy of 
00006  * this software and associated documentation files (the "Software"), to deal in
00007  * the Software without restriction, including without limitation the rights to
00008  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
00009  * the Software, and to permit persons to whom the Software is furnished to do so,
00010  * subject to the following conditions:
00011  * 
00012  * The above copyright notice and this permission notice shall be included in all 
00013  * copies or substantial portions of the Software.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
00017  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
00018  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00019  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
00020  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 /* Information about the P9813 protocol obtained from:
00024  * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED
00025  *
00026  * HSB to RGB routine adapted from:
00027  * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
00028  *
00029  * This library is ported from Arduino to mbed
00030  */
00031 
00032 
00033 // --------------------------------------------------------------------------------------
00034 
00035 #include "ChainableLED.h"
00036 
00037 // Forward declaration
00038 float hue2rgb(float p, float q, float t);
00039 
00040 // --------------------------------------------------------------------------------------
00041 
00042 ChainableLED::ChainableLED(PinName clk_pin, PinName data_pin, unsigned int number_of_leds) :
00043     _clk_pin(clk_pin), _data_pin(data_pin)
00044 {
00045     _num_leds = number_of_leds;
00046     
00047     for (uint8_t i=0; i<_num_leds; i++)
00048         setColorRGB(i, 0, 0, 0);
00049 }
00050 
00051 ChainableLED::~ChainableLED()
00052 {
00053 }
00054 
00055 // --------------------------------------------------------------------------------------
00056 
00057 void ChainableLED::clk(void)
00058 {
00059     _clk_pin = 0;
00060     wait_us(_CLK_PULSE_DELAY);
00061     _clk_pin = 1;
00062     wait_us(_CLK_PULSE_DELAY);
00063 }
00064 
00065 void ChainableLED::sendByte(uint8_t b)
00066 {
00067     // Send one bit at a time, starting with the MSB
00068     for (uint8_t i=0; i<8; i++)
00069     {
00070         // If MSB is 1, write one and clock it, else write 0 and clock
00071         if ((b & 0x80) != 0)
00072             _data_pin = 1;
00073         else
00074             _data_pin = 0;
00075             
00076         clk();
00077 
00078         // Advance to the next bit to send
00079         b <<= 1;
00080     }
00081 }
00082  
00083 void ChainableLED::sendColor(uint8_t red, uint8_t green, uint8_t blue)
00084 {
00085     // Start by sending a uint8_t with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6"
00086     uint8_t prefix = 0xC0;
00087     if ((blue & 0x80) == 0)     prefix|= 0x20;
00088     if ((blue & 0x40) == 0)     prefix|= 0x10; 
00089     if ((green & 0x80) == 0)    prefix|= 0x08;
00090     if ((green & 0x40) == 0)    prefix|= 0x04;
00091     if ((red & 0x80) == 0)      prefix|= 0x02;
00092     if ((red & 0x40) == 0)      prefix|= 0x01;
00093     sendByte(prefix);
00094         
00095     // Now must send the 3 colors
00096     sendByte(blue);
00097     sendByte(green);
00098     sendByte(red);
00099 }
00100 
00101 void ChainableLED::setColorRGB(unsigned int led, uint8_t red, uint8_t green, uint8_t blue)
00102 {
00103     // Send data frame prefix (32x "0")
00104     sendByte(0x00);
00105     sendByte(0x00);
00106     sendByte(0x00);
00107     sendByte(0x00);
00108     
00109     // Send color data for each one of the leds
00110     for (uint8_t i=0; i<_num_leds; i++)
00111     {
00112         if (i == led)
00113         {
00114             _led_state[i*3 + _CL_RED] = red;
00115             _led_state[i*3 + _CL_GREEN] = green;
00116             _led_state[i*3 + _CL_BLUE] = blue;
00117         }
00118                     
00119         sendColor(_led_state[i*3 + _CL_RED], 
00120                   _led_state[i*3 + _CL_GREEN], 
00121                   _led_state[i*3 + _CL_BLUE]);
00122     }
00123 
00124     // Terminate data frame (32x "0")
00125     sendByte(0x00);
00126     sendByte(0x00);
00127     sendByte(0x00);
00128     sendByte(0x00);
00129 }
00130 
00131 void ChainableLED::setColorHSB(unsigned int led, float hue, float saturation, float brightness)
00132 {
00133     float r, g, b;
00134     
00135 //     constrain(hue, 0.0, 1.0);
00136 //     constrain(saturation, 0.0, 1.0);
00137 //     constrain(brightness, 0.0, 1.0);
00138 
00139     if(saturation == 0.0)
00140     {
00141         r = g = b = brightness;
00142     }
00143     else
00144     {
00145         float q = brightness < 0.5 ? 
00146             brightness * (1.0 + saturation) : brightness + saturation - brightness * saturation;
00147         float p = 2.0 * brightness - q;
00148         r = hue2rgb(p, q, hue + 1.0/3.0);
00149         g = hue2rgb(p, q, hue);
00150         b = hue2rgb(p, q, hue - 1.0/3.0);
00151     }
00152 
00153     setColorRGB(led, (uint8_t)(255.0*r), (uint8_t)(255.0*g), (uint8_t)(255.0*b));
00154 }
00155 
00156 // --------------------------------------------------------------------------------------
00157 
00158 float hue2rgb(float p, float q, float t)
00159 {
00160     if (t < 0.0) 
00161         t += 1.0;
00162     if(t > 1.0) 
00163         t -= 1.0;
00164     if(t < 1.0/6.0) 
00165         return p + (q - p) * 6.0 * t;
00166     if(t < 1.0/2.0) 
00167         return q;
00168     if(t < 2.0/3.0) 
00169         return p + (q - p) * (2.0/3.0 - t) * 6.0;
00170 
00171     return p;
00172 }