Arduino based incubator - hangs - SOLVED - power supply issues

Hello all,
This is my first post to the forum, so greetings all.
For my first Arduino project, I tried automating the chicken egg incubator I built last year. Since the humidity level was hard to control, I used the PID library and a relay to control an ultrasonic fogger. Relative humidity is very accurately measured using a Sensirion SHT15 sensor with the Sensirion library. Most importantly, temperature is (and was) controlled by a commercial PID controller.

Some pictures:

I had no previous experience with C, only limited knowledge of Turbopascal.
I use an LCD screen from Wulfden to display information about temperature and humidity. Temperature and humidity values are stored as arrays of bytes, from which I calculate average, minimum and maximum values.
It’s been a lot of work, reading and debugging to get to this point, where my incubator is up and running, with 120 (180 max) chicken eggs inside.
Setpoint for humidity is now 58%, the PID algorithm manages to stay within 1% of that value.

One problem remains: my Arduino Uno keeps freezing, and I don’t know why. My arrays are global variables, so my code should be able to perform calculations on them right?

Then I thought it was maybe a RAM issue, so I now store my text strings in flash memory. Didn't help.

Then I moved most of my functions to the main loop, didn't help ether.

The only “solution” I have found so far, is to make watchdog timer automatically reset my Arduino if it hangs after 8 s. But I'd like to dig to the root of the problem, because my min/max values of the last 24 hours are worthless, and because I'd like to automate the turning of the trays.

Any hints what the source of those crashes could be? Or tips for a debugging strategy? The crashes seem to occur randomly, after a few hours. The longest time the incubator ran was 6 hours. I’ll post my code below.
Thanks for your help,

Wouter

#include <PID_v1.h>
#include <Sensirion.h>              
#include <avr/wdt.h>
#include <MemoryFree.h>


const byte RELAYPIN = 6;                //fog machine
const byte DATAPIN = 2;                 // SHTxx serial data
const byte SCLKPIN = 3;                 // SHTxx serial clock
const byte LCDPIN = 1;                 
const byte AUTOTURNPIN = 7;             //switch to choose RH setpoint

const unsigned long TRHSTEP = 10000;    // measure RH every 10 s
const unsigned long LCDTEMP1 = 0;       //8s temp display
const unsigned long LCDTEMP2 = 8000;
const unsigned long LCDHUM1 = 16000;    //8s RH display
const unsigned long LCDHUM2 = 24000;    //8s RH display
const unsigned long LCDTURN = 32000;    //8s 
const unsigned long LCDPID = 40000;     //8s pidinfo 
const unsigned long LCDSTOP = 48000;

float PTERM = 2.00;
float ITERM = 0.50;
float DTERM = 1.00;


double Setpoint, Input, Output;

unsigned int rawData;
float temperature;
float humidity = 90.0;
byte measActive = false;
byte measType = TEMP;

unsigned long windowSize = 120000;                 //in milliseconds, pid windowsize 2 minutes, so pid output ranges from 0 s to 120 s
unsigned long windowStartTime;
unsigned long rhMillis = 0;            
unsigned long curMillis=0;
unsigned long lcdMillis=0;
unsigned long timevalue=0;

Sensirion sht = Sensirion(DATAPIN, SCLKPIN);
PID mijnPID(&Input, &Output, &Setpoint,PTERM,ITERM,DTERM, DIRECT);

float humidity1Minute[6] = {
  50.0,50.0,50.0,50.0,50.0,50.0};
byte hum1MinIndex = 0;
float averageHum1Min = 50.0;
byte humidity1Hour[60] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte hum1HourIndex = 0;
byte humidity24Hours[24] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte hum24HourIndex = 0;
byte temperature1Minute[6] = {
  0,0,0,0,0,0};
byte temp1MinIndex = 0;
byte temperature1Hour[60] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte temp1HourIndex = 0;
byte lcdState = 5;
boolean fillUpArray = true;

byte averageTemp1Minute = 0;
byte maxTemp1Minute = 0;
byte minTemp1Minute = 0;
byte averageTemp1Hour = 0;
byte maxTemp1Hour = 0;
byte minTemp1Hour = 0;
byte averageHum1Hour = 0;
byte minHum1Hour = 0;
byte maxHum1Hour = 0;
byte averageHum24Hours = 0;
byte minHum24Hours = 0;
byte maxHum24Hours = 0;

