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();
@ -117,11 +100,10 @@ void startAdv(void)
Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
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) {
// ws2812fx.fade_out(fx.msg.fade_out.fadeTime);
// } else {
// ws2812fx.fade_out();
// }
// break;
// }
// case fx_Root_setMode_tag: {
// if (fx.msg.setMode.has_segment) {
// ws2812fx.setMode(static_cast<uint8_t>(fx.msg.setMode.mode));
// } else {
// ws2812fx.setMode(static_cast<uint8_t>(fx.msg.setMode.segment),
// static_cast<uint8_t>(fx.msg.setMode.mode));
// }
// break;
// }
// case fx_Root_setOptions_tag: {
// ws2812fx.setOptions(fx.msg.setOptions.segment,
// parseOptions(fx.msg.setOptions.options));
// break;
// }
// case fx_Root_setSpeed_tag: {
// if (fx.msg.setSpeed.has_segment) {
// ws2812fx.setSpeed(static_cast<uint8_t>(fx.msg.setSpeed.speed));
// } else {
// ws2812fx.setSpeed(static_cast<uint8_t>(fx.msg.setSpeed.segment),
// static_cast<uint8_t>(fx.msg.setSpeed.speed));
// }
// break;
// }
// case fx_Root_increaseSpeed_tag: {
// ws2812fx.increaseSpeed(fx.msg.increaseSpeed.step);
// break;
// }
// case fx_Root_decreaseSpeed_tag: {
// ws2812fx.decreaseSpeed(fx.msg.decreaseSpeed.step);
// break;
// }
// case fx_Root_setColor_tag: {
// switch (fx.msg.setColor.color.which_colorTypes) {
// case fx_ColorType_rgb_tag: {
// ws2812fx.setColor(fx.msg.setColor.color.colorTypes.rgb.r,
// fx.msg.setColor.color.colorTypes.rgb.b,
// fx.msg.setColor.color.colorTypes.rgb.g);
// break;
// }
// case fx_ColorType_rgbw_tag: {
// ws2812fx.setColor(fx.msg.setColor.color.colorTypes.rgbw.r,
// fx.msg.setColor.color.colorTypes.rgbw.b,
// fx.msg.setColor.color.colorTypes.rgbw.g,
// fx.msg.setColor.color.colorTypes.rgbw.w);
// break;
// }
// case fx_ColorType_color_tag: {
// if (fx.msg.setColor.has_segment) {
// ws2812fx.setColor(fx.msg.setColor.segment,
// fx.msg.setColor.color.colorTypes.color);
// } else {
// ws2812fx.setColor(fx.msg.setColor.color.colorTypes.color);
// }
// break;
// }
// case fx_ColorType_multiColor_tag: {
// uint32_t colors[NUM_COLORS] = {
// fx.msg.setColor.color.colorTypes.multiColor.col1,
// fx.msg.setColor.color.colorTypes.multiColor.col2,
// fx.msg.setColor.color.colorTypes.multiColor.col3};
// if (fx.msg.setColor.has_segment) {
// ws2812fx.setColors(fx.msg.setColor.segment, colors);
// } else {
// ws2812fx.setColors(0, colors);
// }
// break;
// }
// }
// break;
// }
// case fx_Root_setBrightness_tag: {
// ws2812fx.setBrightness(fx.msg.setBrightness.brightness);
// break;
// }
// case fx_Root_increaseBrightness_tag: {
// ws2812fx.increaseBrightness(fx.msg.increaseBrightness.step);
// break;
// }
// case fx_Root_decreaseBrightness_tag: {
// ws2812fx.decreaseBrightness(fx.msg.decreaseBrightness.step);
// break;
// }
// case fx_Root_setLength_tag: {
// ws2812fx.setLength(fx.msg.setLength.numPixels);
// break;
// }
// case fx_Root_increaseLength_tag: {
// ws2812fx.increaseLength(fx.msg.increaseLength.step);
// break;
// }
// case fx_Root_decreaseLength_tag: {
// ws2812fx.decreaseLength(fx.msg.decreaseLength.step);
// break;
// }
// case fx_Root_trigger_tag: {
// ws2812fx.trigger();
// break;
// }
// case fx_Root_setNumSegments_tag: {
// ws2812fx.setNumSegments(fx.msg.setNumSegments.numSegments);
// break;
// }
// case fx_Root_setSegment_tag: {
// switch (fx.msg.setSegment.color.which_colorTypes) {
// case fx_ColorType_rgb_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.rgb.r,
// fx.msg.setSegment.color.colorTypes.rgb.g,
// fx.msg.setSegment.color.colorTypes.rgb.b, 0),
// fx.msg.setSegment.speed,
// parseOptions(fx.msg.setSegment.options));
// 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;
// }
// }
} }
void commandVersion() // void swapBuffers()
{ // {
Serial.println(F("Command: Version check")); // uint8_t *base_addr = pixelBuffer;
sendResponse(NEOPIXEL_VERSION_STRING); // 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();
// }
void commandSetup() // void commandVersion()
{ // {
Serial.println(F("Command: Setup")); // Serial.println(F("Command: Version check"));
// sendResponse(NEOPIXEL_VERSION_STRING);
// }
ws2812fx.stop(); // void commandSetup()
// {
// Serial.println(F("Command: Setup"));
width = bleuart.read(); // ws2812fx.stop();
height = bleuart.read();
stride = bleuart.read();
componentsValue = bleuart.read();
is400Hz = bleuart.read();
neoPixelType pixelType; // width = bleuart.read();
pixelType = componentsValue + (is400Hz ? NEO_KHZ400 : NEO_KHZ800); // height = bleuart.read();
// stride = bleuart.read();
// componentsValue = bleuart.read();
// is400Hz = bleuart.read();
components = (componentsValue == NEO_RGB || componentsValue == NEO_RBG || componentsValue == NEO_GRB || componentsValue == NEO_GBR || componentsValue == NEO_BRG || componentsValue == NEO_BGR) ? 3 : 4; // neoPixelType pixelType;
// pixelType = componentsValue + (is400Hz ? NEO_KHZ400 : NEO_KHZ800);
Serial.printf("\tsize: %dx%d\n", width, height); // components = (componentsValue == NEO_RGB || componentsValue == NEO_RBG ||
Serial.printf("\tstride: %d\n", stride); // componentsValue == NEO_GRB || componentsValue == NEO_GBR || componentsValue
Serial.printf("\tpixelType %d\n", pixelType); // == NEO_BRG || componentsValue == NEO_BGR) ? 3 : 4;
Serial.printf("\tcomponents: %d\n", components);
if (pixelBuffer != NULL) // Serial.printf("\tsize: %dx%d\n", width, height);
{ // Serial.printf("\tstride: %d\n", stride);
delete[] pixelBuffer; // Serial.printf("\tpixelType %d\n", pixelType);
} // Serial.printf("\tcomponents: %d\n", components);
uint32_t size = width * height; // if (pixelBuffer != NULL)
pixelBuffer = new uint8_t[size * components]; // {
ws2812fx.updateLength(size); // delete[] pixelBuffer;
ws2812fx.updateType(pixelType); // }
ws2812fx.setPin(PIN);
ws2812fx.start(); // uint32_t size = width * height;
// pixelBuffer = new uint8_t[size * components];
// ws2812fx.updateLength(size);
// ws2812fx.updateType(pixelType);
// ws2812fx.setPin(PIN);
// Done // ws2812fx.start();
sendResponse("OK");
}
void commandSetBrightness() // // Done
{ // sendResponse("OK");
Serial.println(F("Command: SetBrightness")); // }
// Read value // void commandSetBrightness()
uint8_t brightness = bleuart.read(); // {
// Serial.println(F("Command: SetBrightness"));
// Set brightness // // Read value
ws2812fx.setBrightness(brightness); // uint8_t brightness = bleuart.read();
// Refresh pixels // // Set brightness
// swapBuffers(); // ws2812fx.setBrightness(brightness);
// Done // // Refresh pixels
sendResponse("OK"); // // swapBuffers();
}
void commandSetMode() // // Done
{ // sendResponse("OK");
Serial.println(F("Command: SetMode")); // }
// Read value // void commandSetMode()
uint8_t mode = bleuart.read(); // {
// Serial.println(F("Command: SetMode"));
// Set mode // // Read value
ws2812fx.setMode(mode); // uint8_t mode = bleuart.read();
ws2812fx.resume();
// Done // // Set mode
sendResponse("OK"); // ws2812fx.setMode(mode);
} // ws2812fx.resume();
void commandSetSpeed() // // Done
{ // sendResponse("OK");
Serial.println(F("Command: SetSpeed")); // }
// Read value // void commandSetSpeed()
uint16_t speed = (bleuart.read() << 8) | bleuart.read(); // {
// Serial.println(F("Command: SetSpeed"));
// Set speed // // Read value
ws2812fx.setSpeed(speed); // uint16_t speed = (bleuart.read() << 8) | bleuart.read();
ws2812fx.resume();
// Done // // Set speed
sendResponse("OK"); // ws2812fx.setSpeed(speed);
} // ws2812fx.resume();
void commandClearColor() // // Done
{ // sendResponse("OK");
Serial.println(F("Command: ClearColor")); // }
// Read color // void commandClearColor()
uint8_t color[MAXCOMPONENTS]; // {
for (int j = 0; j < components;) // Serial.println(F("Command: ClearColor"));
{
if (bleuart.available())
{
color[j] = bleuart.read();
j++;
}
}
ws2812fx.setMode(FX_MODE_STATIC); // // Read color
ws2812fx.setColor(*(reinterpret_cast<uint32_t *>(color))); // uint8_t color[MAXCOMPONENTS];
// for (int j = 0; j < components;)
// {
// if (bleuart.available())
// {
// color[j] = bleuart.read();
// j++;
// }
// }
// Set all leds to color // ws2812fx.setMode(FX_MODE_STATIC);
// int size = width * height; // ws2812fx.setColor(*(reinterpret_cast<uint32_t *>(color)));
// 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 // // Set all leds to color
Serial.println(F("ClearColor completed")); // // int size = width * height;
// swapBuffers(); // // 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++;
// // }
// // }
if (components == 3) // // Swap buffers
{ // Serial.println(F("ClearColor completed"));
Serial.printf("\tclear (%d, %d, %d)\n", color[0], color[1], color[2]); // // swapBuffers();
}
else
{
Serial.printf("\tclear (%d, %d, %d, %d)\n", color[0], color[1], color[2], color[3]);
}
// Done // if (components == 3)
sendResponse("OK"); // {
} // 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]);
// }
void commandSetPixel() // // Done
{ // sendResponse("OK");
Serial.println(F("Command: SetPixel")); // }
// Read position // void commandSetPixel()
uint8_t x = bleuart.read(); // {
uint8_t y = bleuart.read(); // Serial.println(F("Command: SetPixel"));
// Read colors // // Read position
uint32_t pixelOffset = y * width + x; // uint8_t x = bleuart.read();
uint32_t pixelDataOffset = pixelOffset * components; // uint8_t y = bleuart.read();
uint8_t *base_addr = pixelBuffer + pixelDataOffset;
for (int j = 0; j < components;)
{
if (bleuart.available())
{
*base_addr = bleuart.read();
base_addr++;
j++;
}
}
// Set colors // // Read colors
uint32_t ws2812fxIndex = y * stride + x; // uint32_t pixelOffset = y * width + x;
uint8_t *pixelBufferPointer = pixelBuffer + pixelDataOffset; // uint32_t pixelDataOffset = pixelOffset * components;
uint32_t color; // uint8_t *base_addr = pixelBuffer + pixelDataOffset;
if (components == 3) // for (int j = 0; j < components;)
{ // {
color = ws2812fx.Color(*pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2)); // if (bleuart.available())
Serial.printf("\tcolor (%d, %d, %d)\n", *pixelBufferPointer, *(pixelBufferPointer + 1), *(pixelBufferPointer + 2)); // {
} // *base_addr = bleuart.read();
else // base_addr++;
{ // j++;
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 // // Set colors
sendResponse("OK"); // 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();
void commandImage() // // Done
{ // sendResponse("OK");
Serial.printf("Command: Image %dx%d, %d, %d\n", width, height, components, stride); // }
ws2812fx.pause(); // void commandImage()
// {
// Serial.printf("Command: Image %dx%d, %d, %d\n", width, height, components,
// stride);
// Receive new pixel buffer // ws2812fx.pause();
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++;
}
}
/* // // Receive new pixel buffer
if (components == 3) { // int size = width * height;
uint32_t index = i*components; // uint8_t *base_addr = pixelBuffer;
Serial.printf("\tp%d (%d, %d, %d)\n", i, pixelBuffer[index], pixelBuffer[index+1], pixelBuffer[index+2] ); // for (int i = 0; i < size; i++)
} // {
*/ // for (int j = 0; j < components;)
} // {
// if (bleuart.available())
// {
// *base_addr = bleuart.read();
// base_addr++;
// j++;
// }
// }
// Swap buffers // /*
Serial.println(F("Image received")); // if (components == 3) {
swapBuffers(); // uint32_t index = i*components;
// Serial.printf("\tp%d (%d, %d, %d)\n", i, pixelBuffer[index],
// pixelBuffer[index+1], pixelBuffer[index+2] );
// }
// */
// }
// Done // // Swap buffers
sendResponse("OK"); // Serial.println(F("Image received"));
} // swapBuffers();
void commandHalt() // // 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));
} }