So I made an app in C# which sends serial data to my arduino.
The arduino then processes the bytes to control 84 LED's
The way i currently send my data is the following: 3 bytes with values between 0-255 in a continues datastream. So after one cycle the arduino has processed 252 bytes. However it's taking over 400ms to do this. So now my question is: How do i make it not exceed 100ms?
What I tried so far: Increase the baud rate, however this didn't seem to be a bottleneck.
Decrease the timeout. This seems to improve it a bit but no noticable impact
Debugged: timed how low each step takes.
Conclusion: without serial.readBytes it can complete the cycle in 2-3ms.
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(84, PIN, NEO_GRB + NEO_KHZ800);
byte colors[3];
unsigned long startTime;
unsigned long endTime;
String divider = "/";
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
Serial.begin(115200);
Serial.setTimeout(500);
}
void loop() {
if(Serial.available() >= 3){
startTime = millis();
for(int i=0; i < strip.numPixels(); i++) {
//strip.setPixelColor(i, colors[0], colors[1], colors[2]);
Serial.readBytes(colors, 3);
strip.setPixelColor(i, colors[0], colors[1], colors[2]);
}
strip.show();
endTime = millis();
Serial.println(endTime-startTime+divider+Serial.available());
}
}
AWOL:
We also seem to be missing a major part of the puzzle.
Why show for every three bytes?
this is the (crappy) source in case that helps.
I take a screenshot every ms and process pixels out of it. Pretty much like an ambient light. The sending itself doesnt seem to take long at all. It's just the reading thats very slow on the arduino.
The 3 bytes are basically just RGB, 1 byte Red, 1byte Green, 1byte Blue
Seems promising. Just kind of disappointing how poorly the readBytes method was designed. And outlives its usefulness for anything more than reading a few bytes
They're not though. As i said multiple times before, everything except the readBytes runs within a few ms, that includes setting the LED's to a color. I even tried using another lib before i realised it was the readBytes
I can not confirm your findings. When I send 99 bytes, they are read in 8 ms. Any time the are not a multiple of 3 bytes sent, the default time out of 500 ms kicks in. Send 98 bytes reading time is 508 ms. Send 95 bytes and the reading time is 1008 ms. If three bytes are not available to read in your for() loop you run into a time out. You could be using an if() conditional instead of the for() loop.
//enter into serial monitor and send with no line ending
//123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
//99 bytes
byte colors[3];
unsigned long startTime;
unsigned long endTime;
void setup() {
Serial.begin(115200);
Serial.setTimeout(500);
}
void loop() {
if (Serial.available() >= 3) {
startTime = millis();
for (int i = 0; i < 33; i++) {
Serial.readBytes(colors, 3);
}
endTime = millis();
Serial.println(endTime - startTime);
}
}