void setup()
{
  wdt_enable(WDTO_8S);
  averageHum1Min=constrain(averageHum1Min,0.0,100.0);


  Serial.begin(19200);
  delay(20);
  byte stat;
  byte error = 0;
  mijnPID.SetOutputLimits(0,windowSize);                 //minimum 0 seconde fog machine on
  mijnPID.SetSampleTime(10000);          
  windowStartTime = 0;
  mijnPID.SetMode(AUTOMATIC);
  pinMode(RELAYPIN, OUTPUT);
  digitalWrite(RELAYPIN, LOW);

  pinMode(8, OUTPUT);                                   //no autoturn yet
  pinMode(9, OUTPUT);
  digitalWrite(8, LOW); 
  digitalWrite(9, LOW);  

  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  wdt_reset();
  showString(PSTR("?f?n"));
  showString(PSTR("***tok**tok**tok****"));
  delay(2000);
  showString(PSTR("********************"));
  showString(PSTR("Bezig met opstarten "));
  showString(PSTR("********************"));
  showString(PSTR("You toking to me??"));
  delay(3000);
  lcdMillis = millis();
}

void loop()
{  
  wdt_reset();
  curMillis = millis();                            // Get current time
  if (digitalRead(AUTOTURNPIN) == HIGH) Setpoint = 600;  //538 = 55%, 614 = 60%, change humidity setpoint according to switch position
  else Setpoint = 700;                             //70% RH

  pidparameterchange();                            //set pid aggressiveness according to distance from setpoint

  if (curMillis - rhMillis >= TRHSTEP)             // Time for new measurements?
  {      
    digitalWrite(13, HIGH);                       //LED lights up
    measActive = true;
    measType = TEMP;
    sht.meas(TEMP, &rawData, NONBLOCK);          // Start temp measurement
    rhMillis = curMillis;
  }
  if (measActive && sht.measRdy()) 
  {                                              // Check measurement status
    if (measType == TEMP)
    {                                            // Process temp or humi?
      measType = HUMI;
      temperature = sht.calcTemp(rawData);       // Convert raw sensor data
      temperature = temperature - 0.9;
      sht.meas(HUMI, &rawData, NONBLOCK);        // Start humi measurement
    }
    else 
    {
      measActive = false;
      humidity = sht.calcHumi(rawData, temperature); // Convert raw sensor data
      digitalWrite(13, LOW); //led off
      wdt_reset();
      humcalc();                               //calculate humidity
      tempcalc();                              //calculate temperature
    }

    wdt_reset();
    Input = map(humidity,0.0,100.0,0,1023);    // input pid rescaled from 0 to 1023
    mijnPID.Compute();                         //run PID algorithm
    if(curMillis - windowStartTime>=windowSize)  windowStartTime = curMillis;
    if(Output  > curMillis - windowStartTime) digitalWrite(RELAYPIN,HIGH); //should the fogger be on
    else digitalWrite(RELAYPIN,LOW);                                       //or off?

    lcdprint();                                //display one of the 6 different screens

    wdt_reset();
  }
}

void  pidparameterchange()
{
  if (Setpoint-map(humidity,0.0,100.0,0,1023)>100) 
  {
    PTERM = 10.0; 
    ITERM = 1.00;
  }
  else 
  {
    if (Setpoint-map(humidity,0.0,100.0,0,1023)>50) 
    {
      PTERM = 2.0;  
      ITERM = 0.0;
    }
    else 
    {
      PTERM = 0.10; 
      ITERM = 0;
    }
  }
}

void humcalc() //calculate humidity values
{
  humidity1Minute[hum1MinIndex] = floor(humidity+0.5);
  averageHum1Min = 0.0;
  for (int i=0;i<=5;i++)
  {
    averageHum1Min += humidity1Minute[i];
  }
  averageHum1Min /= 6.0; //calculate average humidity in the last minute 

  if (hum1MinIndex==5)
  {  
    hum1MinIndex=0; //reset index

    humidity1Hour[hum1HourIndex] = floor(averageHum1Min + 0.5);

    averageHum1Hour = averageValue (59, humidity1Hour);
    minHum1Hour = minimumValue (59, humidity1Hour);
    maxHum1Hour = maximumValue (59, humidity1Hour);
    if (hum1HourIndex == 59)   //fill next level
    {
      hum1HourIndex = 0; //reset index

      humidity24Hours[hum24HourIndex] = averageHum1Hour;

      averageHum24Hours = averageValue (23, humidity24Hours);
      minHum24Hours = minimumValue (23, humidity24Hours);
      maxHum24Hours = maximumValue (23, humidity24Hours);

      if (hum24HourIndex == 23) hum24HourIndex = 0;       //reset index
      else hum24HourIndex++;
    }
    else hum1HourIndex++;
  }
  else hum1MinIndex++;
}
byte averageValue (byte maxIndex, byte array[])   //calculate average value from an array of bytes
{
  float average = 0.0;
  byte result;
  for (int i=0;i<=maxIndex;i++)
  {
    average += array[i];      
  }
  average/=(maxIndex+1);
  result=constrain(result,0.0,100.0);
  result = floor(average+0.5);
  return result;
}


