Arduino Freezes Randomly, Memory Issue?

Hello All,

I've been looking through this site for a while now to help me out with various projects and the old posts have been immensely helpful. I have a new problem that I have been fighting by myself for about a month and a half now and i am no closer to figuring it out than when i started. Unfortunately my programming is self taught and more than likely a little rough. It works, for the most part, but after about 4-12 hours of running the program just freezes. No serial updates, nothing. (This is bad because it is controlling an oven, so if it freezes with the oven on, well you guess what happens). I do have a temperature cutout to prevent any catastrophic run-aways.

I first thought that my power supply was noisy, but i have tried many including a $2000 lab grade DC power supply. I thought it might be my arduino board, i was using a Ocean Controls KTA-223 board, switched to a genuine arduino uno with a transistor shield Link and some externally powered relays and it ran for a week and a half straight. I thought great, its fixed. But it just started acting up again a week ago and now it cant run 4 hours or so without freezing.

The only constant hardward are two Sparkfun MAX31855K Thermocouple boards Link and one sparkfun ACS723 current monitor. Link I am using the adafruit MAX31855K library (Because it allows me to select a chip and use the same data lines), and the sparkfun ACS723 just runs off an analog input.

I am almost certain it is not a hardware issue, because everything but the above chips have changed with the same result. The way the serial monitor prints, it makes me think there is memory issues, either stuff being overwritten, or just running out of ram. I do not know enough about that side of programming though. I have added the F macro to some constant serial prints to move then to flash memory instead of SRAM. Its not a big program so i cant picture why im running out of anything...

Any help here would be great! Post 2 will follow up with photos.

/*
  Measuring AC Current Using ACS712,  Measuring Temperature with Sparkfun MAX31855
*/
#include "Adafruit_MAX31855.h" // Using the max31855k driver
#include <SPI.h>

int MAXCLK = 13;  //TC Clock Pin
int MAXCS = 10;  // TC 1 Chip Select Pin
int MAXCS2 = 11;  // TC 2 Chip Select Pin
int MAXDO = 12;  //TC data out pin
Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);  //Define pins per Adafruit Library
Adafruit_MAX31855 thermocouple2(MAXCLK, MAXCS2, MAXDO); //Define pins per Adafruit Library

float temp = 0;  //Variable for TC 1 data
float temp2 = 0;  //Variable for TC 2 data

const int sensorIn = A2;  //Current sensor Analog input
int mVperAmp = 410;  //Trim variable to make voltage to current calcs correct
double Voltage = 0; //Voltage variable for current monitor  (It reads a voltage and converts to current)
double VRMS = 0;  //Voltage variable for current monitor after converting to RMS
double AmpsRMS = 0; //current value through thermal links DUT

int settemp = 110;  //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE
int heaterrelay = 3;   //oven relay controller through transistor shield
int loadrelay = 6;  // load is circuit inside oven with 2.0A on it with thermal links i am testing
int indicatorrelay = 5;  //indicator is an LED strip to indicate a thermal link has failed
double loadcurrent = 0.2; //highest current in error state, anything higher will function normally
int settemp2 = settemp - 4;  //temp trim to reduce setpoint 4 degrees
int settemp3 = settemp - 4; //temp trim to reduce setpoint 4 degrees
int once = 0;
long previousMillis = 0;

void setup() {
  Serial.begin(9600);
  pinMode(heaterrelay, OUTPUT);
  pinMode(loadrelay, OUTPUT);
  pinMode(indicatorrelay, OUTPUT);
  delay(3000);
}

void loop() {
  runprogram();  //(Should) Run for 3 days
  cooldown();    // Cools oven for 12 hours
}

void cooldown() {  //12 hour off time
  unsigned long currentMillis = millis();
  unsigned long StartTime = millis();
  while (millis() - currentMillis < 43200000) {
    previousMillis = currentMillis;
    unsigned long CurrentTime = millis();
  }
  Serial.println(F("12 Hour Delay Complete"));
}

