assign those variable as brightness value to each led (8 led in total)
Speed of reading data is fast, but displaying the brightness is where the slowness occurs
Anyway here's my code, any tips and guidance would be much appreciated!
For hardware specs, im using Arduino UNO R3 ATMega328P
#include <Adafruit_NeoPixel.h>
#define NYEO 4
#define NUMPIXELS 8
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, NYEO, NEO_GRB + NEO_KHZ800);
int r = 0;
int g = 255;
int b = 139;
int fr = 0;
int fg = 0;
int fb = 0;
uint32_t colors[NUMPIXELS];
int value1, value2, value3, value4;
int noko1, noko2, noko3, noko4;
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
}
void loop() {
if (Serial.available() > 0) {
// Stage 1 Denial
String input = Serial.readStringUntil('\n');
parseInput(input);
// Stage 2 Anger
if(value1 > 0) {noko1 = 39;}
if(value2 > 0) {noko2 = 39;}
if(value3 > 0) {noko3 = 39;}
if(value4 > 0) {noko4 = 39;}
// Stage 3 Bargaining
if(noko1 > 0) {noko1--;}
if(noko2 > 0) {noko2--;}
if(noko3 > 0) {noko3--;}
if(noko4 > 0) {noko4--;}
// Stage 4 Depression
int neko1 = noko1*6;
int neko2 = noko2*6;
int neko3 = noko3*6;
int neko4 = noko4*6;
int BrightNya[NUMPIXELS] = {neko1,neko1,neko2,neko2,neko3,neko3,neko4,neko4};
for(int i = 0; i < NUMPIXELS; i++) {
fr = (r*BrightNya[i])/255;
fg = (g*BrightNya[i])/255;
fb = (b*BrightNya[i])/255;
colors[i] = strip.Color(fr,fg,fb);
}
// Stage 5 Acceptance
for(int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, colors[i]);
}
delay(10);
strip.show();
}
}
void parseInput(String input) {
int startIndex = 0;
int commaIndex;
int valueIndex = 0;
while ((commaIndex = input.indexOf(',', startIndex)) != -1 && valueIndex < 3) {
String valueString = input.substring(startIndex, commaIndex);
int value = valueString.toInt();
switch (valueIndex) {
case 0: value1 = value; break;
case 1: value2 = value; break;
case 2: value3 = value; break;
}
startIndex = commaIndex + 1;
valueIndex++;
}
value4 = input.substring(startIndex).toInt();
}
i have tried simplying and combining the calculations into one line and got rid of variable noko1 to noko4 but its still slow
i have also tried increasing baud rate from 9600 to 115200, no effects as well
Seems to me that reading the Strings would be the slow part. What data are you reading into Serial and is there a way to shorten it to just chars? How long are these Strings you're
One advice; spend time getting away from C++ Strings and learn C char array strings. At least then you won't be wasting your time.
You are doing a lot of useless manipulations the hard way and it seems like tou barely know what arrays are. Are you using snippets of code examples or getting gelp frim chatGPT? Either way. you don't learn to think well.
I would nest these as chars in a switch/case structure that increments a byte every time you receive the next char and resets back to say, 0 once the fourth one arrives.
I mean, that's just how I would approach this code, I'm not saying to rewrite based on this, it's just how I would do it and telling Arduino to do stuff using just chars has always been plenty fast enough. I honestly don't have a better suggestion for you, just trying to tick a few things off before other helpers maybe offer a better suggestion.
I mean then you say that you don't think it's the Serial, but the pixels themselves so sorry I can't be more help than that.
In the off chance you do go for the Hail Mary and change your Serial input, the way to do single chars (or any Serial handling) is best illustrated to my knowledge in the immortal example of @Robin2. If you've never read this page, even if you don't use it for this project, it's well worth the time.
i used this approach because it worked for me in the past when there was lesser data to handle but i guess its not efficient for this kind of operation. I'll keep it in mind and read up on the page. Thanks for the inputs!
the functionality is that i want a fading effect where the brightness slowly drops from (39x6) to (0x6) everytime the loop runs. And you're right I don't expose myself enough to using arrays
okay so I changed the noko1 to noko4 variables from global to local and modified the name to a different one, br1 to br4. The result is still the same with same speed as well.
As mentioned on the original post I also tried removing the variable noko1 to noko4 and simplified the calculation, also yield same result
That's funny. To me, not making local copies of global variables would be a thing to do! Local variables get lost at the end of a function and void loop() is a function. If you make them static, that's different but just keeping them global is fine. The PROBLEM is having different variables with the same name, the compiler will use the local vars and whatever happens to them gets lost when loop() ends, getting rid of those should change how the sketch works.
Also what is the flow of the program?
As soon as it receives a 'command' from serial it writes the 8 leds ( once, without transitions)?
To see where is the 'timing bootleneck' try adding some debug print, checking the show timestamp option in the serial debug ( ar use millis() or a higher resolution timer if needed )
I see no for-loop that accomplishes this.
Instead I see some code that basically just outputs light/color to a strip based on Serial inputs being fed to it.
If you're trying to feed new color data through Serial into this Arduino, then this bit surely won't help with the responsiveness of the system:
If all you really want is a fade effect, then what is the Serial input needed for?
Ok, I made a Wokwi that I think simulates your project.
I don't understand your program flow and there seems to be unnecessary calls to strip.show(); (why at the end of void setup() ?
I tried changing the Serial if to a while, tried removing the if (Serial.available() > ) {} altogether (isn't that implicit in your subsequent call to String input = Serial.readStringUntil('\n');?) and I honestly can't help beyond this because I don't understand what this sketch is supposed to do.
For example, in the Wokwi, the pixels are always all green. Also, I can't seem to get them to turn off using "0,0,0,0" after they are all turned on with "1,1,1,1" input to Serial.
You have // Stage 1 Denial but whatever that is supposed to do...just reads input from the incoming Python data and does nothing with it before going to // Stage 2 Anger?
I must be missing something or maybe the Wokwi is not at all representative of where you're already at, I don't know but good luck.
Sorry, I'll try to explain what it functionality is in detail
each set of data comes in format "0,0,0,0" and the arduino receives roughly 20 sets of such data per second. The incoming data value can change between 1 and 0.
Now for the arduino side, as you can see theres 2 if command (shown in stage 2 and 3) for each of the four data (so it calculates each variable individually).
In stage 2, whenever '1' is detected, it sets the variable value of 'noko' to 39. Else, the value of noko remains unchanged.
In stage 3, as long as the value of 'noko' is not zero, it will keep decreasing once per loop() cycle until it hits zero. This is what creates the fading effect.
In stage 4, 'neko' is just amplifying the value to map/scale brightness between 0 to 234 (39x6). Then it just sets each led brightness to value of 'neko'.