byte minimumValue (byte maxIndex, byte array[])  //calculate minimum value from an array of bytes
{
  byte result;
  result = array[0];
  for (int i=1;i<=maxIndex;i++)
  {
    if(array[i]<result) result=array[i];    
  }
  return result;
}

byte maximumValue (byte maxIndex, byte array[]) //calculate maximum value from an array of bytes
{
  byte result;
  result = array[0];
  for (int i=1;i<=maxIndex;i++)
  {
    if(array[i]>result) result=array[i];    
  }
  return result;
}

void tempcalc() //calculate temperature values
{
  float temp = 0.0;
  temp = floor(temperature*10.0+0.5);
  temp = constrain(temp,166,421);
  temperature1Minute[temp1MinIndex]=map(temp,166,421,0,255);
  averageTemp1Minute = averageValue(5, temperature1Minute);
  maxTemp1Minute = maximumValue(5, temperature1Minute);
  minTemp1Minute = minimumValue(5, temperature1Minute);   

  if (temp1MinIndex == 5)
  {
    temp1MinIndex = 0;                                             //reset index
    temperature1Hour[temp1HourIndex] = averageTemp1Minute;

    if (fillUpArray)  fillarrays();//fill arrays with values 1 min after startup
    averageTemp1Hour = averageValue(59, temperature1Hour);
    maxTemp1Hour = maximumValue(59, temperature1Hour);
    minTemp1Hour = minimumValue(59, temperature1Hour);

    if (temp1HourIndex == 59) temp1HourIndex = 0;
    else temp1HourIndex++; 
  }
  else temp1MinIndex ++;     
}

void fillarrays() //fills arrays with first measurement 1 min after boot-up, run only once
{
  for (int i=0;i<=59;i++)
  {
    humidity1Hour[i]=humidity1Hour[0];
  }
  for (int i=0;i<=23;i++)
  {
    humidity24Hours[i]=humidity1Hour[0];
  }
  averageHum24Hours = averageValue (23, humidity24Hours); //calculate 24 h values right after boot-up
  minHum24Hours = minimumValue (23, humidity24Hours);
  maxHum24Hours = maximumValue (23, humidity24Hours);
  for (int i=1;i<=59;i++)
  {
    temperature1Hour[i]=temperature1Hour[0];
  }
  fillUpArray = false;
}