void runprogram() { //run for 3 days
  unsigned long currentMillis = millis();

  while (millis() - currentMillis < 259200000) {
    //Serial.println("Back to the beginning...");
    temp = gettemp();
    temp2 = gettemp2();
    while (temp2 > settemp + 16) {//brick temp overshoot
      Serial.print(F("OVEN TOO HOT: "));
      Serial.println(temp2);
      stoprun10();
      temp2 = gettemp2();
    }
    if (temp < settemp3) {
      // Serial.print("Load on   ");
      digitalWrite(loadrelay, HIGH);
      //Serial.print("Before Delay   ");
      delay(500);
      // Serial.println("After Delay");
      Voltage = getVPP();
      //Serial.print(":1");
      VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
      //Serial.print(":2 ");
      AmpsRMS = ((VRMS * 1000) / mVperAmp);
      Serial.print(AmpsRMS);
      Serial.println(" Amps RMS");
      while (AmpsRMS < loadcurrent) {
        if (once == 0) {
          Serial.println(F("LINK BROKEN"));
          once = 1;
        }
        digitalWrite(heaterrelay, LOW);
        digitalWrite(indicatorrelay, HIGH);
        delay(1000);
        digitalWrite(indicatorrelay, LOW);
        digitalWrite(loadrelay, HIGH);
        delay(1000);
        Voltage = getVPP();
        Serial.println(F(""));
        VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
        AmpsRMS = ((VRMS * 1000) / mVperAmp);
        digitalWrite(loadrelay, LOW);
      }
      once = 0;
      digitalWrite(heaterrelay, HIGH);
      stoprun5();
      digitalWrite(loadrelay, LOW);
      digitalWrite(heaterrelay, LOW);
    }

    digitalWrite(heaterrelay, LOW);
    digitalWrite(loadrelay, LOW);
    stoprun10();
  }
  Serial.println(F("3 Day Run Time Complete; Starting 12 Hour Cool Down."));
}

void stoprun5() {
  Serial.print(F("5 Second Oven On Time START"));
  unsigned long currentMillis = millis();
  while (millis() - currentMillis < 5000) {
  }
  Serial.println(F("---> COMPLETE"));
}

void stoprun10() {
  Serial.println(F("10 Second Oven OFF Time START"));
  delay(1000);
  unsigned long currentMillis = millis();
  static unsigned long lastRefreshTime = 0;
  while (millis() - currentMillis < 9000) {
    if (millis() - lastRefreshTime >= 5000)
    {
      lastRefreshTime += 5000;
      temp = gettemp();
      temp2 = gettemp2();
      Serial.print("TemP1[C]=");
      Serial.print(temp);
      Serial.print("      TemP2[C]=");
      Serial.println(temp2);
    }
  }
  Serial.println(F("---> COMPLETE"));
}


double getVPP() {
  //  Serial.print(F("IntoVPPLoop "));
  double result;
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
  int minValue = 1024;          // store min value here
  Serial.print(F("Checking Load Current"));
  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000) //sample for 1 Sec
  {
    readValue = analogRead(sensorIn);
    if (readValue > maxValue)
    {
      maxValue = readValue;
    }
    if (readValue < minValue)
    {
      minValue = readValue;
    }
  }
  result = ((maxValue - minValue) * 5.0) / 1024.0;
  Serial.print(F(":"));
  return result;
}

float gettemp()
{
  MAXCS = 0;
  double c1 = thermocouple.readCelsius();
  MAXCS = 1;
  c1 = c1 - 3.5;                              //temp trim
  return c1;
}

float gettemp2()
{
  MAXCS2 = 0;
  double c2 = thermocouple2.readCelsius();
  MAXCS2 = 1;
  c2 = c2 - 3.5;                              //temp trim
  return c2;
}[\code]

Photos in the google photos album below:

Are you sure that the arduino bugs out and that the problem is not caused by a serial reset or something? I would suggest you to put in a periodic blink with the LED_BUILTIN in order to figure out if the arduino actually craps out.

Another thing is that the "cooldown" method makes no sense, you could substitute it with "delay(43200000UL)", and the same for "stoprun5()". Your "runprogram" method blocks for 3 days while it does its work, this also seems like a "bad idea" :slight_smile:

Hello, Thank you for the feedback. Should I add a 1 second blink in the beginning of runprogram? I had assumed the "Back to the beginning" serial print would determine if it wasn't working but it may just be the serial interface. I would like to note that during the freeze, none of the relays function, and temperatures are not processed.

