using PWM to control RGB LED for RedBear Demo
Fork of ChainableLED by
ChainableLED.cpp@0:e7513df9d7cb, 2016-04-27 (annotated)
- Committer:
- Jackson_lv
- Date:
- Wed Apr 27 09:47:09 2016 +0000
- Revision:
- 0:e7513df9d7cb
BLE Nano RGB Demo with DAP board
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jackson_lv | 0:e7513df9d7cb | 1 | /* |
Jackson_lv | 0:e7513df9d7cb | 2 | * Copyright (C) 2013 Seeed Technology Inc. |
Jackson_lv | 0:e7513df9d7cb | 3 | * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) |
Jackson_lv | 0:e7513df9d7cb | 4 | * |
Jackson_lv | 0:e7513df9d7cb | 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of |
Jackson_lv | 0:e7513df9d7cb | 6 | * this software and associated documentation files (the "Software"), to deal in |
Jackson_lv | 0:e7513df9d7cb | 7 | * the Software without restriction, including without limitation the rights to |
Jackson_lv | 0:e7513df9d7cb | 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
Jackson_lv | 0:e7513df9d7cb | 9 | * the Software, and to permit persons to whom the Software is furnished to do so, |
Jackson_lv | 0:e7513df9d7cb | 10 | * subject to the following conditions: |
Jackson_lv | 0:e7513df9d7cb | 11 | * |
Jackson_lv | 0:e7513df9d7cb | 12 | * The above copyright notice and this permission notice shall be included in all |
Jackson_lv | 0:e7513df9d7cb | 13 | * copies or substantial portions of the Software. |
Jackson_lv | 0:e7513df9d7cb | 14 | * |
Jackson_lv | 0:e7513df9d7cb | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Jackson_lv | 0:e7513df9d7cb | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
Jackson_lv | 0:e7513df9d7cb | 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
Jackson_lv | 0:e7513df9d7cb | 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
Jackson_lv | 0:e7513df9d7cb | 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
Jackson_lv | 0:e7513df9d7cb | 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Jackson_lv | 0:e7513df9d7cb | 21 | */ |
Jackson_lv | 0:e7513df9d7cb | 22 | |
Jackson_lv | 0:e7513df9d7cb | 23 | /* Information about the P9813 protocol obtained from: |
Jackson_lv | 0:e7513df9d7cb | 24 | * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED |
Jackson_lv | 0:e7513df9d7cb | 25 | * |
Jackson_lv | 0:e7513df9d7cb | 26 | * HSB to RGB routine adapted from: |
Jackson_lv | 0:e7513df9d7cb | 27 | * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript |
Jackson_lv | 0:e7513df9d7cb | 28 | * |
Jackson_lv | 0:e7513df9d7cb | 29 | * This library is ported from Arduino to mbed |
Jackson_lv | 0:e7513df9d7cb | 30 | */ |
Jackson_lv | 0:e7513df9d7cb | 31 | |
Jackson_lv | 0:e7513df9d7cb | 32 | |
Jackson_lv | 0:e7513df9d7cb | 33 | // -------------------------------------------------------------------------------------- |
Jackson_lv | 0:e7513df9d7cb | 34 | |
Jackson_lv | 0:e7513df9d7cb | 35 | #include "ChainableLED.h" |
Jackson_lv | 0:e7513df9d7cb | 36 | |
Jackson_lv | 0:e7513df9d7cb | 37 | // Forward declaration |
Jackson_lv | 0:e7513df9d7cb | 38 | float hue2rgb(float p, float q, float t); |
Jackson_lv | 0:e7513df9d7cb | 39 | |
Jackson_lv | 0:e7513df9d7cb | 40 | // -------------------------------------------------------------------------------------- |
Jackson_lv | 0:e7513df9d7cb | 41 | |
Jackson_lv | 0:e7513df9d7cb | 42 | ChainableLED::ChainableLED(PinName clk_pin, PinName data_pin, unsigned int number_of_leds) : |
Jackson_lv | 0:e7513df9d7cb | 43 | _clk_pin(clk_pin), _data_pin(data_pin) |
Jackson_lv | 0:e7513df9d7cb | 44 | { |
Jackson_lv | 0:e7513df9d7cb | 45 | _num_leds = number_of_leds; |
Jackson_lv | 0:e7513df9d7cb | 46 | |
Jackson_lv | 0:e7513df9d7cb | 47 | for (uint8_t i=0; i<_num_leds; i++) |
Jackson_lv | 0:e7513df9d7cb | 48 | setColorRGB(i, 0, 0, 0); |
Jackson_lv | 0:e7513df9d7cb | 49 | } |
Jackson_lv | 0:e7513df9d7cb | 50 | |
Jackson_lv | 0:e7513df9d7cb | 51 | ChainableLED::~ChainableLED() |
Jackson_lv | 0:e7513df9d7cb | 52 | { |
Jackson_lv | 0:e7513df9d7cb | 53 | } |
Jackson_lv | 0:e7513df9d7cb | 54 | |
Jackson_lv | 0:e7513df9d7cb | 55 | // -------------------------------------------------------------------------------------- |
Jackson_lv | 0:e7513df9d7cb | 56 | |
Jackson_lv | 0:e7513df9d7cb | 57 | void ChainableLED::clk(void) |
Jackson_lv | 0:e7513df9d7cb | 58 | { |
Jackson_lv | 0:e7513df9d7cb | 59 | _clk_pin = 0; |
Jackson_lv | 0:e7513df9d7cb | 60 | wait_us(_CLK_PULSE_DELAY); |
Jackson_lv | 0:e7513df9d7cb | 61 | _clk_pin = 1; |
Jackson_lv | 0:e7513df9d7cb | 62 | wait_us(_CLK_PULSE_DELAY); |
Jackson_lv | 0:e7513df9d7cb | 63 | } |
Jackson_lv | 0:e7513df9d7cb | 64 | |
Jackson_lv | 0:e7513df9d7cb | 65 | void ChainableLED::sendByte(uint8_t b) |
Jackson_lv | 0:e7513df9d7cb | 66 | { |
Jackson_lv | 0:e7513df9d7cb | 67 | // Send one bit at a time, starting with the MSB |
Jackson_lv | 0:e7513df9d7cb | 68 | for (uint8_t i=0; i<8; i++) |
Jackson_lv | 0:e7513df9d7cb | 69 | { |
Jackson_lv | 0:e7513df9d7cb | 70 | // If MSB is 1, write one and clock it, else write 0 and clock |
Jackson_lv | 0:e7513df9d7cb | 71 | if ((b & 0x80) != 0) |
Jackson_lv | 0:e7513df9d7cb | 72 | _data_pin = 1; |
Jackson_lv | 0:e7513df9d7cb | 73 | else |
Jackson_lv | 0:e7513df9d7cb | 74 | _data_pin = 0; |
Jackson_lv | 0:e7513df9d7cb | 75 | |
Jackson_lv | 0:e7513df9d7cb | 76 | clk(); |
Jackson_lv | 0:e7513df9d7cb | 77 | |
Jackson_lv | 0:e7513df9d7cb | 78 | // Advance to the next bit to send |
Jackson_lv | 0:e7513df9d7cb | 79 | b <<= 1; |
Jackson_lv | 0:e7513df9d7cb | 80 | } |
Jackson_lv | 0:e7513df9d7cb | 81 | } |
Jackson_lv | 0:e7513df9d7cb | 82 | |
Jackson_lv | 0:e7513df9d7cb | 83 | void ChainableLED::sendColor(uint8_t red, uint8_t green, uint8_t blue) |
Jackson_lv | 0:e7513df9d7cb | 84 | { |
Jackson_lv | 0:e7513df9d7cb | 85 | // Start by sending a uint8_t with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" |
Jackson_lv | 0:e7513df9d7cb | 86 | uint8_t prefix = 0xC0; |
Jackson_lv | 0:e7513df9d7cb | 87 | if ((blue & 0x80) == 0) prefix|= 0x20; |
Jackson_lv | 0:e7513df9d7cb | 88 | if ((blue & 0x40) == 0) prefix|= 0x10; |
Jackson_lv | 0:e7513df9d7cb | 89 | if ((green & 0x80) == 0) prefix|= 0x08; |
Jackson_lv | 0:e7513df9d7cb | 90 | if ((green & 0x40) == 0) prefix|= 0x04; |
Jackson_lv | 0:e7513df9d7cb | 91 | if ((red & 0x80) == 0) prefix|= 0x02; |
Jackson_lv | 0:e7513df9d7cb | 92 | if ((red & 0x40) == 0) prefix|= 0x01; |
Jackson_lv | 0:e7513df9d7cb | 93 | sendByte(prefix); |
Jackson_lv | 0:e7513df9d7cb | 94 | |
Jackson_lv | 0:e7513df9d7cb | 95 | // Now must send the 3 colors |
Jackson_lv | 0:e7513df9d7cb | 96 | sendByte(blue); |
Jackson_lv | 0:e7513df9d7cb | 97 | sendByte(green); |
Jackson_lv | 0:e7513df9d7cb | 98 | sendByte(red); |
Jackson_lv | 0:e7513df9d7cb | 99 | } |
Jackson_lv | 0:e7513df9d7cb | 100 | |
Jackson_lv | 0:e7513df9d7cb | 101 | void ChainableLED::setColorRGB(unsigned int led, uint8_t red, uint8_t green, uint8_t blue) |
Jackson_lv | 0:e7513df9d7cb | 102 | { |
Jackson_lv | 0:e7513df9d7cb | 103 | // Send data frame prefix (32x "0") |
Jackson_lv | 0:e7513df9d7cb | 104 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 105 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 106 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 107 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 108 | |
Jackson_lv | 0:e7513df9d7cb | 109 | // Send color data for each one of the leds |
Jackson_lv | 0:e7513df9d7cb | 110 | for (uint8_t i=0; i<_num_leds; i++) |
Jackson_lv | 0:e7513df9d7cb | 111 | { |
Jackson_lv | 0:e7513df9d7cb | 112 | if (i == led) |
Jackson_lv | 0:e7513df9d7cb | 113 | { |
Jackson_lv | 0:e7513df9d7cb | 114 | _led_state[i*3 + _CL_RED] = red; |
Jackson_lv | 0:e7513df9d7cb | 115 | _led_state[i*3 + _CL_GREEN] = green; |
Jackson_lv | 0:e7513df9d7cb | 116 | _led_state[i*3 + _CL_BLUE] = blue; |
Jackson_lv | 0:e7513df9d7cb | 117 | } |
Jackson_lv | 0:e7513df9d7cb | 118 | |
Jackson_lv | 0:e7513df9d7cb | 119 | sendColor(_led_state[i*3 + _CL_RED], |
Jackson_lv | 0:e7513df9d7cb | 120 | _led_state[i*3 + _CL_GREEN], |
Jackson_lv | 0:e7513df9d7cb | 121 | _led_state[i*3 + _CL_BLUE]); |
Jackson_lv | 0:e7513df9d7cb | 122 | } |
Jackson_lv | 0:e7513df9d7cb | 123 | |
Jackson_lv | 0:e7513df9d7cb | 124 | // Terminate data frame (32x "0") |
Jackson_lv | 0:e7513df9d7cb | 125 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 126 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 127 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 128 | sendByte(0x00); |
Jackson_lv | 0:e7513df9d7cb | 129 | } |
Jackson_lv | 0:e7513df9d7cb | 130 | |
Jackson_lv | 0:e7513df9d7cb | 131 | void ChainableLED::setColorHSB(unsigned int led, float hue, float saturation, float brightness) |
Jackson_lv | 0:e7513df9d7cb | 132 | { |
Jackson_lv | 0:e7513df9d7cb | 133 | float r, g, b; |
Jackson_lv | 0:e7513df9d7cb | 134 | |
Jackson_lv | 0:e7513df9d7cb | 135 | // constrain(hue, 0.0, 1.0); |
Jackson_lv | 0:e7513df9d7cb | 136 | // constrain(saturation, 0.0, 1.0); |
Jackson_lv | 0:e7513df9d7cb | 137 | // constrain(brightness, 0.0, 1.0); |
Jackson_lv | 0:e7513df9d7cb | 138 | |
Jackson_lv | 0:e7513df9d7cb | 139 | if(saturation == 0.0) |
Jackson_lv | 0:e7513df9d7cb | 140 | { |
Jackson_lv | 0:e7513df9d7cb | 141 | r = g = b = brightness; |
Jackson_lv | 0:e7513df9d7cb | 142 | } |
Jackson_lv | 0:e7513df9d7cb | 143 | else |
Jackson_lv | 0:e7513df9d7cb | 144 | { |
Jackson_lv | 0:e7513df9d7cb | 145 | float q = brightness < 0.5 ? |
Jackson_lv | 0:e7513df9d7cb | 146 | brightness * (1.0 + saturation) : brightness + saturation - brightness * saturation; |
Jackson_lv | 0:e7513df9d7cb | 147 | float p = 2.0 * brightness - q; |
Jackson_lv | 0:e7513df9d7cb | 148 | r = hue2rgb(p, q, hue + 1.0/3.0); |
Jackson_lv | 0:e7513df9d7cb | 149 | g = hue2rgb(p, q, hue); |
Jackson_lv | 0:e7513df9d7cb | 150 | b = hue2rgb(p, q, hue - 1.0/3.0); |
Jackson_lv | 0:e7513df9d7cb | 151 | } |
Jackson_lv | 0:e7513df9d7cb | 152 | |
Jackson_lv | 0:e7513df9d7cb | 153 | setColorRGB(led, (uint8_t)(255.0*r), (uint8_t)(255.0*g), (uint8_t)(255.0*b)); |
Jackson_lv | 0:e7513df9d7cb | 154 | } |
Jackson_lv | 0:e7513df9d7cb | 155 | |
Jackson_lv | 0:e7513df9d7cb | 156 | // -------------------------------------------------------------------------------------- |
Jackson_lv | 0:e7513df9d7cb | 157 | |
Jackson_lv | 0:e7513df9d7cb | 158 | float hue2rgb(float p, float q, float t) |
Jackson_lv | 0:e7513df9d7cb | 159 | { |
Jackson_lv | 0:e7513df9d7cb | 160 | if (t < 0.0) |
Jackson_lv | 0:e7513df9d7cb | 161 | t += 1.0; |
Jackson_lv | 0:e7513df9d7cb | 162 | if(t > 1.0) |
Jackson_lv | 0:e7513df9d7cb | 163 | t -= 1.0; |
Jackson_lv | 0:e7513df9d7cb | 164 | if(t < 1.0/6.0) |
Jackson_lv | 0:e7513df9d7cb | 165 | return p + (q - p) * 6.0 * t; |
Jackson_lv | 0:e7513df9d7cb | 166 | if(t < 1.0/2.0) |
Jackson_lv | 0:e7513df9d7cb | 167 | return q; |
Jackson_lv | 0:e7513df9d7cb | 168 | if(t < 2.0/3.0) |
Jackson_lv | 0:e7513df9d7cb | 169 | return p + (q - p) * (2.0/3.0 - t) * 6.0; |
Jackson_lv | 0:e7513df9d7cb | 170 | |
Jackson_lv | 0:e7513df9d7cb | 171 | return p; |
Jackson_lv | 0:e7513df9d7cb | 172 | } |