diff options
Diffstat (limited to 'arduino/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino')
-rwxr-xr-x | arduino/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/arduino/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino new file mode 100755 index 0000000..f016a29 --- /dev/null +++ b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/neopixel/neopixel.ino @@ -0,0 +1,350 @@ +/********************************************************************* + This is an example for our nRF52 based Bluefruit LE modules + + Pick one up today in the adafruit shop! + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + MIT license, check LICENSE for more information + All text above, and the splash screen below must be included in + any redistribution +*********************************************************************/ + +// This sketch is intended to be used with the NeoPixel control +// surface in Adafruit's Bluefruit LE Connect mobile application. +// +// - Compile and flash this sketch to the nRF52 Feather +// - Open the Bluefruit LE Connect app +// - Switch to the NeoPixel utility +// - Click the 'connect' button to establish a connection and +// send the meta-data about the pixel layout +// - Use the NeoPixel utility to update the pixels on your device + +/* NOTE: This sketch required at least version 1.1.0 of Adafruit_Neopixel !!! */ + +#include <Arduino.h> +#include <Adafruit_NeoPixel.h> +#include <bluefruit.h> + +#define NEOPIXEL_VERSION_STRING "Neopixel v2.0" +#define PIN 30 /* Pin used to drive the NeoPixels */ + +#define MAXCOMPONENTS 4 +uint8_t *pixelBuffer = NULL; +uint8_t width = 0; +uint8_t height = 0; +uint8_t stride; +uint8_t componentsValue; +bool is400Hz; +uint8_t components = 3; // only 3 and 4 are valid values + +Adafruit_NeoPixel neopixel = Adafruit_NeoPixel(); + +// BLE Service +BLEDis bledis; +BLEUart bleuart; + +void setup() +{ + Serial.begin(115200); + while ( !Serial ) delay(10); // for nrf52840 with native usb + + Serial.println("Adafruit Bluefruit Neopixel Test"); + Serial.println("--------------------------------"); + + Serial.println(); + Serial.println("Please connect using the Bluefruit Connect LE application"); + + // Config Neopixels + neopixel.begin(); + + // Init Bluefruit + Bluefruit.begin(); + // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 + Bluefruit.setTxPower(4); + Bluefruit.setName("Bluefruit52"); + Bluefruit.setConnectCallback(connect_callback); + + // Configure and Start Device Information Service + bledis.setManufacturer("Adafruit Industries"); + bledis.setModel("Bluefruit Feather52"); + bledis.begin(); + + // Configure and start BLE UART service + bleuart.begin(); + + // Set up and start advertising + startAdv(); +} + +void startAdv(void) +{ + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + + // Include bleuart 128-bit uuid + Bluefruit.Advertising.addService(bleuart); + + // Secondary Scan Response packet (optional) + // Since there is no room for 'Name' in Advertising packet + Bluefruit.ScanResponse.addName(); + + /* Start Advertising + * - Enable auto advertising if disconnected + * - Interval: fast mode = 20 ms, slow mode = 152.5 ms + * - Timeout for fast mode is 30 seconds + * - Start(timeout) with timeout = 0 will advertise forever (until connected) + * + * For recommended advertising interval + * https://developer.apple.com/library/content/qa/qa1931/_index.html + */ + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds +} + +void connect_callback(uint16_t conn_handle) +{ + char central_name[32] = { 0 }; + Bluefruit.Gap.getPeerName(conn_handle, central_name, sizeof(central_name)); + + Serial.print("Connected to "); + Serial.println(central_name); + + Serial.println("Please select the 'Neopixels' tab, click 'Connect' and have fun"); +} + +void loop() +{ + // Echo received data + if ( Bluefruit.connected() && bleuart.notifyEnabled() ) + { + int command = bleuart.read(); + + switch (command) { + case 'V': { // Get Version + commandVersion(); + break; + } + + case 'S': { // Setup dimensions, components, stride... + commandSetup(); + break; + } + + case 'C': { // Clear with color + commandClearColor(); + break; + } + + case 'B': { // Set Brightness + commandSetBrightness(); + break; + } + + case 'P': { // Set Pixel + commandSetPixel(); + break; + } + + case 'I': { // Receive new image + commandImage(); + break; + } + + } + } +} + +void swapBuffers() +{ + uint8_t *base_addr = pixelBuffer; + int pixelIndex = 0; + for (int j = 0; j < height; j++) + { + for (int i = 0; i < width; i++) { + if (components == 3) { + neopixel.setPixelColor(pixelIndex, neopixel.Color(*base_addr, *(base_addr+1), *(base_addr+2))); + } + else { + neopixel.setPixelColor(pixelIndex, neopixel.Color(*base_addr, *(base_addr+1), *(base_addr+2), *(base_addr+3) )); + } + base_addr+=components; + pixelIndex++; + } + pixelIndex += stride - width; // Move pixelIndex to the next row (take into account the stride) + } + neopixel.show(); + +} + +void commandVersion() { + Serial.println(F("Command: Version check")); + sendResponse(NEOPIXEL_VERSION_STRING); +} + +void commandSetup() { + Serial.println(F("Command: Setup")); + + width = bleuart.read(); + height = bleuart.read(); + stride = bleuart.read(); + componentsValue = bleuart.read(); + is400Hz = bleuart.read(); + + neoPixelType pixelType; + pixelType = componentsValue + (is400Hz ? NEO_KHZ400 : NEO_KHZ800); + + components = (componentsValue == NEO_RGB || componentsValue == NEO_RBG || componentsValue == NEO_GRB || componentsValue == NEO_GBR || componentsValue == NEO_BRG || componentsValue == NEO_BGR) ? 3:4; + + Serial.printf("\tsize: %dx%d\n", width, height); + Serial.printf("\tstride: %d\n", stride); + Serial.printf("\tpixelType %d\n", pixelType); + Serial.printf("\tcomponents: %d\n", components); + + if (pixelBuffer != NULL) { + delete[] pixelBuffer; + } + + uint32_t size = width*height; + pixelBuffer = new uint8_t[size*components]; + neopixel.updateLength(size); + neopixel.updateType(pixelType); + neopixel.setPin(PIN); + + // Done + sendResponse("OK"); +} + +void commandSetBrightness() { + Serial.println(F("Command: SetBrightness")); + + // Read value + uint8_t brightness = bleuart.read(); + + // Set brightness + neopixel.setBrightness(brightness); + + // Refresh pixels + swapBuffers(); + + // Done + sendResponse("OK"); +} + +void commandClearColor() { + Serial.println(F("Command: ClearColor")); + + // Read color + uint8_t color[MAXCOMPONENTS]; + for (int j = 0; j < components;) { + if (bleuart.available()) { + color[j] = bleuart.read(); + j++; + } + } + + // Set all leds to color + int size = width * height; + uint8_t *base_addr = pixelBuffer; + for (int i = 0; i < size; i++) { + for (int j = 0; j < components; j++) { + *base_addr = color[j]; + base_addr++; + } + } + + // Swap buffers + Serial.println(F("ClearColor completed")); + swapBuffers(); + + + if (components == 3) { + Serial.printf("\tclear (%d, %d, %d)\n", color[0], color[1], color[2] ); + } + else { + Serial.printf("\tclear (%d, %d, %d, %d)\n", color[0], color[1], color[2], color[3] ); + } + + // Done + sendResponse("OK"); +} + +void commandSetPixel() { + Serial.println(F("Command: SetPixel")); + + // Read position + uint8_t x = bleuart.read(); + uint8_t y = bleuart.read(); + + // Read colors + uint32_t pixelOffset = y*width+x; + uint32_t pixelDataOffset = pixelOffset*components; + uint8_t *base_addr = pixelBuffer+pixelDataOffset; + for (int j = 0; j < components;) { + if (bleuart.available()) { + *base_addr = bleuart.read(); + base_addr++; + j++; + } + } + + // Set colors + uint32_t neopixelIndex = y*stride+x; + uint8_t *pixelBufferPointer = pixelBuffer + pixelDataOffset; + uint32_t color; + if (components == 3) { + color = neopixel.Color( *pixelBufferPointer, *(pixelBufferPointer+1), *(pixelBufferPointer+2) ); + Serial.printf("\tcolor (%d, %d, %d)\n",*pixelBufferPointer, *(pixelBufferPointer+1), *(pixelBufferPointer+2) ); + } + else { + color = neopixel.Color( *pixelBufferPointer, *(pixelBufferPointer+1), *(pixelBufferPointer+2), *(pixelBufferPointer+3) ); + Serial.printf("\tcolor (%d, %d, %d, %d)\n", *pixelBufferPointer, *(pixelBufferPointer+1), *(pixelBufferPointer+2), *(pixelBufferPointer+3) ); + } + neopixel.setPixelColor(neopixelIndex, color); + neopixel.show(); + + // Done + sendResponse("OK"); +} + +void commandImage() { + Serial.printf("Command: Image %dx%d, %d, %d\n", width, height, components, stride); + + // Receive new pixel buffer + int size = width * height; + uint8_t *base_addr = pixelBuffer; + for (int i = 0; i < size; i++) { + for (int j = 0; j < components;) { + if (bleuart.available()) { + *base_addr = bleuart.read(); + base_addr++; + j++; + } + } + +/* + if (components == 3) { + uint32_t index = i*components; + Serial.printf("\tp%d (%d, %d, %d)\n", i, pixelBuffer[index], pixelBuffer[index+1], pixelBuffer[index+2] ); + } + */ + } + + // Swap buffers + Serial.println(F("Image received")); + swapBuffers(); + + // Done + sendResponse("OK"); +} + +void sendResponse(char const *response) { + Serial.printf("Send Response: %s\n", response); + bleuart.write(response, strlen(response)*sizeof(char)); +} + |