I have revised "cooldown" to your recommendation, same with "stoprun5". I had assumed millis are the best way to time things.

I am unsure of a solution to your final sentence about "runprogram". Is there another way for it to run for 3 days, and then "cooldown" for 12 hours?

Also, my blink LED will need to be on a different pin, 13 is currently occupied with the clock line and i do not believe i can change that. I can add an external LED to D4-ish. I just don't know where to put the code to make sure its working properly and not freezing.

millis() is the way to go, but not the way you use. The intention is to write code that does not block, but the way you use it with a while-loop, it's still blocking.

Thank You.

If this is changed to an "if" loop, will it still block?

Will it only run through once or will it continue until the if statement is false?

void runprogram() { //run for 3 days
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis <= 259200000) {
    previousMillis = currentMillis;
    //Serial.println("Back to the beginning...");
    temp = gettemp();
    temp2 = gettemp2();
    while (temp2 > settemp + 16) {//brick temp overshoot
      Serial.print(F("OVEN TOO HOT: "));
      Serial.println(temp2);
      stoprun10();
      temp2 = gettemp2();
    }
    if (temp < settemp3) {
      // Serial.print("Load on   ");
      digitalWrite(loadrelay, HIGH);
      //Serial.print("Before Delay   ");
      delay(500);
      // Serial.println("After Delay");
      Voltage = getVPP();
      //Serial.print(":1");
      VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
      //Serial.print(":2 ");
      AmpsRMS = ((VRMS * 1000) / mVperAmp);
      Serial.print(AmpsRMS);
      Serial.println(" Amps RMS");
      while (AmpsRMS < loadcurrent) {
        if (once == 0) {
          Serial.println(F("LINK BROKEN"));
          once = 1;
        }
        digitalWrite(heaterrelay, LOW);
        digitalWrite(indicatorrelay, HIGH);
        delay(1000);
        digitalWrite(indicatorrelay, LOW);
        digitalWrite(loadrelay, HIGH);
        delay(1000);
        Voltage = getVPP();
        Serial.println(F(""));
        VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
        AmpsRMS = ((VRMS * 1000) / mVperAmp);
        digitalWrite(loadrelay, LOW);
      }
      once = 0;
      digitalWrite(heaterrelay, HIGH);
      stoprun5();
      digitalWrite(loadrelay, LOW);
      digitalWrite(heaterrelay, LOW);
    }

    digitalWrite(heaterrelay, LOW);
    digitalWrite(loadrelay, LOW);
    stoprun10();
  }

}

I think that that will be OK; you however now have to call it constantly from loop() and your cooldown() will interfere.

//edit
It has a bug; you should not set previousMillis each time. See below.
// edit end

I did prepare the below to show how I would do it but you posted in the mean time; I did not feel like rewriting it :wink:

If you replace the while by an if and reverse the logic, you will have a non-blocking function

/*
  cool down oven for 12 hours
  Returns:
    true if 12 hours have lapsed, else false
*/
bool cooldown()
{
  // variable to remember the start time of the cooldown
  static unsigned long StartTime;
  // variable to remember if cool down is in progress
  static bool inProgress = false;

  // if cool down not started
  if(inProgress == false)
  {
    // remember start time of cool down
    StartTime = millis();
    // remember that cool down is in progress
    inProgress = true;

    Serial.println(F("12 Hour Delay Started"));
  }

  if (millis() - StartTime >= 43200000UL)
  {
    Serial.println(F("12 Hour Delay Complete"));
    // remember that cool down no longer in progress
    inProgress=false;
    // indicate to caller (loop()) that cool down is complete
    return true;
  }
  else
  {
    // indicate to caller (loop()) that cool down is not complete
    return false;
  }
}

You will need to call this constantly from loop. To be able to do so, I suggest a small state machine where your code can be in one of two modes (states)

void loop()
{
  // program mode (1 = run program, 2 = cool down)
  static byte mode = 1;
  
  switch(mode)
  {
    case 1:
      runprogram();
      // go to cooldown
      mode = 2;
      break;
    case 2:
      if(cooldown()==true)
      {
        // cool down completed; back to runprogram
        mode = 1;
      }
      break;
  }
}

