Trouble with using multiple millis instances

A binary search could be a lot faster. Start with all LEDs on (as many LEDs as the controller supports, not how many are physically connected). Then turn off the top half; if there's a drop in current, keep the bottom half on and turn on the bottom half of the top half; otherwise turn off the top half of the bottom half. Repeat until you know which LED is the last one that's physically connected. (I call the LEDs closest to the controller the "bottom" and the ones furthest away the "top".)

If the controller supports 1000 LEDs, this should take only about 10 steps.

Looking at the PixelBlaze site, with the expansion board it seems like the most you can have is 64*800, or 51200, LEDs. Even that many should take only about 16 steps to determine how many LEDs are connected (actually, up to 640 steps since you'd have to do the binary search on each of the 64 channels separately, but that's still a lot less than 51200).

It is much clearer. So, your initial question was how do you keep track of all the conditions, and I see two paths based on a single missing detail.

Path 1 - The addressable LEDs are only ever connected sequentially, as in 401, 402, 403 etc. If this is the case, you do not need a state machine or anything fancy. A simple function call and some counters to track where you are in your count along with a single conditional check for when you reach the end. Each iteration through the millis() condition you will return a check for the end, and if not, increment the count.

Path 2 - The addressable LEDs can appear at any address between 401 and 430. If this is the case, again the same function call, with a single millis() condition, but this time a check for there not there and you have to probably check all 30 and store the results in a data structure.

@gcjr yes, that's all I want.

I'm trying to work on your code, but there are a few things I don't understand how to do.

Here's where I am so far:

[code]
uint16_t Leds1 = EEPROM.read(0);

#define LedCodeOff  0
void
ledWriteCode (
  int   code )
{
  Serial.print ("  ledWriteCode: ");
  Serial.println (code);
}

// -------------------------------------
int
measureCurrent (void)
{
  power_mW_A;
}

// -----------------------------------------------------------------------------
struct Led  {
  int     code;
  bool    active;
  int     current;
};

Led leds [] = {
  { 405 },
  { 410 },
  { 415 },
  { 420 },
  { 425 },
  { 430 },
  { 435 },
  { 440 },
  { 445 },
  { 450 },
  { 455 },
  { 460 },
  { 465 },
  { 470 },
  { 475 },
  { 480 },
  { 485 },
  { 490 },
  { 495 },
  { 500 },
};
#define Nled    (sizeof(leds)/sizeof(Led))

// -------------------------------------
#define CheckLedsDelay   250
#define MinLedCurrent    300

void
checkLeds (void)
{
  Led *p = leds;
  for (unsigned n = 0; n < Nled; n++, p++)  {
    Serial.print (" checkLeds: ");
    Serial.print (p->code);

    ledWriteCode (p->code);

    p->current = measureCurrent ();
    if (MinLedCurrent <= p->current)  {
      p->active = true;
      Serial.print (" active");
    }
    else
      Leds1 = code * 5;
    EEPROM.write(0, Leds1);
    EEPROM.commit();

    ledWriteCode (LedCodeOff);
    delay (CheckLedsDelay);
  }
}

// -----------------------------------------------------------------------------
void
setup ()
{
  Serial.begin (9600);

  checkLeds ();
}

void
loop ()
{
}
[/code]

As you can see I haven't changed much, but I assume the following would happen:
Whenever there are no leds connected, the code would pass the last saved led number to Leds1 variable(I multiply it by 5, as I assume the "code" variable increments by 1 every time there are leds connected). It would also save the variable to EEPROM.

What I don't know how to do:

  1. Make it so that it stops when there are no leds connected. There is no reason to continue going till the end, nor keep saving the variable to EEPROM every time.

  2. Make the delay non-blocking. There are a few other things happening in the background, delay would mess with them. I tried to figure out how to how to incorprate millis() in there, but I'm not sure how to do it.

  3. This bit has me scratching my head a bit:

 ledWriteCode (LedCodeOff);

Does that mean that whenever there are no more leds, the led counter goes back to 0?

@christop That's a great suggestion, but unfortunately I can only go 5 leds at a time and not really measure the exact current, only make sure it's above a certain point. The led blocks can be connected in various ways, and that includes forking as well(parallel, not just serial), that would give false current readings, that's why I'm going for this complicated way of measuring them. Otherwise I could just turn on the entire strip, measure total current and divide.

@Perehama Path 1 is the correct one, I'm trying to work on gcjr's code which is I guess similar to what you're describing.

