Code corrupting / locking up on a Arduino Pro Mini (5v) attached to a color sensor and Neopixel.

Quickly, here’s my set up. This is part of an interactive for children. When it works it works great.

Arduino Pro Mini (5v) hooked up to an Adafruit color sensor and a Neopixel Ring. I’ve posted this on the Adafruit forum and the admin seems to think it’s an Arduino Pro Mini issue.

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. The reset button does nothing, power cycling does nothing. 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 6 times over the last 4 months.

Any clue what could be going on here? I’m at a complete loss and in a situation where I can’t keep reloading the sketch every time this happens. I’ve been banging my head against the wall for weeks. :frowning:

ANY HELP ON THIS IS GREATLY APPRECIATED!!!

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


// 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
// 24 pixels on pin 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 6, NEO_GRB + NEO_KHZ800);


void setup() {



strip.begin();
strip.show();

 

   
  if (tcs.begin()) {
    Serial.println("Found sensor");
    {
      
       for(int i = 0; i < 25 ; i++)
    strip.setPixelColor(i, strip.Color(10, 80, 10));
   strip.show(); 
   delay(2000);
      }
  } else {
    {
   for(int i = 0; i < 25 ; i++)
    strip.setPixelColor(i, strip.Color(100, 10, 0));
   strip.show(); 
   

}
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!

  
  
  
  }



  // 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);



  // 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;

}

I would suspect power issues before the Pro Mini. Mine run for years without problems.

Spikes on the power lines can easily cause the MCU to malfunction, with random timing, if power is shared with the switched LED modules without proper decoupling. The problem is especially serious if you have long leads to the power supplies. See this tutorial: https://www.pololu.com/docs/0J16

You could try powering the MCU(s) separately, with a well filtered 5V power supply applied to “5V”, not Vin. Make sure all the grounds are connected with solid wiring. Avoid breadboards like the plague.

Hi @tfraley,

How much memory is spare with this sketch? I’ve had unpredictable Arduino crashes on a project with too many libraries and not enough bytes remain. Sorry can’t put numbers on it.

You could reduce memory use by:

Gammatable is not altered in the program so take the code that initialises it, run it on a PC, get a list of numbers and initialise gammatable with e.g. = {27,99… etc. Google the F() function and move gammatable into progmem. (Check bytes saved at each stage.)

float r, g, b; - do you really need the precision of float here? If you change that to int does it work as well? That might be the only floats in the sketch (I’m don’t know what’s in the libraries). If you have no floats that saves some memory (no floating point routines).

Thanks for the reply. As far as my sketch size goes I’m only using 30% of the space. I follow some of what your saying (my background is in art unfortunately, I’m just trying to struggle through this).

What I don’t understand is even if it was a memory problem or a power supply issue, as suggested in the prior answer, wouldn’t I be able to get things up and running again simply by power cycling or hitting the reset button? I’m basically dead in the water until I re-load the code using the FTDI cable.

A friend who uses these was wondering if a bad batch of flash memory might be to blame? I did buy 50 of these all at the same time for this project so the odds of getting some chips from the same bad batch would be higher… Super frustrating.

tfraley:
I did buy 50 of these all at the same time for this project so the odds of getting some chips from the same bad batch would be higher…

Are any of your other boards doing the same thing?

Only 30% used so agree, memory full is unlikely to be the problem.

A common problem is that when the load switches off and on the power supply voltage goes up and down a little. In bad situations this can be enough to upset the controller. Have you wired 5v and 0v with 2 wires PSU to Ard, and 2 separate wires PSU to LED ring? (Separate PSU better as @jremington says) I don’t know the current values in your setup, but 1.8A allowance seems enough. Do you change brightness abruptly? What if more than one ring switched together? can that cause a problem? What if you put in a test program that switches full on/full off, synchronised by one Ard controlling the others by a temporary wire linking a spare digital?

I think faulty items are unlikely. You could swap suspect ones out, and spares in. You have to keep good records of item numbers, locations and failures.

When you say " In bad situations this can be enough to upset the controller." do you mean upset the controller so badly it needs the sketch reloaded though? I’ve never had a project where I had to re-loaded sketches like this for the controller to even work again. Normally a reset or power cycle does the trick. These are dead as a door nail until I plug them into my computer and reload the sketch.

Can’t exactly remember but probably just a reset fixed it didn’t require reload. I’ve just googled “can arduino corrupt program” and people think it can.

(You haven’t said how the 5v+0v is wired?) How are you programming? via usb-ttl adaptor? There is another method https://mithatkonar.com/wiki/doku.php/a … bootloader. We don’t know that the bootloader is the problem, but this would remove it.

You could set your 10 spares running 24/7. Fake the signals so they are doing as much as possible.