After you modified runprogram in the same way as cool down, you can modify loop()

void loop()
{
  // program mode (1 = run program, 2 = cool down)
  static byte mode = 1;
  
  switch(mode)
  {
    case 1:
      if(runprogram() == true)
      {
        // run program complete; go to cool down
        mode = 2;
      }
      break;
    case 2:
      if(cooldown()==true)
      {
        // cool down completed; back to run program
        mode = 1;
      }
      break;
  }
}

You can modify your other functions that rely on millis() in the same way.

And this would be a blink using the same principles.

void blink()
{
  static uint32_t lastChangeTime = millis();

  if (millis() - lastChangeTime > 1000)
  {
    lastChangeTime += 1000;
    digitalWrite(blinkPin, !digitalRead(13));
  }
}

blinkPin can be anything; once all your code is non-blocking, you can put a call to it in the beginning of loop().

PS
I forgot to ask:
What are the memory statistics reported after verify.
Which board?

Thanks, i will work on the revisions. There are some things you posted that are above my understanding that i will need to research.

The sketch as written uses 6118 bytes (18%), global variables use 273 bytes (13%) of dynamic memory leaving 1775 for local variables.

It is running on an arduino uno.

Pretty small program...

Another note is that you have a lot of debugging with Serial, which is always good. But you should implement it in a way where you can turn it off in order to eliminate the serial interface as being the problem.

//Comment out the following line to disable serial!
#define DEBUG

#ifdef DEBUG
  #define SERIALPRINT(x) Serial.print(x)
  #define SERIALPRINTLN(x) Serial.println(x)
#else
  #define SERIALPRINT(x)
  #define SERIALPRINTLN(x)
#endif

void setup()
{
#ifdef DEBUG
  Serial.begin(9600);
  while (!Serial) ;
#endif

  //Other setup code here
}

void loop()
{
  SERIALPRINTLN(F("If you see this, debugging is enabled"));
  delay(1000);
}

By doing it this way, you can in one place remove all serial printing.

I have it running now, with runprogram(); and cooldown(); being run off the new millis code.

I am unsure how to remove the stoprun delays as they are not referenced back to the main loop, they are only used within runprogram(); The delays in the stoprun functions make the blink odd because they are "blocking" is my understanding. They hold the program and allow it to do nothing else.

/*
  Measuring AC Current Using ACS712,  Measuring Temperature with Sparkfun MAX31855
*/
#include "Adafruit_MAX31855.h" // Using the max31855k driver
#include <SPI.h>

int MAXCLK = 13;  //TC Clock Pin
int MAXCS = 10;  // TC 1 Chip Select Pin
int MAXCS2 = 11;  // TC 2 Chip Select Pin
int MAXDO = 12;  //TC data out pin
Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);  //Define pins per Adafruit Library
Adafruit_MAX31855 thermocouple2(MAXCLK, MAXCS2, MAXDO); //Define pins per Adafruit Library

float temp = 0;  //Variable for TC 1 data
float temp2 = 0;  //Variable for TC 2 data

const int sensorIn = A2;  //Current sensor Analog input
int mVperAmp = 410;  //Trim variable to make voltage to current calcs correct
double Voltage = 0; //Voltage variable for current monitor  (It reads a voltage and converts to current)
double VRMS = 0;  //Voltage variable for current monitor after converting to RMS
double AmpsRMS = 0; //current value through thermal links DUT

int settemp = 110;  //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE //SET OPERATING TEMPERATURE
int heaterrelay = 3;   //oven relay controller through transistor shield
int loadrelay = 3;  // load is circuit inside oven with 2.0A on it with thermal links i am testing
int indicatorrelay = 5;  //indicator is an LED strip to indicate a thermal link has failed
double loadcurrent = 0.2; //highest current in error state, anything higher will function normally
int settemp2 = settemp - 5;  //temp trim to reduce setpoint 4 degrees
int settemp3 = settemp - 5; //temp trim to reduce setpoint 4 degrees
int once = 0;
long previousMillis = 0;
int ledState = LOW;
const int ledPin =  7;


