This is a library for the DIGI-DOT-BOOSTER which can control LED stripes using the single wire protocol - ws2812 and compatible as well as RGBW LEDs like SK6812. Detailed information including the datasheet and protocol description are available here: http://www.led-genial.de/DIGI-DOT-Booster-WS2812-und-SK6812-ueber-SPI-Schnittstelle-ansteuern DIGI-DOT-BOOSTER acts as a SPI slave and waits for commands sent by a SPI master. This Library provides an easy to use abstraction layer for commands supported by the DD-Booster and adds some additional effects.

Dependents:   DD-Booster-waterdrop BLE_DD-Booster

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DDBooster.cpp Source File

DDBooster.cpp

00001 /*
00002  * DDBoster.cpp - Library to control the Digi-Dot-Booster using a high-level API
00003  *
00004  * https://github.com/Gamadril/DD-Booster-mbed
00005  * MIT License
00006  */
00007 
00008 #include "DDBooster.h"
00009 
00010 #define BOOSTER_CMD_DELAY    500
00011 #define BOOSTER_LED_DELAY    30
00012 
00013 #define BOOSTER_SETRGB       0xA1
00014 #define BOOSTER_SETRGBW      0xA2
00015 #define BOOSTER_SETHSV       0xA3
00016 #define BOOSTER_SETLED       0xA4
00017 #define BOOSTER_SETALL       0xA5
00018 #define BOOSTER_SETRANGE     0xA6
00019 #define BOOSTER_SETRAINBOW   0xA7
00020 #define BOOSTER_GRADIENT     0xA8
00021 
00022 #define BOOSTER_INIT         0xB1
00023 #define BOOSTER_SHOW         0xB2
00024 #define BOOSTER_SHIFTUP      0xB3
00025 #define BOOSTER_SHIFTDOWN    0xB4
00026 #define BOOSTER_COPYLED      0xB5
00027 #define BOOSTER_REPEAT       0xB6
00028 
00029 #define BOOSTER_RGBORDER     0xC1
00030 
00031 DDBooster::DDBooster(PinName MOSI, PinName SCK, PinName CS, PinName RESET)
00032     : _lastIndex(0)
00033     , _device(MOSI, NC, SCK)
00034     , _cs(CS, 1)
00035     , _reset(RESET, 1)
00036 {
00037     _device.format(8,0);
00038     _device.frequency(12000000);
00039 }
00040 
00041 void DDBooster::init(uint16_t ledCount, LedType ledType, LedColorOrder colorOrder)
00042 {
00043     // DD Booster expects the number of LEDs to be an even value (rounded up).
00044     // 256 is defined as 0 to fit in one byte.
00045     if (ledCount > 256) {
00046         ledCount = 256;
00047     }
00048 
00049     _lastIndex = ledCount - 1;
00050 
00051     uint8_t buffer[4];
00052     buffer[0] = BOOSTER_INIT;
00053     buffer[1] = ledCount + (ledCount & 1);
00054     buffer[2] = ledType;
00055     sendRawBytes(buffer, 3);
00056 
00057     if (ledType == LED_RGB && colorOrder != ORDER_GRB) {
00058         buffer[0] = BOOSTER_RGBORDER;
00059         buffer[1] = 3;
00060         buffer[2] = 2;
00061         buffer[3] = 1;
00062         sendRawBytes(buffer, 4);
00063     }
00064 
00065     // a delay after init is not documented, but seems to be necessary
00066     wait_ms(40);
00067 }
00068 
00069 void DDBooster::reset()
00070 {
00071     if (_reset.is_connected()) {
00072         _reset = 0;
00073         wait_ms(100);
00074         _reset = 1;
00075         wait_ms(100);
00076     }
00077 }
00078 
00079 void DDBooster::setRGB(uint8_t r, uint8_t g, uint8_t b)
00080 {
00081     uint8_t cmd[] = {
00082         BOOSTER_SETRGB,
00083         r,
00084         g,
00085         b
00086     };
00087     sendRawBytes(cmd, sizeof (cmd));
00088 }
00089 
00090 void DDBooster::setRGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w)
00091 {
00092     uint8_t cmd[] = {
00093         BOOSTER_SETRGBW,
00094         r,
00095         g,
00096         b,
00097         w
00098     };
00099     sendRawBytes(cmd, sizeof (cmd));
00100 }
00101 
00102 void DDBooster::setHSV(uint16_t h, uint8_t s, uint8_t v)
00103 {
00104     if (h > 359) {
00105         h = 359;
00106     }
00107     uint8_t cmd[] = {
00108         BOOSTER_SETHSV,
00109         h & 0xFF,
00110         h >> 8,
00111         s,
00112         v
00113     };
00114     sendRawBytes(cmd, sizeof (cmd));
00115 }
00116 
00117 void DDBooster::setLED(uint8_t index)
00118 {
00119     if (index > _lastIndex) {
00120         return;
00121     }
00122     uint8_t cmd[] = {
00123         BOOSTER_SETLED,
00124         index
00125     };
00126     sendRawBytes(cmd, sizeof (cmd));
00127 }
00128 
00129 void DDBooster::clearLED(uint8_t index)
00130 {
00131     if (index > _lastIndex) {
00132         return;
00133     }
00134     // optimization by sending two commands in one transaction
00135     uint8_t cmd[] = {
00136         BOOSTER_SETRGB,
00137         0,
00138         0,
00139         0,
00140         BOOSTER_SETLED,
00141         index
00142     };
00143     sendRawBytes(cmd, sizeof (cmd));
00144 }
00145 
00146 void DDBooster::setAll()
00147 {
00148     uint8_t cmd[] = {BOOSTER_SETALL};
00149     sendRawBytes(cmd, sizeof (cmd));
00150 }
00151 
00152 void DDBooster::clearAll()
00153 {
00154     // optimization by sending two commands in one transaction
00155     uint8_t cmd[] = {
00156         BOOSTER_SETRGB,
00157         0,
00158         0,
00159         0,
00160         BOOSTER_SETALL
00161     };
00162     sendRawBytes(cmd, sizeof (cmd));
00163 }
00164 
00165 void DDBooster::setRange(uint8_t start, uint8_t end)
00166 {
00167     if (start > end || end > _lastIndex || start > _lastIndex) {
00168         return;
00169     }
00170     uint8_t cmd[] = {
00171         BOOSTER_SETRANGE,
00172         start,
00173         end
00174     };
00175     sendRawBytes(cmd, sizeof (cmd));
00176 }
00177 
00178 void DDBooster::setRainbow(uint16_t h, uint8_t s, uint8_t v, uint8_t start, uint8_t end, uint8_t step)
00179 {
00180     if (start > end || end > _lastIndex || start > _lastIndex) {
00181         return;
00182     }
00183     if (h > 359) {
00184         h = 359;
00185     }
00186     uint8_t cmd[] = {
00187         BOOSTER_SETRAINBOW,
00188         h & 0xFF,
00189         h >> 8,
00190         s,
00191         v,
00192         start,
00193         end,
00194         step
00195     };
00196     sendRawBytes(cmd, sizeof (cmd));
00197 }
00198 
00199 void DDBooster::setGradient(int start, int end, uint8_t from[3], uint8_t to[3])
00200 {
00201     if (start > end || start > _lastIndex) {
00202         return;
00203     }
00204 
00205     uint8_t steps = end - start;
00206     if (steps == 0) {
00207         setRGB(from[0], from[1], from[2]);
00208         return;
00209     }
00210 
00211     uint8_t s = 0, e = steps;
00212     if (start < 0) {
00213         s = 0 - start;
00214     }
00215     if (end > _lastIndex) {
00216         e -= (end - _lastIndex);
00217     }
00218 
00219     // optimized setRGB(r,g,b) and setLED(start + i) with one transaction and shared memory
00220     uint8_t cmd[6];
00221     cmd[0] = BOOSTER_SETRGB;
00222     cmd[4] = BOOSTER_SETLED;
00223     for (; s <= e; s++) {
00224         cmd[1] = from[0] + (to[0] - from[0]) * s / steps;
00225         cmd[2] = from[1] + (to[1] - from[1]) * s / steps;
00226         cmd[3] = from[2] + (to[2] - from[2]) * s / steps;
00227         cmd[5] = start + s;
00228         sendRawBytes(cmd, sizeof (cmd));
00229     }
00230 }
00231 
00232 void DDBooster::shiftUp(uint8_t start, uint8_t end, uint8_t count)
00233 {
00234     if (start > end || end > _lastIndex || start > _lastIndex) {
00235         return;
00236     }
00237     uint8_t cmd[4] = {
00238         BOOSTER_SHIFTDOWN,
00239         start,
00240         end,
00241         count
00242     };
00243     sendRawBytes(cmd, sizeof (cmd));
00244 }
00245 
00246 void DDBooster::shiftDown(uint8_t start, uint8_t end, uint8_t count)
00247 {
00248     if (start > end || end > _lastIndex || start > _lastIndex) {
00249         return;
00250     }
00251     uint8_t cmd[4] = {
00252         BOOSTER_SHIFTDOWN,
00253         start,
00254         end,
00255         count
00256     };
00257     sendRawBytes(cmd, sizeof (cmd));
00258 }
00259 
00260 void DDBooster::copyLED(uint8_t from, uint8_t to)
00261 {
00262     if (from > _lastIndex || to > _lastIndex) {
00263         return;
00264     }
00265     uint8_t cmd[] = {
00266         BOOSTER_COPYLED,
00267         from,
00268         to
00269     };
00270     sendRawBytes(cmd, sizeof (cmd));
00271 }
00272 
00273 void DDBooster::repeat(uint8_t start, uint8_t end, uint8_t count)
00274 {
00275     if (start > end || end > _lastIndex || start > _lastIndex) {
00276         return;
00277     }
00278     uint8_t cmd[] = {
00279         BOOSTER_REPEAT,
00280         start,
00281         end,
00282         count
00283     };
00284     sendRawBytes(cmd, sizeof (cmd));
00285 }
00286 
00287 void DDBooster::show()
00288 {
00289     uint8_t cmd[] = {BOOSTER_SHOW};
00290     sendRawBytes(cmd, sizeof (cmd));
00291     wait_us(BOOSTER_LED_DELAY * (_lastIndex + 1));
00292 }
00293 
00294 void DDBooster::sendRawBytes(const uint8_t *buffer, uint8_t length)
00295 {
00296     _cs = 0;
00297     for (int i = 0; i < length; i++) {
00298         _device.write(buffer[i]);
00299     }
00300     _cs = 1;
00301     wait_us(BOOSTER_CMD_DELAY);
00302 }