Arduino nano crashes - please advise

diagram:

#include <Arduino.h>
//#include <NeoSWSerial.h>
//NeoSWSerial portOne(10, 11);
#include "ImmersionHeaterController.h"
#include <SoftwareSerial.h>
#include "ApplicationMonitor.h"
#include <OneWire.h>
#include <DallasTemperature.h>

Watchdog::CApplicationMonitor ApplicationMonitor;
int g_nIterations = 0;

//enum debugLevel : int {
//	off = 0, low = 1, med, high
//};

//enum updateMode : int {
//	zero = 0, down = 1, up = 2
//};

debugLevel debug = high;
constexpr int softwareBaudRate = 9600;
int countOfEnergisedRelays = 0;

constexpr int maxNumberOfRelays = 6;
constexpr int relayPin1 = 2;
constexpr int relayPin2 = 3;
constexpr int relayPin3 = 4;
constexpr int relayPin4 = 5;
constexpr int relayPin5 = 6;
constexpr int relayPin6 = 7;
constexpr int relayPinSocket = 8;

constexpr int delayAfterSendingMessage = 50;

unsigned long countOFAllBufferResets = 0;
unsigned long countOfAllMessagesCorrectlyBounded = 0;
unsigned long bufferResetMax = 400000000; //4294967040

unsigned long previousTimeIncPlus = 0;
unsigned long storedTimeIncPlus = 0;
unsigned long previousTimeIncMinus = 0;
unsigned long storedTimeIncMinus = 0;

unsigned long minimumSwitchingTime = 2000;

/**
 * variables for Serial Communication
 */
constexpr int RXpin = 10;
constexpr int TXpin = 11;
SoftwareSerial port(RXpin, TXpin);
constexpr byte numBytes = 8;
char latestInstruction[numBytes];
byte numReceived = 0;
boolean newData = false;
boolean newInstruction = false;
constexpr char startMarker = '<'; //<
constexpr char endMarker = '>'; //>
int pauseWhileSending = 50;

/**
 * variables for temperature measurement
 */
// temp sensors wire pins
constexpr int ONE_WIRE_LOWERT = 9;
constexpr int ONE_WIRE_UPPERT = 12;

// Setup a oneWire instance to communicate with any OneWire device
OneWire OneWireLowerT(ONE_WIRE_LOWERT);
OneWire OneWireUpperT(ONE_WIRE_UPPERT);

// Pass oneWire reference to DallasTemperature library
DallasTemperature TempSensorLower(&OneWireLowerT);
DallasTemperature TempSensorUpper(&OneWireUpperT);

//callibrations
constexpr float referenceHigh = 99.9;
constexpr float referenceLow = 0;
constexpr float tLowerRawHigh = 98.3;
constexpr float tLowerRawLow = 1.0;
constexpr float tLowerRawRange = tLowerRawHigh - tLowerRawLow;
constexpr float referenceRange = referenceHigh - referenceLow;
float tLowerCorrectedValue;
float tLowerRawValue;
constexpr float tUpperRawHigh = 98.3;
constexpr float tUpperRawLow = 0.7;
constexpr float tUpperRawRange = tUpperRawHigh - tUpperRawLow;
float tUpperCorrectedValue;
float tUpperRawValue;

/**
 * TODO this message is not used! Deprecate?
 */
void logError(String error) {
	Serial.print("ERROR! ");
	Serial.println(error);
	//debug = high;
}

/**
 * this function is to help with error detection of transmitted messages
 */
void countMessageNumber(boolean messageStarted) {
	if (messageStarted) {
		countOfAllMessagesCorrectlyBounded++;
//		if (debug >= high) {
//			Serial.print("countOfAllMessagesCorreclyBounded ");
//			Serial.println(countOfAllMessagesCorreclyBounded);
//		}
		if (countOfAllMessagesCorrectlyBounded > bufferResetMax) {
			Serial.println("count1 overflow! ");
			Serial.println("Reset both counts to zero");
			countOfAllMessagesCorrectlyBounded = 0;
			countOFAllBufferResets = 0;
		}
	}
}
/**
 * This requires 1000ms between message sends to avoid buffer filling up
 * If buffer does fill, it will get emptied (elsewhere) but ~5/10% messages are void because of buffer overruns
 */