void setup() {
  Serial.begin(9600);
  pinMode(heaterrelay, OUTPUT);
  pinMode(loadrelay, OUTPUT);
  pinMode(indicatorrelay, OUTPUT);
  delay(3000);
}

void loop()
{
  // program mode (1 = run program, 2 = cool down)
  static byte mode = 1;
blink();
  switch (mode)
  {
    case 1:
      if (runprogram() == true)
      {
        // run program complete; go to cool down
        mode = 2;
      }
      break;
    case 2:
      if (cooldown() == true)
      {
        // cool down completed; back to run program
        mode = 1;
      }
      break;
  }
}

bool cooldown()
{
  // variable to remember the start time of the cooldown
  static unsigned long StartTime;
  // variable to remember if cool down is in progress
  static bool inProgress = false;

  // if cool down not started
  if (inProgress == false)
  {
    // remember start time of cool down
    StartTime = millis();
    // remember that cool down is in progress
    inProgress = true;

    Serial.println(F("12 Hour Delay Started"));
  }

  if (millis() - StartTime >= 43200000UL)  //12 hours 43200000UL
  {
    Serial.println(F("12 Hour Delay Complete"));
    // remember that cool down no longer in progress
    inProgress = false;
    // indicate to caller (loop()) that cool down is complete
    return true;
  }
  else
  {
    // indicate to caller (loop()) that cool down is not complete
    return false;
  }
}

bool runprogram()
{ //run for 3 days
  // variable to remember the start time of the runprogram
  static unsigned long StartTime;
  // variable to remember if cool down is in progress
  static bool inProgress = false;

  // if cool down not started
  if (inProgress == false)
  {
    // remember start time of runprogram
    StartTime = millis();
    // remember that runprogram is in progress
    inProgress = true;
    Serial.println(F("3 Day Run Time Started"));
  }
  if (millis() - StartTime >= 259200000UL)  //3 day 259200000UL
  {
    Serial.println(F("3 Day Runtime Complete"));
    // remember that runprogram no longer in progress
    inProgress = false;
    // indicate to caller (loop()) that run program is complete
    return true;
  }
  else
  {
    //Serial.println("Back to the beginning...");
    temp = gettemp();
    temp2 = gettemp2();
    while (temp2 > settemp + 16) {//brick temp overshoot
      Serial.print(F("OVEN TOO HOT: "));
      Serial.println(temp2);
      stoprun10();
      temp2 = gettemp2();
    }
    if (temp < settemp3) {
      digitalWrite(loadrelay, HIGH);
      delay(500);
      Voltage = getVPP();
      VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
      AmpsRMS = ((VRMS * 1000) / mVperAmp);
      Serial.print(F("Checking Load Current:"));
      Serial.print(AmpsRMS);
      Serial.println(" Amps RMS");
      while (AmpsRMS < loadcurrent) {
        if (once == 0) {
          Serial.println(F("LINK BROKEN"));
          once = 1;
        }
        digitalWrite(heaterrelay, LOW);
        digitalWrite(indicatorrelay, HIGH);
        delay(1000);
        digitalWrite(indicatorrelay, LOW);
        digitalWrite(loadrelay, HIGH);
        delay(1000);
        Voltage = getVPP();
        Serial.println(F(""));
        VRMS = ((Voltage - 0.07) / 2.0) * 0.707;
        AmpsRMS = ((VRMS * 1000) / mVperAmp);
        digitalWrite(loadrelay, LOW);
      }
      once = 0;
      digitalWrite(heaterrelay, HIGH);
      stoprun5();
      digitalWrite(loadrelay, LOW);
      digitalWrite(heaterrelay, LOW);
    }

    digitalWrite(heaterrelay, LOW);
    digitalWrite(loadrelay, LOW);
    stoprun10();
    // indicate to caller (loop()) that cool down is not complete
    return false;
  }
}


void stoprun5() {
  Serial.println(F("5 Second Oven On Time START"));
  delay(3600);
  temp = gettemp();
  temp2 = gettemp2();
  Serial.println(F("5 Second Oven On Time ---> COMPLETE"));
}

void stoprun10() {
  Serial.println(F("10 Second Oven OFF Time START"));
  delay(5000);
  temp = gettemp();
  temp2 = gettemp2();
  delay(5000);
  temp = gettemp();
  temp2 = gettemp2();
  Serial.println(F("10 Second Oven OFF Time ---> COMPLETE"));
}


