Change protocol to protobuf + SLIP

This commit is contained in:
Patrick Moessler 2019-10-16 23:03:18 +02:00
parent 8da1adcb9b
commit 8c6a205efd
2 changed files with 526 additions and 307 deletions

View file

@ -1,4 +0,0 @@
#include <pb.h>
#include <pb_decode.h>
#include <fx.pb.h>

View file

@ -1,9 +1,13 @@
#include <Arduino.h> #include <Arduino.h>
#include <WS2812FX.h> #include <WS2812FX.h>
#include <bluefruit.h> #include <bluefruit.h>
#include "uartproto.h" #include <cstdint>
#include <fx.pb.h>
#include <pb.h>
#include <pb_decode.h>
#include <slip/Stream.h>
#define NEOPIXEL_VERSION_STRING "Neopixel v2.0" #define NEOPIXEL_VERSION_STRING "BLEtail 1.0"
#define PIN 30 /* Pin used to drive the NeoPixels */ #define PIN 30 /* Pin used to drive the NeoPixels */
#define MAXCOMPONENTS 4 #define MAXCOMPONENTS 4
@ -22,22 +26,16 @@ BLEDfu bledfu;
BLEDis bledis; BLEDis bledis;
BLEUart bleuart; BLEUart bleuart;
// framing
packetio::SLIPStream bleslip(bleuart);
void startAdv(void); void startAdv(void);
void connect_callback(uint16_t conn_handle); void connect_callback(uint16_t conn_handle);
void swapBuffers();
void commandVersion();
void commandSetup();
void commandSetBrightness();
void commandSetSpeed();
void commandSetMode();
void commandClearColor();
void commandSetPixel();
void commandImage();
void commandHalt(); void commandHalt();
void sendResponse(char const *); void sendResponse(char const *);
void dispatch(fx_Root &fx);
void setup() void setup() {
{
Serial.begin(115200); Serial.begin(115200);
while (!Serial) while (!Serial)
delay(10); // for nrf52840 with native usb delay(10); // for nrf52840 with native usb
@ -46,28 +44,14 @@ void setup()
Serial.println("--------------------------------"); Serial.println("--------------------------------");
Serial.println(); Serial.println();
Serial.println("Please connect using the Bluefruit Connect LE application"); Serial.println("Please connect using the BLEtail application");
// Config Neopixels // Config Neopixels
ws2812fx.init(); ws2812fx.init();
ws2812fx.setLength(40); ws2812fx.setLength(40);
ws2812fx.setBrightness(50); ws2812fx.setBrightness(10);
ws2812fx.setSpeed(200); ws2812fx.setSpeed(0x1000);
// ws2812fx.setMode(FX_MODE_RAINBOW); ws2812fx.setMode(FX_MODE_RAINBOW);
// ws2812fx.setNumSegments(5);
// ws2812fx.setSegment(0, 0*(40/5), 1*(40/5)-1, FX_MODE_RAINBOW_CYCLE, RED, 200, false);
// ws2812fx.setSegment(1, 1*(40/5), 2*(40/5)-1, FX_MODE_STATIC, BLACK, 200, false);
// ws2812fx.setSegment(2, 2*(40/5), 3*(40/5)-1, FX_MODE_RAINBOW_CYCLE, RED, 200, REVERSE);
// ws2812fx.setSegment(4, 3*(40/5), 4*(40/5)-1, FX_MODE_STATIC, BLACK, 200, false);
// ws2812fx.setSegment(5, 4*(40/5), 5*(40/5)-1, FX_MODE_RAINBOW_CYCLE, GREEN, 200, false);
// ws2812fx.setSegment(0, 0 * (40 / 5), 1 * (40 / 5) - 1, FX_MODE_COLOR_WIPE, YELLOW, 400, false);
// ws2812fx.setSegment(1, 1 * (40 / 5), 2 * (40 / 5) - 1, FX_MODE_COLOR_WIPE, YELLOW, 400, false);
// ws2812fx.setSegment(2, 2 * (40 / 5), 3 * (40 / 5) - 1, FX_MODE_STATIC, BLACK, 200, REVERSE);
// ws2812fx.setSegment(4, 3 * (40 / 5), 4 * (40 / 5) - 1, FX_MODE_FADE, YELLOW, 800, false);
// ws2812fx.setSegment(5, 4 * (40 / 5), 5 * (40 / 5) - 1, FX_MODE_FADE, YELLOW, 800, false);
ws2812fx.start(); ws2812fx.start();
@ -92,8 +76,7 @@ void setup()
startAdv(); startAdv();
} }
void startAdv(void) void startAdv(void) {
{
// Advertising packet // Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower(); Bluefruit.Advertising.addTxPower();
@ -120,8 +103,7 @@ void startAdv(void)
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
} }
void connect_callback(uint16_t conn_handle) void connect_callback(uint16_t conn_handle) {
{
// Get the reference to current connection // Get the reference to current connection
BLEConnection *connection = Bluefruit.Connection(conn_handle); BLEConnection *connection = Bluefruit.Connection(conn_handle);
@ -130,327 +112,569 @@ void connect_callback(uint16_t conn_handle)
Serial.print("Connected to "); Serial.print("Connected to ");
Serial.println(central_name); Serial.println(central_name);
Serial.println("Please select the 'Neopixels' tab, click 'Connect' and have fun");
} }
void loop() uint8_t parseOptions(const fx_Options &opts) {
{ uint8_t o = 0;
// Echo received data if (opts.reverse) {
if (Bluefruit.connected() && bleuart.notifyEnabled()) o |= REVERSE;
{ }
int command = bleuart.read(); if (opts.gammaCorrect) {
o |= GAMMA;
}
o |= (opts.fadeRate << 4);
o |= (opts.size << 1);
return o;
}
switch (command) uint32_t colorFromRGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
{ return ((uint32_t)w) << 24 | ((uint32_t)r) << 16 | ((uint32_t)g) << 8 |
case 'V': ((uint32_t)b);
{ // Get Version }
commandVersion();
break;
}
case 'S': static bool pb_stream_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) {
{ // Setup dimensions, components, stride... Stream *s = reinterpret_cast<Stream *>(stream->state);
commandSetup(); int c = s->read();
break; if (c >= 0) {
*buf = c;
// Serial.print("rx:");
// Serial.println(c);
} else if (c == packetio::PacketStream::EOP) {
stream->bytes_left = 0;
// Serial.println("eop");
reinterpret_cast<packetio::SLIPStream *>(stream->state)->next();
return false;
} else if (c == packetio::PacketStream::EOF) {
if(stream->bytes_left == 0){
stream->bytes_left = SIZE_MAX;
} }
// ignore. will be called again
} else {
Serial.print("err:");
Serial.println(c);
}
return true;
};
case 'C': pb_istream_s as_pb_istream(Stream &s) {
{ // Clear with color return {pb_stream_read, &s, SIZE_MAX};
commandClearColor(); };
break;
}
case 'B': pb_istream_s pb_in = as_pb_istream(bleslip);
{ // Set Brightness
commandSetBrightness();
break;
}
case 'M':
{ // Set Mode
commandSetMode();
break;
}
case 's':
{ // Set Speed
commandSetSpeed();
break;
}
case 'P': void loop() {
{ // Set Pixel if (Bluefruit.connected() && bleuart.notifyEnabled()) {
commandSetPixel(); fx_Root fx = fx_Root_init_zero;
break; if (pb_decode(&pb_in, fx_Root_fields, &fx)) {
} Serial.print("pb decode:");
Serial.println(fx.which_msg);
case 'I': dispatch(fx);
{ // Receive new image pb_in = as_pb_istream(bleslip); // reset stream for next packet
commandImage();
break;
}
case 'H':
{ // Receive new image
commandHalt();
break;
} }
} }
}
ws2812fx.service(); ws2812fx.service();
} }
void swapBuffers() void dispatch(fx_Root &fx) {
{ // switch (fx.which_msg) {
uint8_t *base_addr = pixelBuffer; // case fx_Root_start_tag: {
int pixelIndex = 0; // ws2812fx.start();
for (int j = 0; j < height; j++) // break;
{ // }
for (int i = 0; i < width; i++) // case fx_Root_stop_tag: {
{ // ws2812fx.stop();
if (components == 3) // break;
{ // }
ws2812fx.setPixelColor(pixelIndex, ws2812fx.Color(*base_addr, *(base_addr + 1), *(base_addr + 2))); // case fx_Root_pause_tag: {
} // ws2812fx.pause();
else // break;
{ // }
ws2812fx.setPixelColor(pixelIndex, ws2812fx.Color(*base_addr, *(base_addr + 1), *(base_addr + 2), *(base_addr + 3))); // case fx_Root_resume_tag: {
} // ws2812fx.resume();
base_addr += components; // break;
pixelIndex++; // }
} // case fx_Root_strip_off_tag: {
pixelIndex += stride - width; // Move pixelIndex to the next row (take into account the stride) // ws2812fx.strip_off();
} // break;
ws2812fx.show(); // }
} // case fx_Root_fade_out_tag: {
// if (fx.msg.fade_out.has_fadeTime) {
void commandVersion() // ws2812fx.fade_out(fx.msg.fade_out.fadeTime);
{ // } else {
Serial.println(F("Command: Version check")); // ws2812fx.fade_out();
sendResponse(NEOPIXEL_VERSION_STRING); // }
} // break;
// }
void commandSetup() // case fx_Root_setMode_tag: {
{ // if (fx.msg.setMode.has_segment) {
Serial.println(F("Command: Setup")); // ws2812fx.setMode(static_cast<uint8_t>(fx.msg.setMode.mode));
// } else {
ws2812fx.stop(); // ws2812fx.setMode(static_cast<uint8_t>(fx.msg.setMode.segment),
// static_cast<uint8_t>(fx.msg.setMode.mode));
width = bleuart.read(); // }
height = bleuart.read(); // break;
stride = bleuart.read(); // }
componentsValue = bleuart.read(); // case fx_Root_setOptions_tag: {
is400Hz = bleuart.read(); // ws2812fx.setOptions(fx.msg.setOptions.segment,
// parseOptions(fx.msg.setOptions.options));
neoPixelType pixelType; // break;
pixelType = componentsValue + (is400Hz ? NEO_KHZ400 : NEO_KHZ800); // }
// case fx_Root_setSpeed_tag: {
components = (componentsValue == NEO_RGB || componentsValue == NEO_RBG || componentsValue == NEO_GRB || componentsValue == NEO_GBR || componentsValue == NEO_BRG || componentsValue == NEO_BGR) ? 3 : 4; // if (fx.msg.setSpeed.has_segment) {
// ws2812fx.setSpeed(static_cast<uint8_t>(fx.msg.setSpeed.speed));
Serial.printf("\tsize: %dx%d\n", width, height); // } else {
Serial.printf("\tstride: %d\n", stride); // ws2812fx.setSpeed(static_cast<uint8_t>(fx.msg.setSpeed.segment),
Serial.printf("\tpixelType %d\n", pixelType); // static_cast<uint8_t>(fx.msg.setSpeed.speed));
Serial.printf("\tcomponents: %d\n", components); // }
// break;
if (pixelBuffer != NULL) // }
{ // case fx_Root_increaseSpeed_tag: {
delete[] pixelBuffer; // ws2812fx.increaseSpeed(fx.msg.increaseSpeed.step);
} // break;
// }
uint32_t size = width * height; // case fx_Root_decreaseSpeed_tag: {
pixelBuffer = new uint8_t[size * components]; // ws2812fx.decreaseSpeed(fx.msg.decreaseSpeed.step);
ws2812fx.updateLength(size); // break;
ws2812fx.updateType(pixelType); // }
ws2812fx.setPin(PIN); // case fx_Root_setColor_tag: {
// switch (fx.msg.setColor.color.which_colorTypes) {
ws2812fx.start(); // case fx_ColorType_rgb_tag: {
// ws2812fx.setColor(fx.msg.setColor.color.colorTypes.rgb.r,
// Done // fx.msg.setColor.color.colorTypes.rgb.b,
sendResponse("OK"); // fx.msg.setColor.color.colorTypes.rgb.g);
} // break;
// }
void commandSetBrightness() // case fx_ColorType_rgbw_tag: {
{ // ws2812fx.setColor(fx.msg.setColor.color.colorTypes.rgbw.r,
Serial.println(F("Command: SetBrightness")); // fx.msg.setColor.color.colorTypes.rgbw.b,
// fx.msg.setColor.color.colorTypes.rgbw.g,
// Read value // fx.msg.setColor.color.colorTypes.rgbw.w);
uint8_t brightness = bleuart.read(); // break;
// }
// Set brightness // case fx_ColorType_color_tag: {
ws2812fx.setBrightness(brightness); // if (fx.msg.setColor.has_segment) {
// ws2812fx.setColor(fx.msg.setColor.segment,
// Refresh pixels // fx.msg.setColor.color.colorTypes.color);
// swapBuffers(); // } else {
// ws2812fx.setColor(fx.msg.setColor.color.colorTypes.color);
// Done // }
sendResponse("OK"); // break;
} // }
// case fx_ColorType_multiColor_tag: {
void commandSetMode() // uint32_t colors[NUM_COLORS] = {
{ // fx.msg.setColor.color.colorTypes.multiColor.col1,
Serial.println(F("Command: SetMode")); // fx.msg.setColor.color.colorTypes.multiColor.col2,
// fx.msg.setColor.color.colorTypes.multiColor.col3};
// Read value // if (fx.msg.setColor.has_segment) {
uint8_t mode = bleuart.read(); // ws2812fx.setColors(fx.msg.setColor.segment, colors);
// } else {
// Set mode // ws2812fx.setColors(0, colors);
ws2812fx.setMode(mode); // }
ws2812fx.resume(); // break;
// }
// Done // }
sendResponse("OK"); // break;
} // }
// case fx_Root_setBrightness_tag: {
void commandSetSpeed() // ws2812fx.setBrightness(fx.msg.setBrightness.brightness);
{ // break;
Serial.println(F("Command: SetSpeed")); // }
// case fx_Root_increaseBrightness_tag: {
// Read value // ws2812fx.increaseBrightness(fx.msg.increaseBrightness.step);
uint16_t speed = (bleuart.read() << 8) | bleuart.read(); // break;
// }
// Set speed // case fx_Root_decreaseBrightness_tag: {
ws2812fx.setSpeed(speed); // ws2812fx.decreaseBrightness(fx.msg.decreaseBrightness.step);
ws2812fx.resume(); // break;
// }
// Done // case fx_Root_setLength_tag: {
sendResponse("OK"); // ws2812fx.setLength(fx.msg.setLength.numPixels);
} // break;
// }
void commandClearColor() // case fx_Root_increaseLength_tag: {
{ // ws2812fx.increaseLength(fx.msg.increaseLength.step);
Serial.println(F("Command: ClearColor")); // break;
// }
// Read color // case fx_Root_decreaseLength_tag: {
uint8_t color[MAXCOMPONENTS]; // ws2812fx.decreaseLength(fx.msg.decreaseLength.step);
for (int j = 0; j < components;) // break;
{ // }
if (bleuart.available()) // case fx_Root_trigger_tag: {
{ // ws2812fx.trigger();
color[j] = bleuart.read(); // break;
j++; // }
} // case fx_Root_setNumSegments_tag: {
} // ws2812fx.setNumSegments(fx.msg.setNumSegments.numSegments);
// break;
ws2812fx.setMode(FX_MODE_STATIC); // }
ws2812fx.setColor(*(reinterpret_cast<uint32_t *>(color))); // case fx_Root_setSegment_tag: {
// switch (fx.msg.setSegment.color.which_colorTypes) {
// Set all leds to color // case fx_ColorType_rgb_tag: {
// int size = width * height; // ws2812fx.setSegment(
// uint8_t *base_addr = pixelBuffer; // fx.msg.setSegment.segment, fx.msg.setSegment.start,
// for (int i = 0; i < size; i++) // fx.msg.setSegment.end, fx.msg.setSegment.mode,
// { // colorFromRGBW(fx.msg.setSegment.color.colorTypes.rgb.r,
// // ws2812fx.setPixelColor(i, *(reinterpret_cast<uint32_t*>(color))); // fx.msg.setSegment.color.colorTypes.rgb.g,
// for (int j = 0; j < components; j++) // fx.msg.setSegment.color.colorTypes.rgb.b, 0),
// { // fx.msg.setSegment.speed,
// *base_addr = color[j]; // parseOptions(fx.msg.setSegment.options));
// base_addr++; // break;
// }
// case fx_ColorType_rgbw_tag: {
// ws2812fx.setSegment(
// fx.msg.setSegment.segment, fx.msg.setSegment.start,
// fx.msg.setSegment.end, fx.msg.setSegment.mode,
// colorFromRGBW(fx.msg.setSegment.color.colorTypes.rgbw.r,
// fx.msg.setSegment.color.colorTypes.rgbw.g,
// fx.msg.setSegment.color.colorTypes.rgbw.b,
// fx.msg.setSegment.color.colorTypes.rgbw.w),
// fx.msg.setSegment.speed,
// parseOptions(fx.msg.setSegment.options));
// break;
// }
// case fx_ColorType_color_tag: {
// ws2812fx.setSegment(
// fx.msg.setSegment.segment, fx.msg.setSegment.start,
// fx.msg.setSegment.end, fx.msg.setSegment.mode,
// fx.msg.setSegment.color.colorTypes.color,
// fx.msg.setSegment.speed,
// parseOptions(fx.msg.setSegment.options));
// break;
// }
// case fx_ColorType_multiColor_tag: {
// uint32_t colors[NUM_COLORS] = {
// fx.msg.setSegment.color.colorTypes.multiColor.col1,
// fx.msg.setSegment.color.colorTypes.multiColor.col2,
// fx.msg.setSegment.color.colorTypes.multiColor.col3};
// ws2812fx.setSegment(
// fx.msg.setSegment.segment, fx.msg.setSegment.start,
// fx.msg.setSegment.end, fx.msg.setSegment.mode, colors,
// fx.msg.setSegment.speed,
// parseOptions(fx.msg.setSegment.options));
// break;
// }
// }
// break;
// }
// case fx_Root_resetSegments_tag: {
// ws2812fx.resetSegments();
// break;
// }
// case fx_Root_resetSegmentRuntimes_tag: {
// ws2812fx.resetSegmentRuntimes();
// break;
// }
// case fx_Root_resetSegmentRuntime_tag: {
// ws2812fx.resetSegmentRuntime(fx.msg.resetSegmentRuntime.segment);
// break;
// }
// case fx_Root_setPixelColor_tag: {
// switch (fx.msg.setPixelColor.color.which_colorTypes) {
// case fx_ColorType_rgb_tag: {
// ws2812fx.setPixelColor(fx.msg.setPixelColor.offset,
// fx.msg.setPixelColor.color.colorTypes.rgb.r,
// fx.msg.setPixelColor.color.colorTypes.rgb.b,
// fx.msg.setPixelColor.color.colorTypes.rgb.g);
// break;
// }
// case fx_ColorType_rgbw_tag: {
// ws2812fx.setPixelColor(fx.msg.setPixelColor.offset,
// fx.msg.setPixelColor.color.colorTypes.rgbw.r,
// fx.msg.setPixelColor.color.colorTypes.rgbw.b,
// fx.msg.setPixelColor.color.colorTypes.rgbw.g,
// fx.msg.setPixelColor.color.colorTypes.rgbw.w);
// break;
// }
// case fx_ColorType_color_tag: {
// ws2812fx.setPixelColor(fx.msg.setPixelColor.offset,
// fx.msg.setPixelColor.color.colorTypes.color);
// break;
// }
// }
// break;
// }
// case fx_Root_copyPixels_tag: {
// ws2812fx.copyPixels(fx.msg.copyPixels.destination,
// fx.msg.copyPixels.source,
// fx.msg.copyPixels.count);
// break;
// }
// case fx_Root_display_tag: {
// break;
// }
// case fx_Root_show_tag: {
// ws2812fx.show();
// break;
// }
// case fx_Root_halt_tag: {
// commandHalt();
// break;
// } // }
// } // }
// 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() // void swapBuffers()
{ // {
Serial.println(F("Command: SetPixel")); // 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)
// {
// ws2812fx.setPixelColor(pixelIndex, ws2812fx.Color(*base_addr,
// *(base_addr + 1), *(base_addr + 2)));
// }
// else
// {
// ws2812fx.setPixelColor(pixelIndex, ws2812fx.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)
// }
// ws2812fx.show();
// }
// Read position // void commandVersion()
uint8_t x = bleuart.read(); // {
uint8_t y = bleuart.read(); // Serial.println(F("Command: Version check"));
// sendResponse(NEOPIXEL_VERSION_STRING);
// }
// Read colors // void commandSetup()
uint32_t pixelOffset = y * width + x; // {
uint32_t pixelDataOffset = pixelOffset * components; // Serial.println(F("Command: Setup"));
uint8_t *base_addr = pixelBuffer + pixelDataOffset;
for (int j = 0; j < components;)
{
if (bleuart.available())
{
*base_addr = bleuart.read();
base_addr++;
j++;
}
}
// Set colors // ws2812fx.stop();
uint32_t ws2812fxIndex = y * stride + x;
uint8_t *pixelBufferPointer = pixelBuffer + pixelDataOffset;
uint32_t color;
if (components == 3)
{
color = ws2812fx.Color(*pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2));
Serial.printf("\tcolor (%d, %d, %d)\n", *pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2));
}
else
{
color = ws2812fx.Color(*pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2), *(pixelBufferPointer + 3));
Serial.printf("\tcolor (%d, %d, %d, %d)\n", *pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2), *(pixelBufferPointer + 3));
}
ws2812fx.pause();
ws2812fx.setPixelColor(ws2812fxIndex, color);
ws2812fx.show();
// Done // width = bleuart.read();
sendResponse("OK"); // height = bleuart.read();
} // stride = bleuart.read();
// componentsValue = bleuart.read();
// is400Hz = bleuart.read();
void commandImage() // neoPixelType pixelType;
{ // pixelType = componentsValue + (is400Hz ? NEO_KHZ400 : NEO_KHZ800);
Serial.printf("Command: Image %dx%d, %d, %d\n", width, height, components, stride);
ws2812fx.pause(); // components = (componentsValue == NEO_RGB || componentsValue == NEO_RBG ||
// componentsValue == NEO_GRB || componentsValue == NEO_GBR || componentsValue
// == NEO_BRG || componentsValue == NEO_BGR) ? 3 : 4;
// Receive new pixel buffer // Serial.printf("\tsize: %dx%d\n", width, height);
int size = width * height; // Serial.printf("\tstride: %d\n", stride);
uint8_t *base_addr = pixelBuffer; // Serial.printf("\tpixelType %d\n", pixelType);
for (int i = 0; i < size; i++) // Serial.printf("\tcomponents: %d\n", components);
{
for (int j = 0; j < components;)
{
if (bleuart.available())
{
*base_addr = bleuart.read();
base_addr++;
j++;
}
}
/* // if (pixelBuffer != NULL)
if (components == 3) { // {
uint32_t index = i*components; // delete[] pixelBuffer;
Serial.printf("\tp%d (%d, %d, %d)\n", i, pixelBuffer[index], pixelBuffer[index+1], pixelBuffer[index+2] ); // }
}
*/
}
// Swap buffers // uint32_t size = width * height;
Serial.println(F("Image received")); // pixelBuffer = new uint8_t[size * components];
swapBuffers(); // ws2812fx.updateLength(size);
// ws2812fx.updateType(pixelType);
// ws2812fx.setPin(PIN);
// Done // ws2812fx.start();
sendResponse("OK");
}
void commandHalt() // // Done
{ // sendResponse("OK");
// }
// void commandSetBrightness()
// {
// Serial.println(F("Command: SetBrightness"));
// // Read value
// uint8_t brightness = bleuart.read();
// // Set brightness
// ws2812fx.setBrightness(brightness);
// // Refresh pixels
// // swapBuffers();
// // Done
// sendResponse("OK");
// }
// void commandSetMode()
// {
// Serial.println(F("Command: SetMode"));
// // Read value
// uint8_t mode = bleuart.read();
// // Set mode
// ws2812fx.setMode(mode);
// ws2812fx.resume();
// // Done
// sendResponse("OK");
// }
// void commandSetSpeed()
// {
// Serial.println(F("Command: SetSpeed"));
// // Read value
// uint16_t speed = (bleuart.read() << 8) | bleuart.read();
// // Set speed
// ws2812fx.setSpeed(speed);
// ws2812fx.resume();
// // 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++;
// }
// }
// ws2812fx.setMode(FX_MODE_STATIC);
// ws2812fx.setColor(*(reinterpret_cast<uint32_t *>(color)));
// // Set all leds to color
// // int size = width * height;
// // uint8_t *base_addr = pixelBuffer;
// // for (int i = 0; i < size; i++)
// // {
// // // ws2812fx.setPixelColor(i, *(reinterpret_cast<uint32_t*>(color)));
// // 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 ws2812fxIndex = y * stride + x;
// uint8_t *pixelBufferPointer = pixelBuffer + pixelDataOffset;
// uint32_t color;
// if (components == 3)
// {
// color = ws2812fx.Color(*pixelBufferPointer, *(pixelBufferPointer + 1),
// *(pixelBufferPointer + 2)); Serial.printf("\tcolor (%d, %d, %d)\n",
// *pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer +
// 2));
// }
// else
// {
// color = ws2812fx.Color(*pixelBufferPointer, *(pixelBufferPointer + 1),
// *(pixelBufferPointer + 2), *(pixelBufferPointer + 3));
// Serial.printf("\tcolor (%d, %d, %d, %d)\n", *pixelBufferPointer,
// *(pixelBufferPointer + 1), *(pixelBufferPointer + 2),
// *(pixelBufferPointer + 3));
// }
// ws2812fx.pause();
// ws2812fx.setPixelColor(ws2812fxIndex, color);
// ws2812fx.show();
// // Done
// sendResponse("OK");
// }
// void commandImage()
// {
// Serial.printf("Command: Image %dx%d, %d, %d\n", width, height, components,
// stride);
// ws2812fx.pause();
// // 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 commandHalt() {
sendResponse("power off"); sendResponse("power off");
ws2812fx.stop(); ws2812fx.stop();
if (Bluefruit.connected()) if (Bluefruit.connected()) {
{
Bluefruit.disconnect(Bluefruit.connHandle()); Bluefruit.disconnect(Bluefruit.connHandle());
} }
@ -460,8 +684,7 @@ void commandHalt()
sd_power_system_off(); sd_power_system_off();
} }
void sendResponse(char const *response) void sendResponse(char const *response) {
{
Serial.printf("Send Response: %s\n", response); Serial.printf("Send Response: %s\n", response);
bleuart.write(response, strlen(response) * sizeof(char)); // bleuart.write(response, strlen(response) * sizeof(char));
} }