void recvCharsWithStartEndMarkers() {
	static boolean recvInProgress = false;
	static byte ndx = 0;
	char receivedChar[numBytes];
	//set receivedChar to un-initialised
	memset(receivedChar, 0, sizeof(receivedChar));
	char charReadFromPort;
	boolean messageStarted = false;

	port.listen();
	unsigned long timeout = 10000;
	unsigned long startTimeWhile = millis();
	unsigned long currentTime = millis();

	while (port.available() > 0 && newData == false
			&& currentTime - startTimeWhile < timeout) {
		currentTime = millis();
		charReadFromPort = (char) port.read();
		if (recvInProgress == true) {
			if (charReadFromPort != endMarker) {
				receivedChar[ndx] = charReadFromPort;
				ndx++;
				//it is possible that the message sent is longer than numBytes. if so, the last characters will be discarded
				if (ndx >= numBytes - 1) {
					ndx = numBytes - 2;
				}
			} else {
				//countMessageNumber(messageStarted);
				receivedChar[ndx] = '\0'; // terminate the string
				recvInProgress = false;
				numReceived = ndx;  // save the number for use when printing
				ndx = 0;
				newData = true;
			}
		} else if (charReadFromPort == startMarker) {
			recvInProgress = true;
			messageStarted = true;
		}
	}

	if (newData) {
		strncpy(latestInstruction, receivedChar, numBytes);
		newInstruction = true;
		if (debug >= high) {
			Serial.print("latestInstruction ");
			Serial.println(latestInstruction);
		}

	} else {
		strncpy(latestInstruction, "nochnge", numBytes);
		newInstruction = false;
	}
	newData = false;
}

/**
 * this works for messages less than 8 characters
 * a delay is required: delayAfterSendingMessage
 * currently the messages invoke no action - this requires implementation on the other side
 */
void wrapCharMessage(char message[]) {
	port.print(startMarker);
	port.print(message);
	port.print(endMarker);
	delay(delayAfterSendingMessage);
}

/****
 * make sure to check if relay switches on high or low
 */
void adjustLoad(int relayID, boolean on) {
	uint8_t cond;

	//low switching
//	if (on)
//		cond = LOW;
//	else
//		cond = HIGH;

	//high switching
	if (on)
		cond = HIGH;
	else
		cond = LOW;

	switch (relayID) {
	case 1:
		digitalWrite(relayPin1, cond);
		break;
	case 2:
		digitalWrite(relayPin2, cond);
		break;
	case 3:
		digitalWrite(relayPin3, cond);
		break;
	case 4:
		digitalWrite(relayPin4, cond);
		break;
	case 5:
		digitalWrite(relayPin5, cond);
		break;
	case 6:
		digitalWrite(relayPin6, cond);
		break;
	default:
		break;
		//todo this should not happen
	}
}

void updateRelayCount(updateMode mode) {
	switch (mode) {
	case 0:
		countOfEnergisedRelays = 0;
		break;
	case 1:
		countOfEnergisedRelays--;
		break;
	case 2:
		countOfEnergisedRelays++;
		break;
	default:
		break;
		//send data to emonloadcontrol
	}
}

void configureSocket(boolean turnOn) {
	if (turnOn)
		digitalWrite(relayPinSocket, HIGH);
	else
		digitalWrite(relayPinSocket, LOW);
}

void configureLoads(int numberOfRelays, boolean turnOn) {
	switch (countOfEnergisedRelays) {
	case 0:
		if (turnOn) {
			adjustLoad(1, true);
			updateRelayCount(up);
		}
		break; /* optional */
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		if (turnOn) {
			adjustLoad(6, true);
			updateRelayCount(up);
		} else {
			//work out if frequent switching is an issue
			for (int i = 0; i < numberOfRelays; i++) {
				adjustLoad(countOfEnergisedRelays, false);
				if (countOfEnergisedRelays != 0)
					updateRelayCount(down);
			}
		}
		break;
	case 6:
		if (turnOn) {
			//sending the messages invokes no action on the other side!
			//wrapCharMessage("IHfull");
		} else {
			//wrapCharMessage("IHNF");
			for (int i = 0; i < numberOfRelays; i++) {
				adjustLoad(countOfEnergisedRelays, false);
				if (countOfEnergisedRelays != 0)
					updateRelayCount(down);
			}
		}
		break;
	default:
		//logError("issue with configureRelays");
		Serial.print("count ");
		Serial.print(countOfEnergisedRelays);
		Serial.print(" numberOfRelays ");
		Serial.print(numberOfRelays);
		Serial.print(" turnOn(1) turnOff(0):");
		Serial.println(turnOn);
		adjustLoad(1, false);
		adjustLoad(2, false);
		adjustLoad(3, false);
		adjustLoad(4, false);
		adjustLoad(5, false);
		adjustLoad(6, false);
		updateRelayCount(zero);
		break;
	}
//	Serial.print("numberOfRelaysOn after call ");
//	Serial.println(numberOfRelaysOn);

}

