Code corruption? Thoughts?

Quickly, here's my set up.

Arduino Pro mini hooked up to an Adafruit color sensor and a Neopixel Ring

There's 10 of them all drawing 5v in parallel from a Meanwell 5v18a power supply. This is plugged into a surge protector.

I have this setup x4 so basically there's 40 of these going.

The concept is you place a colored piece of paper in front of the sensor and as long as that paper is there the Neopixel stays that color.

Overnight the power supply is unplugged then runs for around 10 hours the next day.

Everything runs fine except periodically the arduino will just stop responding and the neopixel is unlit. If I re-upload the code to the arduino pro it will work fine again, almost like the code is getting corrupted somehow? Out of the 40 units it has happened 4 times over the last 3 months.

Any clue what could be going on here? I'm at a loss.

Without seeing any code we can only offer generalities.

The behavior that you describe can be caused by reading and/or writing beyond the bounds of an array. Examine all array operations to make sure that that is not happening.

Using the String class can cause memory problems that can lead to crashes.

Or just running out of SRAM.

Read the forum guidelines to see how to properly post code.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Here's the code being used. It's kinda cobbled together from a couple different sources and TBH I'm not 100% certain about what some of it does. My background is in art and I'm just trying to get this done as part of a children's interactive piece so yeah, i'm a bit lost/frustrated.

Would REALLY appreciate any input or possible fixes you have for this code though!


#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <Adafruit_NeoPixel.h>
#include "Flora_Pianoglove.h"


// we only play a note when the clear response is higher than a certain number 
//#define CLEARTHRESHHOLD  1300


// our RGB -> eye-recognized gamma color
byte gammatable[256];

// color sensor
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_2_4MS, TCS34725_GAIN_4X); // integreation times can be 2_4MS, 24MS, 50MS, 101MS, 154MS, 700MS -gain can be 1X, 4X, 16X, 60X
// one pixel on pin 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 6, NEO_GRB + NEO_KHZ800);


void setup() {




  /*

  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }

  */

  
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  // thanks PhilB for this gamma table!
  // it helps convert RGB colors to what humans see
  for (int i=0; i<256; i++) {
    float x = i;
    x /= 255;
    x = pow(x, 3.3); //WAS 3.3
    x *= 255;
      
    gammatable[i] = x;      

    //Serial.println(gammatable[i]);
  }
  
}

void loop() {


   

  uint16_t clear, red, green, blue;


  delay(80);  // takes 50ms to read 

  
  tcs.getRawData(&red, &green, &blue, &clear);
  delay(40);

 /* // not close enough to colorful item
  if (clear < CLEARTHRESHHOLD) {
    for(int i = 0; i < 25 ; i++)
    strip.setPixelColor(i, strip.Color(22, 222, 0)); // turn off the LED
    strip.show();
    return;
  }*/



  // Figure out some basic hex code for visualization
  uint32_t 
  sum = red;
  sum += green;
  sum += blue;
  sum = clear;
  float r, g, b;
  r = red; r /= sum;
  g = green; g /= sum;
  b = blue; b /= sum;
  r *= 620; g *= 555; b *= 510; //HERE IS WHERE WE LIVE NOW WAS 255, 240, 220
  if (r > 255) r = 255;
  if (g > 255) g = 255;
  if (b > 255) b = 255;
  


 

  // OK we have to find the two primary colors
  // check if blue is smallest. MEME: fix for 'white'
  float remove, normalize;
  if ((b < g) && (b < r)) {
    remove = b;
    normalize = max(r-b, g-b);
  } else if ((g < b) && (g < r)) {
    remove = g;
    normalize = max(r-g, b-g);
  } else {
    remove = r;
    normalize = max(b-r, g-r);
  }
 // get rid of minority report
  float rednorm = r - remove;
  float greennorm = g - remove;
  float bluenorm = b - remove;
  // now normalize for the highest number
  rednorm /= normalize;
  greennorm /= normalize;
  bluenorm /= normalize;


  
  for(int i = 0; i < 25 ; i++)
{
   strip.setPixelColor(i, strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]));
}
strip.show();

 delay(20);

 
  

 
}