Thanks to all for your help, if you can guide me a bit more I would appreciate it.

i think this is what you want. see no reason for it to be non-blocking since it's performed on demand. a delay of 300 msec, presumably to allow an accurate current measurement seems very excessive, may 10 msec

Output:

checkLeds:
 ledWriteCode: 405
  checkLeds: 0, code 405, cur 557
 ledWriteCode: 410
  checkLeds: 1, code 410, cur 449
 ledWriteCode: 415
  checkLeds: 2, code 415, cur 723
 ledWriteCode: 420
  checkLeds: 3, code 420, cur 608
 ledWriteCode: 425
  checkLeds: 4, code 425, cur 280
save: addr 123, val 4

Code with simulation functions


char s [80];

// -----------------------------------------------------------------------------
void
ledWriteCode (
    int   code )
{
    Serial.print (" ledWriteCode: ");
    Serial.println (code);
}

// -------------------------------------
int
measureCurrent (void)
{
    return random (250, 800);
}

// -------------------------------------
void
save (
    unsigned addr,
    byte      val )
{
    sprintf (s, "save: addr %d, val %d", addr, val);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
#define CheckLedsDelay   250
#define MinLedCurrent    300

#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int
checkLeds (void)
{
    Serial.println ("checkLeds:");
    unsigned n = 0;
    for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
        ledWriteCode (code);
        delay (CheckLedsDelay);
        int cur =  measureCurrent ();

        sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
        Serial.println (s);

        if (MinLedCurrent > cur)
            break;
    }
    return n;
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    int nLeds = checkLeds ();
#define EEPROM_NLED_ADR 123
    save (EEPROM_NLED_ADR, nLeds);
}

void
loop ()
{
}

Thanks for the help!

Unfortunately there has to be a delay longer than 10ms, and has to be non-blocking. I'm sending the led data(including 401, 402 etc) over serial to the other controller every 40ms(that interval is a limitation of the other controller, can't be lower). I might be ok with 100, will have to check it, but it has to be non-blocking it will interfere with serial.

I will be away for work for the next week, after that I will try to change the delay myself, go over your code and understand it and come back if I can't figure it out. As much as I appreciate your help and time spent I have to also learn something along the way:)

One small question I wanted to ask, how come you put measureCurrent in a separate function if it's only one line of code? Are there any other benefits than keeping the sketch tidy?

Once again, thanks for the help!

seems that it's still not clear what you're trying to do. when does this serial transmission occur?

why does this need to be "non-blocking"? is there something else that needs to be done while testing the LEDs? serial input will be buffered and waiting.

The controller in charge of the leds doesn't know which leds to turn on or off until the ESP32 tells it so, which it does every 40ms over serial.

So when the checkLeds function is called, the "code" variable is passed through serial in order to turn on or off the leds every 40ms.

are there other "commands" that need to be processed thru the serial interface?

what is exactly performing the test, the Arduino or esp32? does the device measuring the current need to report the current thru the serial interface, as well?

as you can see now:
leaving out information in an informatic project just leads to distraction of solving the problem.

the first step is always: avoid writing code. Describe in normal words what shall happen.

The normal worded description must describe

  • all data-processing
  • all devices and sensors involved

If multiple things have to be executed in parallel adding a timing diagram that shows the timely overlapping of these multiple things.

best regards Stefan

@gcjr There is no Arduino, only the ESP32 sending the data through serial, and Pixelblaze, the controller of the leds receiving the data.

There is indeed more data passed through serial, mostly from other sensors(audio, accelerometer, light), but these don't matter much, while calculating the number of leds they are not used by Pixelblaze. The point is that ESP32 has to send over the number of leds to Pixelblaze, both the final measured number and the ones to turn on while measuring(401, 402 etc). It doesn't need to report current measurement, only number of leds.

I will give a shot at turning the delay into non-blocking, I believe I will have to put the start of the timer right before this line in checkLeds function:

Serial.println ("checkLeds:");

and the end of timer replacing this line:

delay (CheckLedsDelay);

@StefanL38 You're right in that I should have tried better to explain what I'm doing, my very limited coding experience being the main issue here.

and exactly this is the reason why you should describe in normal words. Because in normal words you are a real expert.

Of course you can go on playing that ping-pong game of short postings (ping) and get a new asking back (pong) what this means or a guessing what it might means.

how many devices are included in this project?