double getVPP() {
  //  Serial.print(F("IntoVPPLoop "));
  double result;
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
  int minValue = 1024;          // store min value here
  // Serial.print(F("Checking Load Current"));
  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000) //sample for 1 Sec
  {
    readValue = analogRead(sensorIn);
    if (readValue > maxValue)
    {
      maxValue = readValue;
    }
    if (readValue < minValue)
    {
      minValue = readValue;
    }
  }
  result = ((maxValue - minValue) * 5.0) / 1024.0;
  Serial.print(F(":"));
  return result;
}

float gettemp()
{
  MAXCS = 0;
  double c1 = thermocouple.readCelsius();
  MAXCS = 1;
  c1 = c1 - 3.5;                              //temp trim
  Serial.print("TemP1[C]=");
  Serial.print(c1);
  return c1;
}

float gettemp2()
{
  MAXCS2 = 0;
  double c2 = thermocouple2.readCelsius();
  MAXCS2 = 1;
  c2 = c2 - 3.5;                              //temp trim
  Serial.print("     TemP2[C]=");
  Serial.println(c2);
  return c2;
}

void blink()
{

  static uint32_t lastChangeTime = millis();

  if (millis() - lastChangeTime > 1000)
  {
    lastChangeTime += 1000;

    if (ledState == LOW) {
            Serial.println("IN BLINK1");
      ledState = HIGH;
        digitalWrite(ledPin, ledState);
    } else {
            Serial.println("IN BLINK2");
      ledState = LOW;
        digitalWrite(ledPin, ledState);
    }
   
  }

}

You could create a delay with blink and call that instead of any calls to "delay()", like this:

void delayWithBlink(unsigned long delay_millis)
{
  unsigned long ms = millis();
  while (millis() - ms < delay_millis) blink();
}

I know, it's basically what you where told not to do, but if you need the delays..... :slight_smile:

Thank You, this has been running for a day without any issues besides the serial monitor failing. (Program still doing its thing though). I had to restart the computer it was on and it continued on.

Hopefully this solves it, if not i will be back.

Honestly, this way of multitasking with the arduino makes me think of a whole new way of programming. I have never thought of coding like that. It is a lot to wrap my head around, but from a birds eye view it makes perfect sense!

Normal computer coding does not align very well with single core MCU's, so multitasking requires each task not to block. If you get a hang (LOL, got it?) of it, it's great fun!

If your issue should persist, you might want to find out wheter the library "Adafruit_MAX31855" has any issues. If not, then you might want to draw a cirquit diagram of your setup, and ask in the General electronics forum - there are some pretty capable silverbacks in there! :wink:

Good luck!

You could also use the watchdog timer to make sure your code is not getting lost somewhere. Your code will have to peridically reset the watchdog timer, if it doesnt an interrupt is triggered that lets you know your code is got lost.

noweare:
You could also use the watchdog timer to make sure your code is not getting lost somewhere. Your code will have to peridically reset the watchdog timer, if it doesnt an interrupt is triggered that lets you know your code is got lost.

That could cause the heating part of the code to run endlessly without ever reaching the cool down part, not really a good idea :slight_smile:

EDIT: Unless.. You use EEPROM to store the last entered part of the program and then use the stored value to resume from that point whenever the arduino is reset!

Danois90:
That could cause the heating part of the code to run endlessly without ever reaching the cool down part, not really a good idea :slight_smile:

I don't follow. You can reset the wd timer in any loop. The watchdog uses its own timer.

Anyways, tough problem, logging time stamps and where your at in the process will help if it is a repeatable thing.

Well it froze again with the code posted above. I added the delay with blink too, and no blink, no serial com updates. This time the load and oven were on.

I’m about done with it...

You still have two while-loops where it can hang.

while (temp2 > settemp + 16)
{
  ...
  ...
}
while (AmpsRMS < loadcurrent)
{
  ...
  ...
}

But you should see the relevant messages on the serial monitor (I assume that it is permanently (!) connected / open on your PC).

I start suspecting an electrical interference problem; I'm not knowledgeable in that area.