RgbColor HsvToRgb(HsvColor hsv)
{
    RgbColor rgb;
    unsigned char region, remainder, p, q, t;

    if (hsv.s == 0)
    {
        rgb.r = hsv.v;
        rgb.g = hsv.v;
        rgb.b = hsv.v;
        return rgb;
    }

    region = hsv.h / 43;
    remainder = (hsv.h - (region * 43)) * 6; 

    p = (hsv.v * (255 - hsv.s)) >> 8;
    q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
    t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;

    switch (region)
    {
        case 0:
            rgb.r = hsv.v; rgb.g = t; rgb.b = p;
            break;
        case 1:
            rgb.r = q; rgb.g = hsv.v; rgb.b = p;
            break;
        case 2:
            rgb.r = p; rgb.g = hsv.v; rgb.b = t;
            break;
        case 3:
            rgb.r = p; rgb.g = q; rgb.b = hsv.v;
            break;
        case 4:
            rgb.r = t; rgb.g = p; rgb.b = hsv.v;
            break;
        default:
            rgb.r = hsv.v; rgb.g = p; rgb.b = q;
            break;
    }

    return rgb;
}

HsvColor RgbToHsv(RgbColor rgb)
{
    HsvColor hsv;
    unsigned char rgbMin, rgbMax;

    rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
    rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);

    hsv.v = rgbMax;
    if (hsv.v == 0)
    {
        hsv.h = 0;
        hsv.s = 0;
        return hsv;
    }

    hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
    if (hsv.s == 0)
    {
        hsv.h = 0;
        return hsv;
    }

    if (rgbMax == rgb.r)
        hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
    else if (rgbMax == rgb.g)
        hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
    else
        hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);

    return hsv;

}

Your gamma seems high at 3.3. I've used a gamma of 2, and found it to work well with LEDs. As a power of two is simply a number multiplied by itself, the computation is a lot less intensive.

Do you really need to re-upload, meaning a reboot or cold start is not doing the job?

At a quick glance, the code doesn't have the obvious problems that sometimes cause intermittent failures. I would look at hardware.

Hitting the reset button and/or disconnecting then reconnecting power did no good. On a whim I re-uploaded the code to one of the 'dead' units and it was right back to normal. I'm perplexed.

Yes, and one subtle difference is the time taken. Pressing the reset button restarts without power loss. An upload usually involves disconnection and reconnection. This means that if something is overheating, an upload may work while a reset won't.

I was getting the best color results with that 3.3 but I could try a gamma of 2. We are trying to as closely replicate the color of the slips of paper as possible. They are shining into these frost acrylic orbs.

The main point of using gamma=2 is for speed. If you don't need that, then don't fix what ain't broke.

Gotcha gotcha. Look I'm learning! :sweat_smile:

In this case they are pretty much the same I think though because the issue will be there first thing in the morning after being powered down all night though.

A cold start :wink:
May be that gives time to a polyfuse to reset

Rats. That is a real mystery then. Thought - when you only reset, the LEDs remain on... FWIW

Right?? The way these will run literally for months, get disconnected from power every night then seemingly out of the blue one will just not respond one morning is so frustrating. My heart literally drops.

Yeah and in this case they are dark/off.

But - that is only in the morning, after boot up. Have you ever seen an already operational one freeze? My thought is, maybe the start up process is broken.

I've never seen it happen in the moment no. TBH it could happen midday (I'm not there watching it). I just know that first thing in the morning I will plug it in and the LED's are dark, even if I unplug and replug a couple times.

That was going to be my next question. But, the power supply may not drain completely between power cycles. Have you ever seen it at the end of the day, assuming you are there at that time?

That's true there are likely some beefy caps in there. Do you think a bad power supply could cause an issue like this? A spike of some sort etc. Could it somehow knock an arduino offline in this manner? I know 2 of the problem arduinos were on the same power supply (not sure about the 3rd a college fixed it for me).