a single ESP32 connected to the pixelblaze?
or are there more devices?
If yes what exact type of microcontroller are these devices? and how many?

This is wayyy too unprecise description.
"There is indeed more data passed through serial, mostly from other sensors(audio, accelerometer, light),"
which serial connection? The serial connection between the ESP32 and the pixelblaze or some other devices??

at what frequency do you send this data? How often per second or minute do send this data? at what baudrate? and how many bytes?

You can try this. But to me at the stage in the development-process this makes no sense
because we the other users still have only an
##unclear
picture of what you are trying to do.

How should we ever be of help if we can't compare your half baken code if this is the right direction or not.

To make an analogon:

You are talking somehow of numbers without specifying what the numbers are for.

The helpers make some assumings and a suggestion: If temperature goes above 30 degrees switch on ventilator
But what the project is really about is: if waterlevel is below 30 cm switch on waterpump.

So how many rounds of too short too unclear postings and asking back do you need to understand this?

Does your head explode if you sit down and think about it and then write 20 to 40 sentences where all details

  • exact naming which device
  • numbers
  • direction of data beeing transferred

is repeated in each and every sentence

Does your hand fell of if you type this amount of letters?

Do you die from hunger and thirst by writing down such a detailed description?

Are you flying a landing-approach of a plane in parallel to posting these too short postings?

I guess always no!

So what the hell is the reason to refuse writing down such a detailed description and adding a timing chart?

I'm not refusing to write down any detail.

Most if not all of the questions you ask, including intervals, devices used, naming, data direction etc, are explained quite well in post 19, and to a lesser extent in post 1. These are quite long posts, and while I have no issue spending the time to write them, I mostly try to post something short so that whoever is helping me doesn't have to spend ages reading.

As stated in my previous post, the sensors are not important while this part of the code is running, simply because at that time Pixelblaze is not using them.

I don't mean to sound rude, but I see you've spent some time writing your reply above yet ask things that have already been answered.

@gcjr I've spent quite a few hours trying to replace delay with a non-blocking one, but I can't make it work.

I get either of 2 results: All readouts are done simultaneously(405-500), or I get no readouts at all. I'm placing everything within the for loop, I understand that time has to start being counted in there and not before it. Here's where I'm at:

char s [80];


int LedPeriod = 250;
unsigned long LedTime_now;
bool ItWasDone = false;


// -----------------------------------------------------------------------------
void
ledWriteCode (
  int   code )
{
  Serial.print (" ledWriteCode: ");
  Serial.println (code);
}

// -------------------------------------
int
measureCurrent (void)
{
  return random (250, 800);
}

// -------------------------------------
void
save (
  unsigned addr,
  byte      val )
{
  sprintf (s, "save: addr %d, val %d", addr, val);
  Serial.println (s);
}

// -----------------------------------------------------------------------------
#define CheckLedsDelay   250
#define MinLedCurrent    300

#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int
checkLeds (void)
{


  Serial.println ("checkLeds:");
  unsigned n = 0;
  for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
    ledWriteCode (code);

    ItWasDone = true;
    LedTime_now = millis();


    if (ItWasDone && ( millis() - LedTime_now >= LedPeriod) )
    {


      int cur =  measureCurrent ();

      sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
      Serial.println (s);
      ItWasDone = false;

      if (MinLedCurrent > cur)
        break;


    }
  }
  return n;

}

// -----------------------------------------------------------------------------
void
setup ()
{
  Serial.begin (115200);

  int nLeds = checkLeds ();
  //#define EEPROM_NLED_ADR 123
  //   save (EEPROM_NLED_ADR, nLeds);
}

void
loop ()
{

}

