Arrays and calculation, can someone see what wrong with this?

Hi All

First to solve get a virtual pint of beer (_)3

I working on some WS2811 pixels using a ESP8266, I have a web interface where I can test the colours, and set the RGB order (WS2811 are GRB) and the Master Intensity

The below function just populates an array of a single colour, and calculates the Intensity

bool testColour(String RGBIin){
  uniSize = 512;
  DynamicJsonBuffer jsonBuffer;
  JsonObject& json = jsonBuffer.parseObject(RGBIin);
  if (!json.success()) { Serial.println(" * Failed to parse JSON file");
    webSocket.broadcastTXT("status=Test colour FAILED");
    return false;
  }
  JsonArray& RGBI = json["colourval"].asArray();
  DataStuct.Mst_Int = RGBI[3]; // scale of 0 to 100
  float I = (DataStuct.Mst_Int/100);
  for (int t = 0; t < uniSize; t+=3) {
    uniData[t]   = round(int(RGBI[0])*I);  
    uniData[t+1] = round(int(RGBI[1])*I); 
    uniData[t+2] = round(int(RGBI[2])*I); 
  } 
  sendWS();  
}

When sendWS gets called it loops through the array, but before sending out the data it puts them in the correct order (ie from RGB to GRB)

void updateLEDs(PixOrd SelPixOrd) {  
  switch (SelPixOrd) {
    case RGB:     
      rgbOffset[0] = 0;
      rgbOffset[1] = 0;
      rgbOffset[2] = 0;
      break;
    case GRB:
      rgbOffset[0] = 1;
      rgbOffset[1] = -1;
      rgbOffset[2] = 0;
      break;
  }
}

void ICACHE_FLASH_ATTR sendWS() { 
  updateLEDs(SelPixOrd);
   uint32_t writeBits;
  uint8_t  bitMask, time, dataByte;
  int c =0;
  float I = (DataStuct.Mst_Int/100);
  os_intr_lock();
  for (uint16_t t = 0; t < 512; t++) { // outer loop counting bytes
     // set RGB order 
     dataByte = uniData[t+rgbOffset[c]];
      if (c++==2) { c=0;}
      bitMask = 0x80; // 128
      while (bitMask) {
 	/// deal with output
    }    
  }
  os_intr_unlock();
}

I wanted to move the Intensity from the testColour to sendWS, so in the testColour changed

uniData[t]   = round(int(RGBI[0])*I);  
uniData[t+1] = round(int(RGBI[1])*I); 
uniData[t+2] = round(int(RGBI[2])*I); 

to

uniData[t]   = RGBI[0];
uniData[t+1] = RGBI[1];
uniData[t+2] = RGBI[2];

in the the sendWS changed

dataByte = uniData[t+rgbOffset[c]];

to

dataByte = round(int(uniData[t+rgbOffset[c]])*I);

I am now I'm getting crazy things happening, mainly on the 1st pixel. I know the calculation works as it works in the testColour, I know I have the setting of the dataByte correct as it works before I add the calculation

Anyone got any ideas?

Thanks in advance

One thing I'm confused about. Your 512-byte array contains 170-2/3 pixels. Does the 171st pixel not get a Blue value?

johnwasser:
One thing I'm confused about. Your 512-byte array contains 170-2/3 pixels. Does the 171st pixel not get a Blue value?

You are correct in your assumption, however. If the data in coming in via Art-net, the Art-Net sends the correct uniSize. So I'm using Jinx, so if a set the output 170 pixels, the Art-Net sends uniSize with it, ie 510

If I'm using the test, I set the size else where uniSize = (pixCount*3);

I never got over the above problem why this would not do the calculations within the main loop, so I have had to call a function just before I start to process the data, an unnecessary call but it works.

void updateIntensity() {
  float I = (DataStuct.Mst_Int / 100);
  for (uint16_t t = 0; t < uniSize; t++) {
    uniData[t] = round(int(uniData[t]) * I);
  }
}

Another thing that looks like it might cause a problem:

      if (c++==2) { c=0;}

I would be worried that the post-increment might happen AFTER the assignment, like this:

      if (c==2) { c=0;}
      c++

This would count 0, 1, 2, 1, 2, 1, 2...
It is safer to NOT use post-increment or post-decrement in a statement where the same variable is assigned a new value.

      c = (c+1) %3;  // count 0, 1, 2, 0, 1, 2...