void checkOverflowAndEmptyBuffer() {
	if (port.overflow()) {
		Serial.println("overflow!");
		int timeout = 0;
		//buffer size is 64 bytes, each character can represent a byte
		while (port.available() && timeout < 64) {
			port.read();
			timeout++;
		}
	}
}

/**
 * this is a fudge for buffer errors
 *
 */
void updateErrorCount() {
	countOFAllBufferResets++;
	if (countOFAllBufferResets > bufferResetMax) {
		Serial.println("Overflow1 Reset ");
		countOFAllBufferResets = 0;
		countOfAllMessagesCorrectlyBounded = 0;
	}
	if (countOfAllMessagesCorrectlyBounded > bufferResetMax) {
		Serial.println("overflow2! Reset");
		countOfAllMessagesCorrectlyBounded = 0;
	}
//	Serial.print("bufferErrorCount: ");
//	Serial.println(countOFAllBufferResets);
//	Serial.print(" countOfAllMessagesCorreclyBounded: ");
//	Serial.println(countOfAllMessagesCorreclyBounded);
	if (countOFAllBufferResets < bufferResetMax
			&& countOfAllMessagesCorrectlyBounded < bufferResetMax) {
		Serial.print("% errors ");
		if (countOfAllMessagesCorrectlyBounded > 0)
			Serial.println(
					(countOFAllBufferResets / countOfAllMessagesCorrectlyBounded)
							* 100);
	}
}

void addressIssues() {
	//updateErrorCount();
	checkOverflowAndEmptyBuffer();
}

void adjustLoadsAccordingToInstruction() {
	if (newInstruction) {
		if (strncmp(latestInstruction, "alloff", strlen("alloff")) == 0) {
			configureLoads(6, 0);
			configureSocket(false);
		} else if (strncmp(latestInstruction, "Sct+", strlen("Sct+")) == 0) {
			configureSocket(true);
		} else if (strncmp(latestInstruction, "SoC-", strlen("SoC-")) == 0) {
			configureSocket(false);
		} else if (strncmp(latestInstruction, "inc+", strlen("inc+")) == 0) {
			if (countOfEnergisedRelays < 6) {
				configureLoads(1, 1);
			}
		} else if (strncmp(latestInstruction, "inc-", strlen("inc-")) == 0) {
//			previousTimeIncMinus = storedTimeIncMinus;
//			storedTimeIncMinus = millis();
//				if (storedTimeIncMinus - storedTimeIncPlus
//						> minimumSwitchingTime) {
			//				}
			if (countOfEnergisedRelays > 0) {
				configureLoads(1, 0);

			}
		} else {
			if (debug >= med) {
				Serial.print("instruction not matched ");
				Serial.print("latestInstruction: ");
				Serial.println(latestInstruction);
			}
			addressIssues();
		}
	}
}

/**
 * NOTE: There is a issue with start-up of Arduino programs that control these relays.
 * These relays input controls are Active LOW, meaning that setting a pin LOW turns them ON.
 * To assure that no relays activate at Reset or Power-On until you want them to,
 * the initialization sequence in SETUP should be:
 * pinMode(Relay, OUTPUT);
 * digitalWrite(Relay, HIGH);
 *
 */
void initialiseRelays() {
	pinMode(relayPin1, OUTPUT);
	pinMode(relayPin2, OUTPUT);
	pinMode(relayPin3, OUTPUT);
	pinMode(relayPin4, OUTPUT);
	pinMode(relayPin5, OUTPUT);
	pinMode(relayPin6, OUTPUT);
	pinMode(relayPinSocket, OUTPUT);

	digitalWrite(relayPin1, LOW);
	digitalWrite(relayPin2, LOW);
	digitalWrite(relayPin3, LOW);
	digitalWrite(relayPin4, LOW);
	digitalWrite(relayPin5, LOW);
	digitalWrite(relayPin6, LOW);
	digitalWrite(relayPinSocket, LOW);

}

void blinkLed(int numBlinks) {
	for (int dl = 0; dl < numBlinks; dl++) {
		digitalWrite(LED_BUILTIN, HIGH);
		delay(100);
		digitalWrite(LED_BUILTIN, LOW);
		delay(100);
	}
}

void setup() {
	Serial.begin(9600);
	Serial.println("setting up");
	ApplicationMonitor.Dump(Serial);
	ApplicationMonitor.EnableWatchdog(
			Watchdog::CApplicationMonitor::Timeout_4s);

	//initialise temperature sensors
//	TempSensorLower.begin();
//	TempSensorUpper.begin();

	port.begin(softwareBaudRate);
	port.listen();
	initialiseRelays();
	blinkLed(5);
	Serial.println("<Arduino is ready eddy>");
}