don't understand the purpose of using millis() here. this isn't a while loop (nor does it need to be because this code isn't repeated being called).

since LedPeriod can't be exceeded, the condition is always false and the for loop just goes to the next LED code.

need to get to bed, may look again tomorrow AM

why do

you have

to spread

your code over so many lines ?

// -----------------------------------------------------------------------------
void
setup ()
{
  Serial.begin (115200);

It could be two lines compact

void setup () {
  Serial.begin (115200);

What do you expect from an

empty

function void loop()

?

For the convenience of the other users here a well formatted version of petros code

char s [80];

int LedPeriod = 250;
unsigned long LedTime_now;
bool ItWasDone = false;

void ledWriteCode (int   code ){
  Serial.print (" ledWriteCode: ");
  Serial.println (code);
}

int measureCurrent (void){
  return random (250, 800);
}

void save (unsigned addr,byte      val ) {
  sprintf (s, "save: addr %d, val %d", addr, val);
  Serial.println (s);
}

#define CheckLedsDelay   250
#define MinLedCurrent    300

#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int checkLeds (void) {
  Serial.println ("checkLeds:");
  unsigned n = 0;

  for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
    ledWriteCode (code);

    ItWasDone = true;
    LedTime_now = millis();

    if (ItWasDone && ( millis() - LedTime_now >= LedPeriod) ) {
      int cur =  measureCurrent ();

      sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
      Serial.println (s);
      ItWasDone = false;

      if (MinLedCurrent > cur)
        break;
    }
  }
  return n;
}

void setup () {
  Serial.begin (115200);

  int nLeds = checkLeds ();
  //#define EEPROM_NLED_ADR 123
  //   save (EEPROM_NLED_ADR, nLeds);
}

void loop () {

}

tips how to improve your posting style

This code was provided by @gcjr , he’s been quite helpful so far. I haven’t incorporated it to mine yet, there is no reason to add anything extra to it until I figure out how to remove the delay.

tips how to improve your posting style

OMG OMD OMA

You are commenting

What do you expect from an unfinished code?
You must be really kidding by posting this code.

I really can't believe that you fiddled around with the this code-version

char s [80];

int LedPeriod = 250;
unsigned long LedTime_now;
bool ItWasDone = false;

void ledWriteCode (int   code ){
  Serial.print (" ledWriteCode: ");
  Serial.println (code);
}

int measureCurrent (void){
  return random (250, 800);
}

void save (unsigned addr,byte      val ) {
  sprintf (s, "save: addr %d, val %d", addr, val);
  Serial.println (s);
}

#define CheckLedsDelay   250
#define MinLedCurrent    300

#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int checkLeds (void) {
  Serial.println ("checkLeds:");
  unsigned n = 0;

  for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
    ledWriteCode (code);

    ItWasDone = true;
    LedTime_now = millis();

    if (ItWasDone && ( millis() - LedTime_now >= LedPeriod) ) {
      int cur =  measureCurrent ();

      sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
      Serial.println (s);
      ItWasDone = false;

      if (MinLedCurrent > cur)
        break;
    }
  }
  return n;
}

void setup () {
  Serial.begin (115200);

  int nLeds = checkLeds ();
  //#define EEPROM_NLED_ADR 123
  //   save (EEPROM_NLED_ADR, nLeds);
}

void loop () {

}

for hours

It must have been a different codeversion if it should make any sense

Why are you so lazy to post this piece of code instead of the one you have really used ?

Except beeing what I call a
tips how to improve your posting style

at least in the context of the code you posted, why is there a need for it to be non-blocking? you're calling a sub-function one time expecting it to return the # of active LEDs

in this context, this is how i would write that sub-function

char s [80];

// -----------------------------------------------------------------------------
void
ledWriteCode (
    int   code )
{
    Serial.print (" ledWriteCode: ");
    Serial.println (code);
}

// -------------------------------------
int
measureCurrent (void)
{
    return random (250, 800);
}

// -------------------------------------
#define EepromNledAddr 123
void
save (
    unsigned addr,
    byte      val )
{
    sprintf (s, "save: addr %d, val %d", addr, val);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
#define CheckLedsDelay   250
#define MinLedCurrent    300
#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int
checkLeds (void)
{
    Serial.println ("checkLeds:");

    unsigned n = 0;
    for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
        ledWriteCode (code);

        delay (10);
        int cur =  measureCurrent ();

        sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
        Serial.println (s);

        if (MinLedCurrent > cur)
            break;
    }
    return n;
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (115200);
    int nLeds = checkLeds ();

    save (EepromNledAddr, nLeds);
}

void
loop ()
{
}

but i thought you said this feature, determining the # of LEDs, is actually driven by some other processor (e.g. PC) sending LED codes. in this context, a different approach is needed

i was going to say there needs to be a cmd to enter a mode for determining the # of LEDs available, but that mode would be on the sending processor (PC). the esp would only need to recognize a command to set the LED code, measure the current and return either the value of the measured current or a boolean that it exceeds some minimum

here's another approach based of you post #19
Output:

cmdProcess: ledCurrent 405
 ledWriteCode: 405
 ledCurrent - code 405, cur 557
