I've been pulling my hair out trying to figure out what's wrong with my setup/code here. I have an Arduino UNO controlling a 5M RGB LED strip connected to a PC with a custom application to send serial data to control it. For the purpose of testing though, I'm using the Arduino serial monitor to send data.
This malformed data only occurs sometimes and usually when I have the 'rainbow' field in the JSON string set to true and I send another string with something else changed (eg. brightness, rgb values etc).
Here's an example of a JSON string I send:
<{"red":255,"green":0,"blue":0,"brightness":100,"rainbow":true}>
and the output I expect and most of the time receive:
<{"red":255,"green":0,"blue":0,"brightness":100,"rainbow":true}>
09:46:57.779 -> {"red":255,"green":0,"blue":0,"brightness":100,"rainbow":true}
09:46:57.779 -> RED: 255
09:46:57.779 -> GREEN: 0
09:46:57.779 -> BLUE: 0
09:46:57.779 -> BRIGHTNESS: 100
09:46:57.779 -> RAINBOW: 1
Unfortunately I get malformed data sometimes. Here's an example:
I sent this JSON string:
<{"red":255,"green":0,"blue":0,"brightness":100,"rainbow":true}>
and got this as output:
09:47:04.780 -> <{ss":100,"rainbow":true}>
09:47:04.780 -> {ss":100,"rainbow":true}
09:47:04.780 -> RED: 0
09:47:04.780 -> GREEN: 0
09:47:04.780 -> BLUE: 0
09:47:04.780 -> BRIGHTNESS: 0
09:47:04.780 -> RAINBOW: 0
Here's my full sketch code:
#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>
#define MAX_PACKET_LENGTH 128
const uint8_t led_pin = 8;
const int led_count = 141;
const char begin_char = '<';
const char end_char = '>';
uint8_t red = 0;
uint8_t green = 0;
uint8_t blue = 0;
uint8_t brightness = 255;
bool rainbow = false;
Adafruit_NeoPixel led_strip;
void setup() {
Serial.begin(115200);
Serial.println("UNO!");
led_strip = Adafruit_NeoPixel(led_count, led_pin, NEO_GRB + NEO_KHZ800);
led_strip.begin();
led_strip.clear();
led_strip.setBrightness(brightness);
led_strip.show();
}
void loop() {
led_strip.fill(led_strip.Color(red, green, blue));
led_strip.setBrightness(brightness);
led_strip.show();
static char data[MAX_PACKET_LENGTH];
memset(&data, 0, MAX_PACKET_LENGTH);
int count = 0;
while (data[count] != end_char) {
if (Serial.available() > 0) {
char data_t = Serial.read();
if (data_t == begin_char) {
count = 0;
memset(&data, 0, MAX_PACKET_LENGTH);
} else {
++count;
}
data[count] = data_t;
}
}
if (data[0] != begin_char) {
return;
}
data[count + 1] = '\0';
Serial.println(data);
memmove(&data[0], &(data[1]), strlen(&(data[1])));
data[strlen(data) - 2] = '\0';
Serial.println(data);
StaticJsonDocument<80> doc;
DeserializationError error = deserializeJson(doc, data);
red = doc["red"];
green = doc["green"];
blue = doc["blue"];
brightness = doc["brightness"];
rainbow = doc["rainbow"];
Serial.print("RED: "); Serial.println(red);
Serial.print("GREEN: "); Serial.println(green);
Serial.print("BLUE: "); Serial.println(blue);
Serial.print("BRIGHTNESS: "); Serial.println(brightness);
Serial.print("RAINBOW: "); Serial.println(rainbow);
if (rainbow) {
while (true) {
for (long first_hue = 0; first_hue < 5 * 65536; first_hue += 256) {
for (int i = 0; i < led_strip.numPixels(); ++i) {
int hue = first_hue + (i * 65536L / led_strip.numPixels());
led_strip.setPixelColor(i, led_strip.gamma32(led_strip.ColorHSV(hue)));
}
led_strip.show();
delay(5);
if (Serial.available() > 0) {
Serial.println("BREAKING OUT");
return;
}
}
}
}
}
I'm sure I'm missing something obvious here but I haven't been able to figure it out.
Cheers