Hi,
I just can't figure out what I'm doing wrong so I'm going to ask for help here.
I'm trying to control some ws2812b LEDs connected to an arduino nano via serial.
I'm sending json formated strings like:
<{"led":"boden", "brightness":200, color:[200, 2, 200]}>
Most of the time the first string that is sent works, but after that I'm only receiving garbage.
Could someone give me a hint why this is happening?
Also tried different serial speeds.
This is my code:
#include <Arduino.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define SERIAL_BUFFER_SIZE 256
#define PIN 3
Adafruit_NeoPixel strip = Adafruit_NeoPixel(300, PIN, NEO_GRB + NEO_KHZ800);
const byte numChars = 128;
char receivedChars[numChars];
char tempChars[numChars];
boolean newData = false;
uint8_t brightness = 255;
uint8_t red = 0;
uint8_t green = 0;
uint8_t blue = 0;
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
Serial.print(rc);
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
Serial.println(" ");
}
} else if (rc == startMarker) {
recvInProgress = true;
Serial.print("Serial received: ");
}
}
}
void parseData() {
Serial.print("parseData(): ");
Serial.println(tempChars);
StaticJsonBuffer<255> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(tempChars);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
if (root["led"] == "boden") {
if (root.containsKey("brightness")) {
brightness = atoi(root["brightness"]);
}
if (root.containsKey("color")) {
if (root["color"][0] != NULL) {
red = atoi(root["color"][0]);
}
if (root["color"][1] != NULL) {
green = atoi(root["color"][1]);
}
if (root["color"][2] != NULL) {
blue = atoi(root["color"][2]);
}
}
}
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
parseData();
newData = false;
}
// while (Serial.available()) {
// Serial.write(Serial.read());
// }
if (! Serial.available()) {
if (brightness && !(red || green || blue)) {
rainbow(20, brightness);
} else {
setColor(red, green, blue);
strip.setBrightness(brightness);
strip.show();
}
}
}
void setColor (uint8_t r, uint8_t g, uint8_t b) {
uint16_t i;
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, r, g, b);
strip.setBrightness(brightness);
strip.show();
}
}
void rainbow(uint8_t wait, uint8_t brightness) {
uint16_t i, j;
strip.setBrightness(brightness);
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
if (Serial.available()) {
return;
}
}
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
And here the serial output I get (first transmission is ok):
Serial received: {"led":"boden", "brightness":200, color:[200, 2, 200]}>
parseData(): {"led":"boden", "brightness":200, color:[200, 2, 200]}
Serial received: {edn"ht200r:, >
parseData(): {edn"ht200r:,
parseObject() failed<\r><\n>
Serial received: {"lderi":lo, 2}>
parseData(): {"lderi":lo, 2}
parseObject() failed
Serial received: {d"n"ht00r:[, >
parseData(): {d"n"ht00r:[,
parseObject() failed
Serial received: {":, tne0,[220>
parseData(): {":, tne0,[220
parseObject() failed
Hope someone can help.
Thanks!