cmdProcess: ledCurrent 415
 ledWriteCode: 415
 ledCurrent - code 415, cur 449
cmdProcess: ledCurrent 410
 ledWriteCode: 410
 ledCurrent - code 410, cur 723
cmdProcess: junk
 cmd unknown

Code:

char s [80];

// -----------------------------------------------------------------------------
void
ledWriteCode (
    int   code )
{
    Serial.print (" ledWriteCode: ");
    Serial.println (code);
}

// -------------------------------------
int
measureCurrent (void)
{
    return random (250, 800);
}

// -------------------------------------
#define EepromNledAddr 123
void
save (
    unsigned addr,
    byte      val )
{
    sprintf (s, "save: addr %d, val %d", addr, val);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
#define CheckLedsDelay   250
#define MinLedCurrent    300
#define LedCode0    405
#define LedCodeN    500
#define LedCodeDel  5

int
checkLeds (void)
{
    Serial.println ("checkLeds:");

    unsigned n = 0;
    for (unsigned code = LedCode0; LedCodeN >= code; code += LedCodeDel, n++)  {
        ledWriteCode (code);

        int cur =  measureCurrent ();
        delay (10);

        sprintf (s, "  checkLeds: %d, code %3d, cur %3d", n, code, cur);
        Serial.println (s);

        if (MinLedCurrent > cur)
            break;
    }
    return n;
}

// -----------------------------------------------------------------------------
void
cmdProcess (
    char *buf )
{
    sprintf (s, "%s: %s", __func__, buf);
    Serial.println (s);

    char cmd [20];
    int  val;
    int n = sscanf (buf, "%s %d", cmd, &val);

    if (2 == n)  {
        if (! strcmp(cmd, "ledCurrent"))  {
            ledWriteCode (val);
            delay (10);
            int cur =  measureCurrent ();

            sprintf (s, " ledCurrent - code %3d, cur %3d", val, cur);
            Serial.println (s);
            return;
        }

        // of course there can be other commands 

    }
    sprintf (s, " cmd unknown");
    Serial.println (s);
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (115200);
}

// ---------------------------------------------------------
char buf [80];

void
loop ()
{
    if (Serial.available ())  {
        int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
        buf [n] = '\0';

        cmdProcess (buf);
    }
}

What the ESP is doing, is initiate the measure procedure when a button is pressed.

Here's a crude representation of the hardware connections:

Here's the relevant code from post #6 in charge of reading the sensor board via serial:

void SensorBoard()  //  SENSOR BOARD READ ROUTINE
{
  while (Serial1.available() > 0)                           // Something to receive?
  {
    receivedBytes[idx++] = Serial1.read();                  // Read next byte into array

    if (! started)                                         // Are we still trying to find the start marker?
    {
      if (receivedBytes[idx - 1] != startMarker[idx - 1])  // Check if the byte received matches expected.
        idx = 0;                                           // If not, start over.

      if (idx == START_BYTES)                              // Have we got all 6 bytes?
        started = true;                                    // Then we're started, so will read reset of data.
    }
    else                                                   // We're started.
    {
      if (idx == LENGTH)                                   // Read to the end?
        processData = true;                                // Set the flag so the data gets processed.
    }
  }


  if (processData)                                         // Flag set?
  {
    for (uint8_t x = 0; x < LENGTH; x++)                   // Loop through the array.
    {

      freq[0] = receivedBytes[6];
      freq[1] = receivedBytes[7];
      freq[2] = receivedBytes[8];
      freq[3] = receivedBytes[9];
      freq[4] = receivedBytes[10];
      freq[5] = receivedBytes[11];
      freq[6] = receivedBytes[12];
      freq[7] = receivedBytes[13];
      freq[8] = receivedBytes[14];
      freq[9] = receivedBytes[15];
      freq[10] = receivedBytes[16];
      freq[11] = receivedBytes[17];
      freq[12] = receivedBytes[18];
      freq[13] = receivedBytes[19];
      freq[14] = receivedBytes[20];
      freq[15] = receivedBytes[21];
      freq[16] = receivedBytes[22];
      freq[17] = receivedBytes[23];
      freq[18] = receivedBytes[24];
      freq[19] = receivedBytes[25];
      freq[20] = receivedBytes[26];
      freq[21] = receivedBytes[27];
      freq[22] = receivedBytes[28];
      freq[23] = receivedBytes[29];
      freq[24] = receivedBytes[30];
      freq[25] = receivedBytes[31];
      freq[26] = receivedBytes[32];
      freq[27] = receivedBytes[33];
      freq[28] = receivedBytes[34];
      freq[29] = receivedBytes[35];
      freq[30] = receivedBytes[36];
      freq[31] = receivedBytes[37];
      freq[32] = receivedBytes[38];
      freq[33] = receivedBytes[39];
      freq[34] = receivedBytes[40];
      freq[35] = receivedBytes[41];
      freq[36] = receivedBytes[42];
      freq[37] = receivedBytes[43];
      freq[38] = receivedBytes[44];
      freq[39] = receivedBytes[45];
      freq[40] = receivedBytes[46];
      freq[41] = receivedBytes[47];
      freq[42] = receivedBytes[48];
      freq[43] = receivedBytes[49];
      freq[44] = receivedBytes[50];
      freq[45] = receivedBytes[51];
      freq[46] = receivedBytes[52];
      freq[47] = receivedBytes[53];
      freq[48] = receivedBytes[54];
      freq[49] = receivedBytes[55];
      freq[50] = receivedBytes[56];
      freq[51] = receivedBytes[57];
      freq[52] = receivedBytes[58];
      freq[53] = receivedBytes[59];
      freq[54] = receivedBytes[60];
      freq[55] = receivedBytes[61];
      freq[56] = receivedBytes[62];
      freq[57] = receivedBytes[63];
      freq[58] = receivedBytes[64];
      freq[59] = receivedBytes[65];
      freq[60] = receivedBytes[66];
      freq[61] = receivedBytes[67];
      freq[62] = receivedBytes[68];
      freq[63] = receivedBytes[69];
      audio[0] = receivedBytes[70];
      audio[1] = receivedBytes[71];
      audio[2] = receivedBytes[72];
      audio[3] = receivedBytes[73];
      audio[4] = receivedBytes[74];
      audio[5] = receivedBytes[75];
      acc[0] = receivedBytes[76];
      acc[1] = receivedBytes[77];
      acc[2] = receivedBytes[78];
      acc[3] = receivedBytes[79];
      acc[4] = receivedBytes[80];
      acc[5] = receivedBytes[81];
    }
    started = false;                                       // Start looking for the start marker again.
    processData = false;                                   // Clear the processing flag.
    idx = 0;                                               // Reset the array index to start over.
  }
}

This happens whenever a pattern on Pixelblaze requires sensor data(accelerometer, audio input), and is triggered by turning an input high on ESP32. This is time-sensitive(bytes are sent at 40ms intervals), if there is any delay in the code will result in packet loss.

This runs endlessly in loop():

if ((unsigned long)(millis() - SerialTime_now) > SerialPeriod) {
    SerialTime_now = millis();

    Serial1.write(header, sizeof(header));
    Serial1.write(freq, sizeof(freq));
    Serial1.write(audio, sizeof(audio));
    Serial1.write(acc, sizeof(acc));
    Serial1.write(light, sizeof(light));
    Serial1.write(analog, sizeof(analog));
    Serial1.write(end, sizeof(end));

  }

These are the bytes transmitted to Pixelblaze via serial. Some are taken straight from the sensor board, some are created in ESP32 via analog inputs. 4 bytes towards the end represent led count. They are transmitted every 40ms, without them(if there is some blocking delay happening elsewhere in the code), Pixelblaze will not know which leds to turn on or off.

Pixelblaze doesn't know how many leds are connected to it. It thinks there are 300(I've put that number in settings as it is the max theoretical number I can get to if all led bricks are connected).

I need to somehow let it know, hence the whole measure procedure. As you will notice in the drawing, the led bricks can also be connected in parallel, so getting an overall current reading(turn all leds on) would give false results.

If I start measuring using your code(any iteration, but let's stick to the one from post #24 because it does exactly what I want bar for the blocking delay), checkLeds() function will send value 405 to code variable, but then Serial1.write in loop() will most likely not happen because of the delay, so Pixelblaze will not know that it has to switch leds 1-5 on and current measurement will be false.

The way I understand it, I have two options:

  1. Find a way to have checkLeds() do its thing with a non-blocking delay.

  2. Bring Serial1.write (all 98 bytes as Pixelblaze expects that) inside checkLeds(). As I write these lines, I realize that during measurement I don't care about anything else(sensors, analog inputs etc), the only thing I want to happen is do the measurement.