void lcdprint()  //display temperature, humidity and time online
{
  timevalue = curMillis - lcdMillis;

  if (timevalue > LCDTEMP1 && timevalue < LCDTEMP2 && lcdState!=0) //temp display
  {
    showString(PSTR("?f"));
    showString(PSTR("Temperatuur   "));
    float temp = 0.0;
    temp = map(averageTemp1Minute,0,255,166,421)/10.0;
    Serial.print(temp,1);  
    showString(PSTR("?0C**   Nu "));
    Serial.print(temperature);
    showString(PSTR("?0C   **"));
    showString(PSTR("Max 1m: "));
    temp = map(maxTemp1Minute,0,255,166,421)/10.0;
    Serial.print(temp,1);
    showString(PSTR("?0C?n"));
    showString(PSTR("Min 1m: "));
    temp = map(minTemp1Minute,0,255,166,421)/10.0;
    Serial.print(temp,1);
    showString(PSTR("?0C"));
    lcdState=0;  
  }

  if (timevalue > LCDTEMP2 && timevalue < LCDHUM1  && lcdState!=1)
  {
    float temp = 0.0;
    showString(PSTR("?f"));
    showString(PSTR("Gem temperatuur 1h: **     "));
    temp = map(averageTemp1Hour,0,255,166,421)/10.0;
    Serial.print(temp,1);  
    showString(PSTR("?0C     **"));
    showString(PSTR("Max: "));
    temp = map(maxTemp1Hour,0,255,166,421)/10.0;
    Serial.print(temp,1);
    showString(PSTR("?0C?n"));
    showString(PSTR("Min: "));
    temp = map(minTemp1Hour,0,255,166,421)/10.0;
    Serial.print(temp,1);
    showString(PSTR("?0C"));
    lcdState=1;
  }

  if (timevalue > LCDHUM1 && timevalue < LCDHUM2 && lcdState!=2)
  {                                                                //display rh
    float temp = 0.0;
    showString(PSTR("?f"));
    showString(PSTR("Rel Luchtvochtigheid"));
    Serial.print(averageHum1Min);
    showString(PSTR("%"));
    showString(PSTR("     Nu "));
    Serial.print(humidity);
    showString(PSTR("%freeRAM "));
    Serial.print(freeMemory());
    showString(PSTR(" / 2048"));
    //showString(PSTR("%Setpoint:?n"));
    //showString(PSTR("**       "));
    //Serial.print(map(Setpoint,0,1023,0,100));
    //showString(PSTR("%      **"));
    lcdState=2; 
  }

  if(timevalue > LCDHUM2 && timevalue < LCDTURN  && lcdState!=3)
  { 
    byte temp = 0;
    showString(PSTR("?f"));
    showString(PSTR("1 uur:    "));
    temp = averageHum1Hour;
    Serial.print(averageHum1Hour);
    showString(PSTR("%?n"));
    showString(PSTR("Min:  "));
    temp = minHum1Hour;
    Serial.print(minHum1Hour);
    showString(PSTR("% Max:   "));
    temp = maxHum1Hour;
    Serial.print(temp);
    showString(PSTR("%"));
    showString(PSTR("24 uur:   "));
    temp = averageHum24Hours;
    Serial.print(temp);
    showString(PSTR("%?n"));
    showString(PSTR("Min:  "));
    temp = minHum24Hours;
    Serial.print(temp);
    showString(PSTR("%"));
    showString(PSTR(" Max:   "));
    temp = maxHum24Hours;
    Serial.print(temp);
    showString(PSTR("%"));    
    lcdState=3; 
  }

  if(timevalue > LCDTURN && timevalue < LCDPID  && lcdState!=4)
  {                                                                  //display time incubator has been online
    showString(PSTR("?f"));
    showString(PSTR("freeRAM "));
    Serial.print(freeMemory());
    showString(PSTR(" / 2048"));
    showString(PSTR("?n  Kast staat al?n"));
    //showString(PSTR("     "));
    Serial.print(curMillis/86400000);
    showString(PSTR("d "));
    Serial.print((curMillis%86400000)/3600000);
    showString(PSTR("h "));
    Serial.print((curMillis%3600000)/60000);
    showString(PSTR("m aan?n"));
    //showString(PSTR("****    aan    *****"));
    showString(PSTR("freeRAM "));
    Serial.print(freeRam());
    showString(PSTR(" / 2048"));
    lcdState=4; 
  }

  if(timevalue > LCDPID && timevalue < LCDSTOP  && lcdState!=5)
  {
    showString(PSTR("?f"));
    showString(PSTR("Instellingen RL PID ")); 
    showString(PSTR("P="));
    float temp = 0.0;
    temp = PTERM;
    Serial.print(temp);  
    showString(PSTR(" I="));
    temp = ITERM;
    Serial.print(temp); 
    showString(PSTR("?n"));
    showString(PSTR("D="));
    temp = DTERM; 
    Serial.print(temp);
    showString(PSTR("?n"));
    showString(PSTR("  Mist aan "));
    temp = Output*100.0/windowSize;
    Serial.print(temp); 
    showString(PSTR(" %"));
    lcdState=5;  
  }     
  if(curMillis - lcdMillis > LCDSTOP) lcdMillis = curMillis;
}

void showString (PGM_P s)                              //store strings in flash memory
{
  char c;
  while ((c = pgm_read_byte(s++)) != 0)
    Serial.print(c);
}

int freeRam ()                                         //returns free RAM
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

One likely culprit is array bounds violations. It looks like you're using constrain statements to defend against that, but your usage is not correct. Constrain returns the contstrained number, it doesn't change the value it is passed. So this:

  constrain(hum1MinIndex,0,6);

Should be this:

  hum1MinIndex=constrain(hum1MinIndex,0,6);

You might want to grab one of the freemem functions regularly posted here to see how much RAM you have left. Given that you've started moving strings to progmem with no effect, it likely isn't an issue, but it might give you the necessary comfort to consider moving code back into individual functions again.

