A version of library with explicit flush() .

Fork of Chainable_RGB_LED by Seeed

Committer:
bor2
Date:
Sun Aug 26 00:29:00 2018 +0000
Revision:
2:d827cd87b212
Parent:
1:50d0a66599e1
Addressing problems that some B and G colors are swapped and some segments are powered by several strips.; ; Note this code doesn't compile in Eclipse and I'd like to figure out why.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
seeed 0:24631ceaa38a 1 /*
seeed 0:24631ceaa38a 2 * Copyright (C) 2013 Seeed Technology Inc.
seeed 0:24631ceaa38a 3 * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com)
seeed 0:24631ceaa38a 4 *
sam_grove 1:50d0a66599e1 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
seeed 0:24631ceaa38a 6 * this software and associated documentation files (the "Software"), to deal in
seeed 0:24631ceaa38a 7 * the Software without restriction, including without limitation the rights to
seeed 0:24631ceaa38a 8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
seeed 0:24631ceaa38a 9 * the Software, and to permit persons to whom the Software is furnished to do so,
seeed 0:24631ceaa38a 10 * subject to the following conditions:
sam_grove 1:50d0a66599e1 11 *
sam_grove 1:50d0a66599e1 12 * The above copyright notice and this permission notice shall be included in all
seeed 0:24631ceaa38a 13 * copies or substantial portions of the Software.
sam_grove 1:50d0a66599e1 14 *
seeed 0:24631ceaa38a 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
seeed 0:24631ceaa38a 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
seeed 0:24631ceaa38a 17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
seeed 0:24631ceaa38a 18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
sam_grove 1:50d0a66599e1 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
seeed 0:24631ceaa38a 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
seeed 0:24631ceaa38a 21 */
seeed 0:24631ceaa38a 22
seeed 0:24631ceaa38a 23 /* Information about the P9813 protocol obtained from:
seeed 0:24631ceaa38a 24 * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED
seeed 0:24631ceaa38a 25 *
seeed 0:24631ceaa38a 26 * HSB to RGB routine adapted from:
seeed 0:24631ceaa38a 27 * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
seeed 0:24631ceaa38a 28 *
seeed 0:24631ceaa38a 29 * This library is ported from Arduino to mbed
seeed 0:24631ceaa38a 30 */
seeed 0:24631ceaa38a 31
sam_grove 1:50d0a66599e1 32 #include "ChainableLED.h"
sam_grove 1:50d0a66599e1 33
sam_grove 1:50d0a66599e1 34 float hue2rgb(float p, float q, float t)
sam_grove 1:50d0a66599e1 35 {
sam_grove 1:50d0a66599e1 36 if (t < 0.0f) {
sam_grove 1:50d0a66599e1 37 t += 1.0f;
sam_grove 1:50d0a66599e1 38 }
sam_grove 1:50d0a66599e1 39 if(t > 1.0f) {
sam_grove 1:50d0a66599e1 40 t -= 1.0f;
sam_grove 1:50d0a66599e1 41 }
sam_grove 1:50d0a66599e1 42 if(t < 1.0f/6.0f) {
sam_grove 1:50d0a66599e1 43 return p + (q - p) * 6.0f * t;
sam_grove 1:50d0a66599e1 44 }
sam_grove 1:50d0a66599e1 45 if(t < 1.0f/2.0f) {
sam_grove 1:50d0a66599e1 46 return q;
sam_grove 1:50d0a66599e1 47 }
sam_grove 1:50d0a66599e1 48 if(t < 2.0f/3.0f) {
sam_grove 1:50d0a66599e1 49 return p + (q - p) * (2.0f/3.0f - t) * 6.0f;
sam_grove 1:50d0a66599e1 50 }
sam_grove 1:50d0a66599e1 51
sam_grove 1:50d0a66599e1 52 return p;
sam_grove 1:50d0a66599e1 53 }
seeed 0:24631ceaa38a 54
seeed 0:24631ceaa38a 55 // --------------------------------------------------------------------------------------
seeed 0:24631ceaa38a 56
sam_grove 1:50d0a66599e1 57 ChainableLED::ChainableLED(PinName clk_pin, PinName data_pin, uint32_t number_of_leds) :
sam_grove 1:50d0a66599e1 58 _clk_pin(clk_pin),
sam_grove 1:50d0a66599e1 59 _data_pin(data_pin),
sam_grove 1:50d0a66599e1 60 _num_leds(number_of_leds)
seeed 0:24631ceaa38a 61 {
sam_grove 1:50d0a66599e1 62 _leds = new led_val_t [number_of_leds];
sam_grove 1:50d0a66599e1 63 _clk_pin = 0;
sam_grove 1:50d0a66599e1 64 _data_pin = 0;
sam_grove 1:50d0a66599e1 65 ledsOff();
seeed 0:24631ceaa38a 66 }
seeed 0:24631ceaa38a 67
seeed 0:24631ceaa38a 68 ChainableLED::~ChainableLED()
seeed 0:24631ceaa38a 69 {
sam_grove 1:50d0a66599e1 70 delete [] _leds;
seeed 0:24631ceaa38a 71 }
seeed 0:24631ceaa38a 72
sam_grove 1:50d0a66599e1 73 void ChainableLED::ledsOff(void)
seeed 0:24631ceaa38a 74 {
sam_grove 1:50d0a66599e1 75 for (uint8_t i=0; i<_num_leds; i++) {
sam_grove 1:50d0a66599e1 76 setColorRGB(i, 0, 0, 0);
sam_grove 1:50d0a66599e1 77 }
bor2 2:d827cd87b212 78 flush();
seeed 0:24631ceaa38a 79 }
seeed 0:24631ceaa38a 80
seeed 0:24631ceaa38a 81 void ChainableLED::sendByte(uint8_t b)
seeed 0:24631ceaa38a 82 {
seeed 0:24631ceaa38a 83 // Send one bit at a time, starting with the MSB
sam_grove 1:50d0a66599e1 84 for (uint8_t i=0; i<8; i++) {
sam_grove 1:50d0a66599e1 85 _data_pin = (b & 0x80) ? 1 : 0;
sam_grove 1:50d0a66599e1 86 _clk_pin = 1;
sam_grove 1:50d0a66599e1 87 _clk_pin = 0;
seeed 0:24631ceaa38a 88 b <<= 1;
seeed 0:24631ceaa38a 89 }
seeed 0:24631ceaa38a 90 }
sam_grove 1:50d0a66599e1 91
seeed 0:24631ceaa38a 92 void ChainableLED::sendColor(uint8_t red, uint8_t green, uint8_t blue)
seeed 0:24631ceaa38a 93 {
sam_grove 1:50d0a66599e1 94 uint8_t r67 = ~(red & 0xC0) >> 6;;
sam_grove 1:50d0a66599e1 95 uint8_t g67 = ~(green & 0xC0) >> 4;
sam_grove 1:50d0a66599e1 96 uint8_t b67 = ~(blue & 0xC0) >> 2;
sam_grove 1:50d0a66599e1 97 uint8_t verify = 0xC0 | r67 | g67 | b67;
sam_grove 1:50d0a66599e1 98
sam_grove 1:50d0a66599e1 99 sendByte(verify);
seeed 0:24631ceaa38a 100 sendByte(blue);
seeed 0:24631ceaa38a 101 sendByte(green);
seeed 0:24631ceaa38a 102 sendByte(red);
seeed 0:24631ceaa38a 103 }
seeed 0:24631ceaa38a 104
sam_grove 1:50d0a66599e1 105 void ChainableLED::setColorRGB(uint32_t led, uint8_t red, uint8_t green, uint8_t blue)
seeed 0:24631ceaa38a 106 {
bor2 2:d827cd87b212 107 _leds->rgb[led*3 + 0] = red;
bor2 2:d827cd87b212 108 _leds->rgb[led*3 + 1] = green;
bor2 2:d827cd87b212 109 _leds->rgb[led*3 + 2] = blue;
bor2 2:d827cd87b212 110 }
bor2 2:d827cd87b212 111
bor2 2:d827cd87b212 112 void ChainableLED::flush() {
seeed 0:24631ceaa38a 113 // Send data frame prefix (32x "0")
seeed 0:24631ceaa38a 114 sendByte(0x00);
seeed 0:24631ceaa38a 115 sendByte(0x00);
seeed 0:24631ceaa38a 116 sendByte(0x00);
seeed 0:24631ceaa38a 117 sendByte(0x00);
sam_grove 1:50d0a66599e1 118
seeed 0:24631ceaa38a 119 // Send color data for each one of the leds
bor2 2:d827cd87b212 120 for (uint32_t i=0; i<_num_leds; i++) {
sam_grove 1:50d0a66599e1 121 sendColor(_leds->rgb[i*3 + 0], _leds->rgb[i*3 + 1], _leds->rgb[i*3 + 2]);
seeed 0:24631ceaa38a 122 }
seeed 0:24631ceaa38a 123
seeed 0:24631ceaa38a 124 // Terminate data frame (32x "0")
seeed 0:24631ceaa38a 125 sendByte(0x00);
seeed 0:24631ceaa38a 126 sendByte(0x00);
seeed 0:24631ceaa38a 127 sendByte(0x00);
seeed 0:24631ceaa38a 128 sendByte(0x00);
seeed 0:24631ceaa38a 129 }
seeed 0:24631ceaa38a 130
sam_grove 1:50d0a66599e1 131 template<typename T>
sam_grove 1:50d0a66599e1 132 T min(T a, T b) { return (a < b) ? a : b; }
sam_grove 1:50d0a66599e1 133
sam_grove 1:50d0a66599e1 134 template<typename T>
sam_grove 1:50d0a66599e1 135 static inline T max(T a, T b) { return (a > b) ? a : b; }
sam_grove 1:50d0a66599e1 136
sam_grove 1:50d0a66599e1 137 void ChainableLED::setColorHSB(uint32_t led, float hue, float saturation, float brightness)
seeed 0:24631ceaa38a 138 {
seeed 0:24631ceaa38a 139 float r, g, b;
seeed 0:24631ceaa38a 140
sam_grove 1:50d0a66599e1 141 hue = min<float>(hue, 1.0f);//constrain(hue, 0.0, 1.0);
sam_grove 1:50d0a66599e1 142 hue = max<float>(hue, 0.0f);
sam_grove 1:50d0a66599e1 143 saturation = min<float>(saturation, 1.0f);//constrain(saturation, 0.0, 1.0);
sam_grove 1:50d0a66599e1 144 saturation = max<float>(saturation, 0.0f);
sam_grove 1:50d0a66599e1 145 brightness = min<float>(brightness, 1.0f);//constrain(brightness, 0.0, 1.0);
sam_grove 1:50d0a66599e1 146 brightness = max<float>(brightness, 0.0f);
seeed 0:24631ceaa38a 147
sam_grove 1:50d0a66599e1 148 if(saturation == 0.0f) {
seeed 0:24631ceaa38a 149 r = g = b = brightness;
sam_grove 1:50d0a66599e1 150 } else {
sam_grove 1:50d0a66599e1 151 float q = (brightness < 0.5f) ? (brightness * (1.0f + saturation)) : (brightness + saturation - brightness * saturation);
sam_grove 1:50d0a66599e1 152 float p = 2.0f * brightness - q;
sam_grove 1:50d0a66599e1 153 r = hue2rgb(p, q, hue + 1.0f/3.0f);
seeed 0:24631ceaa38a 154 g = hue2rgb(p, q, hue);
sam_grove 1:50d0a66599e1 155 b = hue2rgb(p, q, hue - 1.0f/3.0f);
seeed 0:24631ceaa38a 156 }
seeed 0:24631ceaa38a 157
sam_grove 1:50d0a66599e1 158 setColorRGB(led, (uint8_t)(255.0f*r), (uint8_t)(255.0f*g), (uint8_t)(255.0f*b));
bor2 2:d827cd87b212 159 flush();
seeed 0:24631ceaa38a 160 }