BLE Color Pixels based on nRF51822 and WS2812B
Dependencies: BLE_API color_pixels mbed nRF51822
Fork of BLE_LCDDemo by
Color pixels library using WS2812B and nRF51822 (16MHz)
You can get the colorful led strip from seeed:
- http://www.seeedstudio.com/depot/Digital-RGB-LED-FlexiStrip-60-LED-1-Meter-p-1666.html
- http://www.seeedstudio.com/depot/WS2812B-Digital-RGB-LED-Waterproof-FlexiStrip-144-LEDmeter-2-meter-p-1869.html
- http://www.seeedstudio.com/depot/WS2812B-RGB-LED-with-Integrated-Driver-Chip-10-PCs-pack-p-1675.html
Click this link to download the color pixels app for android. The source code of the Android app is at https://github.com/Seeed-Studio/ble_color_pixels
If the BLE device is disconnected frequently, we can improve the stability by changing the BLE parameters - Advertising Duration (main.cpp), Min Interval and Max Interval (nRF51822/projectconfig.h)
#define CFG_GAP_CONNECTION_MIN_INTERVAL_MS 20 /**< Minimum acceptable connection interval */ #define CFG_GAP_CONNECTION_MAX_INTERVAL_MS 200 /**< Maximum acceptable connection interval */
main.cpp@7:0e54bd52bd2d, 2015-05-05 (annotated)
- Committer:
- yihui
- Date:
- Tue May 05 05:48:40 2015 +0000
- Revision:
- 7:0e54bd52bd2d
- Parent:
- 4:3ce54cebbdc3
update libraries
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 4:3ce54cebbdc3 | 1 | /* BLE Color Pixels |
rgrover1 | 0:6b62bf1cc2ba | 2 | */ |
rgrover1 | 0:6b62bf1cc2ba | 3 | |
rgrover1 | 0:6b62bf1cc2ba | 4 | #include "mbed.h" |
rgrover1 | 0:6b62bf1cc2ba | 5 | #include "BLEDevice.h" |
yihui | 7:0e54bd52bd2d | 6 | #include "UARTService.h" |
yihui | 4:3ce54cebbdc3 | 7 | #include "color_pixels.h" |
rgrover1 | 0:6b62bf1cc2ba | 8 | |
rgrover1 | 0:6b62bf1cc2ba | 9 | #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; |
rgrover1 | 0:6b62bf1cc2ba | 10 | * it will have an impact on code-size and power consumption. */ |
rgrover1 | 0:6b62bf1cc2ba | 11 | |
rgrover1 | 0:6b62bf1cc2ba | 12 | #if NEED_CONSOLE_OUTPUT |
rgrover1 | 0:6b62bf1cc2ba | 13 | Serial pc(USBTX, USBRX); |
rgrover1 | 0:6b62bf1cc2ba | 14 | #define DEBUG(...) { pc.printf(__VA_ARGS__); } |
rgrover1 | 0:6b62bf1cc2ba | 15 | #else |
rgrover1 | 0:6b62bf1cc2ba | 16 | #define DEBUG(...) /* nothing */ |
rgrover1 | 0:6b62bf1cc2ba | 17 | #endif /* #if NEED_CONSOLE_OUTPUT */ |
rgrover1 | 0:6b62bf1cc2ba | 18 | |
yihui | 4:3ce54cebbdc3 | 19 | ColorPixels pixels(1, 32); |
yihui | 4:3ce54cebbdc3 | 20 | |
rgrover1 | 0:6b62bf1cc2ba | 21 | BLEDevice ble; |
rgrover1 | 0:6b62bf1cc2ba | 22 | DigitalOut led1(LED1); |
rgrover1 | 0:6b62bf1cc2ba | 23 | |
yihui | 7:0e54bd52bd2d | 24 | UARTService *uartServicePtr; |
yihui | 7:0e54bd52bd2d | 25 | |
yihui | 4:3ce54cebbdc3 | 26 | |
yihui | 4:3ce54cebbdc3 | 27 | void processPacket(uint8_t *packet) |
yihui | 4:3ce54cebbdc3 | 28 | { |
yihui | 4:3ce54cebbdc3 | 29 | uint8_t red = packet[0]; |
yihui | 4:3ce54cebbdc3 | 30 | uint8_t green = packet[1]; |
yihui | 4:3ce54cebbdc3 | 31 | uint8_t blue = packet[2]; |
yihui | 4:3ce54cebbdc3 | 32 | |
yihui | 4:3ce54cebbdc3 | 33 | uint8_t mode = packet[3]; |
yihui | 4:3ce54cebbdc3 | 34 | |
yihui | 4:3ce54cebbdc3 | 35 | uint8_t number = packet[4] - 1; |
yihui | 4:3ce54cebbdc3 | 36 | |
yihui | 4:3ce54cebbdc3 | 37 | mode = mode & 1; |
yihui | 4:3ce54cebbdc3 | 38 | |
yihui | 4:3ce54cebbdc3 | 39 | DEBUG("r: %d, g: %d, b: %d, mode: %d\n\r", red, green, blue, mode); |
yihui | 4:3ce54cebbdc3 | 40 | |
yihui | 4:3ce54cebbdc3 | 41 | if (mode == 0) { |
yihui | 4:3ce54cebbdc3 | 42 | pixels.set_color(number, red, green, blue); |
yihui | 4:3ce54cebbdc3 | 43 | pixels.update(); |
yihui | 4:3ce54cebbdc3 | 44 | } else if (mode == 1) { |
yihui | 4:3ce54cebbdc3 | 45 | for (int i = 0; i < 32; i++) { |
yihui | 4:3ce54cebbdc3 | 46 | pixels.set_color(i, red, green, blue); |
yihui | 4:3ce54cebbdc3 | 47 | } |
yihui | 4:3ce54cebbdc3 | 48 | pixels.update(); |
yihui | 4:3ce54cebbdc3 | 49 | } else if (mode == 2) { |
yihui | 4:3ce54cebbdc3 | 50 | |
yihui | 4:3ce54cebbdc3 | 51 | } else { |
yihui | 4:3ce54cebbdc3 | 52 | |
yihui | 4:3ce54cebbdc3 | 53 | } |
yihui | 4:3ce54cebbdc3 | 54 | |
yihui | 4:3ce54cebbdc3 | 55 | } |
rgrover1 | 0:6b62bf1cc2ba | 56 | |
yihui | 7:0e54bd52bd2d | 57 | void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) |
rgrover1 | 0:6b62bf1cc2ba | 58 | { |
rgrover1 | 0:6b62bf1cc2ba | 59 | DEBUG("Disconnected!\n\r"); |
yihui | 7:0e54bd52bd2d | 60 | |
rgrover1 | 0:6b62bf1cc2ba | 61 | DEBUG("Restarting the advertising process\n\r"); |
rgrover1 | 0:6b62bf1cc2ba | 62 | ble.startAdvertising(); |
rgrover1 | 0:6b62bf1cc2ba | 63 | } |
rgrover1 | 0:6b62bf1cc2ba | 64 | |
yihui | 7:0e54bd52bd2d | 65 | void onDataWritten(const GattCharacteristicWriteCBParams *params) |
rgrover1 | 0:6b62bf1cc2ba | 66 | { |
yihui | 7:0e54bd52bd2d | 67 | if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) { |
yihui | 7:0e54bd52bd2d | 68 | uint16_t bytesRead = params->len; |
yihui | 7:0e54bd52bd2d | 69 | DEBUG("received %u bytes\n\r", bytesRead); |
yihui | 7:0e54bd52bd2d | 70 | ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); |
yihui | 7:0e54bd52bd2d | 71 | processPacket((uint8_t *)params->data); |
rgrover1 | 0:6b62bf1cc2ba | 72 | } |
rgrover1 | 0:6b62bf1cc2ba | 73 | } |
rgrover1 | 0:6b62bf1cc2ba | 74 | |
rgrover1 | 0:6b62bf1cc2ba | 75 | void periodicCallback(void) |
rgrover1 | 0:6b62bf1cc2ba | 76 | { |
rgrover1 | 0:6b62bf1cc2ba | 77 | led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ |
rgrover1 | 0:6b62bf1cc2ba | 78 | } |
rgrover1 | 0:6b62bf1cc2ba | 79 | |
rgrover1 | 0:6b62bf1cc2ba | 80 | int main(void) |
rgrover1 | 0:6b62bf1cc2ba | 81 | { |
rgrover1 | 0:6b62bf1cc2ba | 82 | led1 = 1; |
rgrover1 | 0:6b62bf1cc2ba | 83 | Ticker ticker; |
rgrover1 | 0:6b62bf1cc2ba | 84 | ticker.attach(periodicCallback, 1); |
yihui | 4:3ce54cebbdc3 | 85 | |
yihui | 4:3ce54cebbdc3 | 86 | pixels.clear(); |
yihui | 4:3ce54cebbdc3 | 87 | pixels.set_color(0, 255, 0, 0); |
yihui | 4:3ce54cebbdc3 | 88 | pixels.set_color(0, 0, 255, 0); |
yihui | 4:3ce54cebbdc3 | 89 | pixels.set_color(0, 0, 0, 255); |
yihui | 4:3ce54cebbdc3 | 90 | pixels.update(); |
rgrover1 | 0:6b62bf1cc2ba | 91 | |
rgrover1 | 0:6b62bf1cc2ba | 92 | DEBUG("Initialising the nRF51822\n\r"); |
rgrover1 | 0:6b62bf1cc2ba | 93 | ble.init(); |
rgrover1 | 0:6b62bf1cc2ba | 94 | ble.onDisconnection(disconnectionCallback); |
rgrover1 | 0:6b62bf1cc2ba | 95 | ble.onDataWritten(onDataWritten); |
yihui | 7:0e54bd52bd2d | 96 | |
rgrover1 | 0:6b62bf1cc2ba | 97 | /* setup advertising */ |
rgrover1 | 0:6b62bf1cc2ba | 98 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
rgrover1 | 0:6b62bf1cc2ba | 99 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
rgrover1 | 0:6b62bf1cc2ba | 100 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
yihui | 7:0e54bd52bd2d | 101 | (const uint8_t *)"Color Pixels", sizeof("Color Pixels") - 1); |
rgrover1 | 0:6b62bf1cc2ba | 102 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, |
yihui | 7:0e54bd52bd2d | 103 | (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
yihui | 7:0e54bd52bd2d | 104 | |
yihui | 7:0e54bd52bd2d | 105 | ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); |
rgrover1 | 0:6b62bf1cc2ba | 106 | ble.startAdvertising(); |
yihui | 7:0e54bd52bd2d | 107 | |
yihui | 7:0e54bd52bd2d | 108 | UARTService uartService(ble); |
yihui | 7:0e54bd52bd2d | 109 | uartServicePtr = &uartService; |
yihui | 7:0e54bd52bd2d | 110 | |
rgrover1 | 0:6b62bf1cc2ba | 111 | while (true) { |
rgrover1 | 0:6b62bf1cc2ba | 112 | ble.waitForEvent(); |
rgrover1 | 0:6b62bf1cc2ba | 113 | } |
rgrover1 | 0:6b62bf1cc2ba | 114 | } |
yihui | 4:3ce54cebbdc3 | 115 |