wildbill, thank you for your suggestions, much appreciated.

I followed your suggestion and corrected my contrains:

  hum1MinIndex=constrain(hum1MinIndex,0,5); //constrain indexes
  hum1HourIndex=constrain(hum1HourIndex,0,59);
  hum24HourIndex=constrain(hum24HourIndex,0,23);
  temp1MinIndex=constrain(temp1MinIndex,0,5);
  temp1HourIndex=constrain(temp1HourIndex,0,59);
  
  lcdState=constrain(lcdState,0,5);
  averageHum1Min=constrain(averageHum1Min,0.0,100.0);

This now reflects the actual sizes of all the arrays, so no more array bounds violations I hope.
I updated my code above.

I also added two different freeRam functions I found online:

#include <MemoryFree.h>

Serial.print(freeMemory());

and

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 

Serial.print(freeRam());

I'll upload this afternoon, and report back here.
Fingers crossed and thanks again!

I followed your suggestion and corrected my contrains...This now reflects the actual sizes of all the arrays, so no more array bounds violations I hope.

I really don't see how constraining what should be constants is going to help anything. Personally, I think trying to just screams "clueless". Just assign the variable the correct value in the first place.

It's not like you are constraining things in loop, where there might be value added doing so.

  if(curMillis - windowStartTime>windowSize)  windowStartTime += windowSize;

Adding time variables is a bad idea.

Some comments in the code, on the other hand, would be a good idea, as would using Tools + Auto Format to correct the inconsistent indenting.

A lot of the stuff in loop() should be put in functions.

Hello,

correcting the constraints didn't work. When I came back from work, I noticed the Arduino crashed after 4 hours and 40 minutes.

The free RAM functions tell me I have 1500 bytes of RAM available after startup, so no problems there.

PaulS: Thank you for your comments. Maybe you're right about clueless. But hopeless is maybe a better word. :smiley:
I've checked my code so many times now, and I really don't see where I would violate my array bounds. So I removed the constrains.

Adding time variables is a bad idea.

Aha! A bad idea I didn't code myself! That piece of code comes from the PID Library Relay Output Example

I've changed

     if(curMillis - windowStartTime>windowSize)  windowStartTime += windowSize;
     if(Output  >= curMillis - windowStartTime) digitalWrite(RELAYPIN,HIGH);
     else digitalWrite(RELAYPIN,LOW);

to

    if(curMillis - windowStartTime>=windowSize)  windowStartTime = curMillis;
    if(Output  > curMillis - windowStartTime) digitalWrite(RELAYPIN,HIGH);
    else digitalWrite(RELAYPIN,LOW);

Would that be allright?
I've updated my code above, formatted (thanks for the tip) and restored functions / added more comment.

Wouter

What do you see on the Serial monitor when it crashes? Can you put in some more debugging strings to isolate the area that's causing it?

Unfortunately I can only connect it to my netbook when I'm arround (it's at my aunt's place).
Also, serial monitor displays only gibberish, since I'm using pin 1 to drive my LCD, at 19200 baud (incompatible with serial monitor?).
So I can only display debug messages on the LCD. Like the amount of free RAM you suggested, still around 1485 bytes after about an hour.

The strange thing is that it only happens after 4 to 6 hours. I really don't understand why it never happens sooner? I did notice earlier, now that I divided my code over a few functions, that loop takes longer to complete, causing timevalue to miss one of the LCD screens (the fifth one, who shows the time the incubator has been online). So I had to increase the time interval each screen is displayed from 8 to 12 seconds.

Thanks again for all the help,

PaulS:

  if(curMillis - windowStartTime>windowSize)  windowStartTime += windowSize;

Adding time variables is a bad idea.

But that's adding an interval to a timestamp to get a new later timestamp, nothing wrong with that at all.

Crashes can be caused by power supply glitches, or electrical noise, not just software problems. Try monitoring the power source when the outputs switch and check that the relay coil has a flyback diode fitted.

So I had to increase the time interval each screen is displayed from 8 to 12 seconds

That's disturbing - could that be causing an issue with not resetting the watchdog timer soon enough as well? Also, what on earth is consuming that time?

On the topic of missing screens of LCD data, I'd be inclined to just flip to the next one every eight seconds, rather than using multiple measures such as LCDHUM2. I don't believe it's causing a problem, but it would make the code a little simpler.

