I have been working under the assumption that it is some kind of variable going outside its bounds, but have not been able to pinpoint exactly that.
If that's the case, it must be the array levelSetting[]
The value of "setVal" is capped in "void settings()" (bottom of code)
As suggested, I have deleted a good part of the code to be able to post it. (Thanks PerryBebbington)
volatile byte setVal = 0; // Variable used for determining what to display on LCD
volatile int levelSetting[8];
// depth = 1 //Distance from sensor to bottom of well or maximum meassurement in cm
// stopLevel = 2
// startLevel = 3
// start2Level = 4
// sensor selection = 5
// Output mode = 6
// Well area in m2 = 7
long duration;
long distance;
long meassurement;
long sampMeassurement;
void setup() {
Wire.begin();
// Serial.begin(9600);
byte error, address;
byte nDevices;
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
lcdaddress = address;
nDevices++;
}
}
pLCD = new LiquidCrystal_I2C(lcdaddress, 16, 2);
pLCD -> init();
pLCD -> clear();
pLCD -> backlight();
//EEPROM.write(5,1);
// Initial reading of level settings from EEPROM
for (byte i=0; i<=7; i++) {
if (i == 5 || i == 6) {
levelSetting[i] = EEPROM.read(i);
}
else {
levelSetting[i] = EEPROM.read(i)*4;
}
}
levelSetting[6] = constrain(levelSetting[6], 0, 1);
levelSetting[5] = constrain(levelSetting[5], 0, numSensors);
attachInterrupt(digitalPinToInterrupt(encoderSwitchPin), settings, FALLING);
attachInterrupt(digitalPinToInterrupt(encoderPinA), encoder, CHANGE);
wdt_enable(WDTO_4S); //Enable watchdog timer with 4 seconds
}
void loop() {
//What to display on LCD
switch (setVal) {
case 5: //Setting sensor selection
pLCD -> setCursor(0, 0);
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[setVal])));
pLCD -> print(buffer);
strcpy_P(buffer, (char *)pgm_read_word(&(sensorName[levelSetting[setVal]])));
pLCD -> setCursor(0, 1);
pLCD -> print(buffer);
break;
case 6: //Setting output mode
pLCD -> setCursor(0, 0);
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[setVal])));
pLCD -> print(buffer);
strcpy_P(buffer, (char *)pgm_read_word(&(outputMode[levelSetting[setVal]])));
pLCD -> setCursor(0, 1);
pLCD -> print(buffer);
break;
case 7: //Setting area
pLCD -> setCursor(0, 0);
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[setVal])));
pLCD -> print(buffer);
pLCD -> setCursor(0, 1);
if (levelSetting[setVal] > 99) {
pLCD -> print((levelSetting[setVal]-(levelSetting[setVal]-1)));
pLCD -> print(".");
if (levelSetting[setVal]-100 < 10) {pLCD -> print(0);}
pLCD -> print(levelSetting[setVal]-100);
}
else {
pLCD -> print(0);
pLCD -> print(".");
pLCD -> print(levelSetting[setVal]);
}
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[9])));
pLCD -> print(buffer);
break;
case 8:
setVal = 0;
break;
default: //Setting for levels
pLCD -> setCursor(0, 0);
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[setVal])));
pLCD -> print(buffer);
if (setVal == 0){
pLCD -> setCursor(9, 0);
if (pumpRun == 0){strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[13])));}
if (pumpRun == 1){strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[14])));}
pLCD -> print(buffer);
}
pLCD -> setCursor(0, 1);
pLCD -> print(levelSetting[setVal]);
if (setVal == 0){strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[10])));}
else {strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[8])));}
pLCD -> print(buffer);
if (setVal == 0){
if (pumpRun == 0) {
if (inFlow < 10 && inFlow >= 0) {
pLCD -> setCursor(10, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(inFlow);
}
if (inFlow >= 10 && inFlow < 100) {
pLCD -> setCursor(9, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(inFlow);
}
if (inFlow >= 100 && inFlow < 1000) {
pLCD -> setCursor(8, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(inFlow);
}
}
else {
if (outFlow > -10 && outFlow < 0) {
pLCD -> setCursor(9, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(outFlow);
}
if (outFlow <= -10 && outFlow > -100) {
pLCD -> setCursor(8, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(outFlow);
}
if (outFlow <= -100 && outFlow > -1000) {
pLCD -> setCursor(7, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(outFlow);
}
if (outFlow <= -1000) {
pLCD -> setCursor(6, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(spaceText[0])));
pLCD -> print(buffer);
pLCD -> print(outFlow);
}
}
pLCD -> setCursor(13, 1);
strcpy_P(buffer, (char *)pgm_read_word(&(LCDtext[11])));
pLCD -> print(buffer);
}
break;
}
//Ultrasonic = 0
//4-20ma sensor = 1
//0-10v sensor = 2
//0-5v sensor = 3
if (setVal == 5 || setVal == 6) {
EEPROM.update(setVal, levelSetting[setVal]);
}
else if (setVal != 0) {
EEPROM.update(setVal, levelSetting[setVal]/4);
}
wdt_reset();
}
void settings() {
if (digitalRead(encoderSwitchPin) == LOW){
if (setVal >= 8) {
setVal = 0;
}
else {
setVal=setVal+1;
}
}
}
void encoder() {
if (setVal !=0){
if (digitalRead(encoderPinA) == HIGH) // found a low-to-high on channel A
{
if (digitalRead(encoderPinB) == LOW) // check channel B to see which way encoder is turning
{
levelSetting[setVal] = (levelSetting[setVal] + 1); // CW
}
else
{
levelSetting[setVal] = (levelSetting[setVal] - 1); // CCW
}
}
else // found a high-to-low on channel A
{
if (digitalRead(encoderPinB) == LOW)
{
levelSetting[setVal] = (levelSetting[setVal] - 1); // CCW
}
else
{
levelSetting[setVal] = (levelSetting[setVal] + 1); // CW
}
}
}
if (setVal == 5){
levelSetting[setVal] = constrain(levelSetting[setVal], 0, numSensors);}
else if (setVal ==6) {levelSetting[setVal] = constrain(levelSetting[setVal], 0, 1);}
else {levelSetting[setVal] = constrain(levelSetting[setVal], 0, 600);}
}