void measureTempAndAdjustLoad() {
	// Send the command to get temperatures
	TempSensorLower.requestTemperatures();
	TempSensorUpper.requestTemperatures();
	tLowerRawValue = TempSensorLower.getTempCByIndex(0);
	tUpperRawValue = TempSensorUpper.getTempCByIndex(0);

	if (tLowerRawValue == -127.0 || tUpperRawValue == -127.0) {
		//this indicates issue with sensors
		Serial.print("temp sensors not functioning correctly ");
		//turn off  all loads
		configureLoads(6, 0);

		if (tLowerRawValue == -127.0) {
			Serial.print("temp lower issue ");
		}
		if (tUpperRawValue == -127.0) {
			Serial.print("temp lower issue ");
		}
	}

	tLowerCorrectedValue = (((tLowerRawValue - tLowerRawLow) * referenceRange)
			/ tLowerRawRange) + referenceLow;

	tUpperCorrectedValue = (((tUpperRawValue - tUpperRawLow) * referenceRange)
			/ tUpperRawRange) + referenceLow;

	//	Serial.print("tLowerRawValue: ");
//	Serial.println(tLowerRawValue);
//	Serial.print("tUpperRawValue: ");
//	Serial.println(tUpperRawValue);

//	Serial.print("tLowerCorrectedValue: ");
//	Serial.println(tLowerCorrectedValue);
//	Serial.print("tUpperCorrectedValue: ");
//	Serial.println(tUpperCorrectedValue);

	if (tUpperCorrectedValue > 90 || tLowerCorrectedValue > 85) {
		//turn off  all loads
		configureLoads(6, 0);
	}
}

void testConfigure() {
	int shortDelay = 1000;
	configureLoads(6, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 1);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);
	configureLoads(1, 0);
	delay(shortDelay);

	configureLoads(6, 0);

}
void cycleRelaysOnAndOff() {
	int shortDelay = 3000;
	int longDelay = 10000;
	delay(longDelay);

	Serial.println("all off");
	digitalWrite(relayPin1, LOW);
	digitalWrite(relayPin2, LOW);
	digitalWrite(relayPin3, LOW);
	digitalWrite(relayPin4, LOW);
	digitalWrite(relayPin5, LOW);
	digitalWrite(relayPin6, LOW);
	delay(shortDelay);

	Serial.println("1 on");
	digitalWrite(relayPin1, HIGH);
	delay(shortDelay);

	Serial.println("1 off");
	digitalWrite(relayPin1, LOW);
	delay(shortDelay);

	Serial.println("2 on");
	digitalWrite(relayPin2, HIGH);
	delay(shortDelay);

	Serial.println("2 off");
	digitalWrite(relayPin2, LOW);
	delay(shortDelay);

	Serial.println("3 on");
	digitalWrite(relayPin3, HIGH);
	delay(shortDelay);

	Serial.println("3 off");
	digitalWrite(relayPin3, LOW);
	delay(shortDelay);

	Serial.println("4 on");
	digitalWrite(relayPin4, HIGH);
	delay(shortDelay);

	Serial.println("4 off");
	digitalWrite(relayPin4, LOW);
	delay(shortDelay);

	Serial.println("5 on");
	digitalWrite(relayPin5, HIGH);
	delay(shortDelay);

	Serial.println("5 off");
	digitalWrite(relayPin5, LOW);
	delay(shortDelay);

	Serial.println("6 on");
	digitalWrite(relayPin6, HIGH);
	delay(shortDelay);

	Serial.println("6 off");
	digitalWrite(relayPin6, LOW);
	delay(shortDelay);

	Serial.println("1, 2, 3, 4, 5, 6 on");
	digitalWrite(relayPin1, HIGH);
	digitalWrite(relayPin2, HIGH);
	digitalWrite(relayPin3, HIGH);
	digitalWrite(relayPin4, HIGH);
	digitalWrite(relayPin5, HIGH);
	digitalWrite(relayPin6, HIGH);
	delay(shortDelay);

}

/**
 * 	check how often the instructions come from emonloadcontrol and adjust delay accordingly
 * 	otherwise loop goes round too quickly and messages are chopped up
 */
void loop() {
	ApplicationMonitor.IAmAlive();
	ApplicationMonitor.SetData(g_nIterations++);
	const boolean testingSystem = false;
	const boolean testConfigureRelays = false;
	const boolean cycleRelays = false;
	if (!testingSystem) {
		delay(200);
		recvCharsWithStartEndMarkers();
		adjustLoadsAccordingToInstruction();
		measureTempAndAdjustLoad();

	} else {
		if (testConfigureRelays)
			testConfigure();
		if (cycleRelays)
			cycleRelaysOnAndOff();
	}
}