Can you use softwareserial for the LCD and reserve the serial port for debug? Although it sounds like you're not going to be around to capture that data anyway. Somehow you need to be able to indicate where you were when it crashed. Is the watchdog masking your ability to tell?

Well the last version of my code seems a bit more stable, runs for about 12 - 16 hours before it crashes.

MarkT:
Crashes can be caused by power supply glitches, or electrical noise, not just software problems. Try monitoring the power source when the outputs switch and check that the relay coil has a flyback diode fitted.

Hi Mark, the relay has all the bells and whistles (transistor, LED, diode), it's from a kit I bought on ebay. Furthermore, I'm not switching the 220 V -> 24 V AC transformer on and off that powers the ultrasonic fogger. The transformer is always on, I switch the output (24 V AC ~ 1 amp). It also switches only once every two minutes.

My Arduino is powered by a beefy 7805 voltage regulator, which gets 12 Volts at 5 A maximum from a switching power supply I bought, originally to power the motor to turn the trays. It used to be on it's own 9 V PSU, it crashed back then as well.

wildbill:
That's disturbing - could that be causing an issue with not resetting the watchdog timer soon enough as well? Also, what on earth is consuming that time?

I wonder as well. But untill the eggs hatch the dog is my best friend: before I configured wdt, the Arduino froze, not regulating humidity for hours. Now it's just an annoyance.

On the topic of missing screens of LCD data, I'd be inclined to just flip to the next one every eight seconds, rather than using multiple measures such as LCDHUM2. I don't believe it's causing a problem, but it would make the code a little simpler.

I'll write some switch case code to control the LCD, thanks for the tip.

Can you use softwareserial for the LCD and reserve the serial port for debug? Although it sounds like you're not going to be around to capture that data anyway. Somehow you need to be able to indicate where you were when it crashed. Is the watchdog masking your ability to tell?

I'll put my code full off serial.prints, then run the incubator with my pc attached untill it freezes. Hopefully, that way we can figure out what it was doing when it crashed... This will have to wait untill hatch time I'm afraid.

Good luck... BTW those eggs look smaller than the ones in Jurassic Park :wink:

Not as much of a fan of some constrain function as you are (maybe Paul is on my side with this too). You need to be aware of what you set the array indices to instead of constrain them in case of overflow. I'd get rid off all these constrain function before asking again what's wrong with the code.

BTW, you constrained the hum1MinIndex to 0-6 but you only have 6 element in the relevant array so once hum1MinIndex==6 you destroy the chicken world. Good work giving the chicken the inevitable. They should chant iiagdtd ]:slight_smile:

Before you rule out power issues completely, consider whether the mains power you're getting is ok. I recall another troubleshooting thread where the eventual problem turned out to be a very old fridge. When the compressor kicked in, it caused all sorts of issues for the electronics plugged in on the same circuit.

Good luck... BTW those eggs look smaller than the ones in Jurassic Park smiley-wink

Yes, fortunately. When they are 5 months old they still need to fit in my homebuilt plucker.

Before you rule out power issues completely, consider whether the mains power you're getting is ok. I recall another troubleshooting thread where the eventual problem turned out to be a very old fridge. When the compressor kicked in, it caused all sorts of issues for the electronics plugged in on the same circuit.

wildbill, thank you for that remark. Especially the part about the old fridge, because:

One likely culprit is standing there! But I noticed before the lights flicker heavily when inductive loads get switched on...
I placed a 2200 µF capacitor parallel to the output of my power supply and voila. No more reboots for the last 4 days.

Thank you so much!

Cromp:
I placed a 2200 µF capacitor parallel to the output of my power supply and voila. No more reboots for the last 4 days.

Hey. I have the same problem right now with a heavy load circuit causing my arduino to hang. im using a usb adapter and a usb cable to power it. how would i go about putting the capacitor parallel to the usb power output?

i'd appreciate any help. thanks!

Add it from the 5V pin to one of the ground pins. If its too big a capacitor its conceivable the USB supply could trip out (more likely for an actual computer/laptop than a wall-wart supply).

[BTW there is already 47uF on 5V rail on the standard Arduino]

MarkT:
Add it from the 5V pin to one of the ground pins. If its too big a capacitor its conceivable the USB supply could trip out (more likely for an actual computer/laptop than a wall-wart supply).

[BTW there is already 47uF on 5V rail on the standard Arduino]

thanks for your help. ill give it a shot later today and post results.
Here is the original thread with my issue for reference.