Keypad returning incorrect values

I am using the keypad library and have a key map array as follows

const byte ROWS = 3; 
const byte COLS = 3;
//define the symbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'n','s','m'},
  {'a','u','r'},
  {'b','l','d'},
};
byte rowPins[ROWS] = {31, 33, 41}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {35, 37, 39}; //connect to the column pinouts of the keypad

the code for reading the keypad is as follows

void readKey() {
  char customKey = customKeypad.getKey();
  //
  if (customKey != NO_KEY){
    switch (customKey) {
      case 'a':
        //settings screen
        if (currentScreen < 5)
        {
          
          celciusFlagSettings = celciusFlag;
          currentScreen = 5;
          displayBG();
        }
        else
        {
          
          if (currentScreen == thresholdScreen)
          {
             sensorHigh[0] = sensorHighTemp[0];
                 sensorHigh[1] = sensorHighTemp[1];
                 sensorHigh[2] = sensorHighTemp[2];
                 sensorHigh[3] = sensorHighTemp[3];
                 sensorHigh[4] = sensorHighTemp[4];
                 sensorLow[0] = sensorLowTemp[0];
                 sensorLow[1] = sensorLowTemp[1];
                 sensorLow[2] = sensorLowTemp[2];
                 sensorLow[3] = sensorLowTemp[3];
                 sensorLow[4] = sensorLowTemp[4];
          }
          else
          {
            if (currentScreen == dataSettingsScreen)
            {
              lastAlertTemp = 0000;
              lastAlertNode = 0;
              writeData();
            }
            else
            {
              celciusFlag = celciusFlagSettings;
            }
          }
          writeData();
          displayBG();
          currentScreen = 0;
        }
        break;
      case 'b':
        //data screen
        if (currentScreen < 5)
        {
          displayBG();
          currentScreen = dataScreen;
        }
        else
        {
          //cancel
          displayBG();
          //delay(20);
          currentScreen = 0;
        }
        displayBG();
        //delay(18);
        //currentScreen = 6;
        break;
      case 's':
        if (currentScreen == settingsScreen)
        {
          if (settingsHighlight == 0)
          {
            if (celciusFlagSettings == true)
            {
              celciusFlagSettings = false; 
            }
            else
            {
              celciusFlagSettings = true; 
            }  
          }
          else
          {
             if (settingsHighlight == 1)
             { 
                 currentScreen = thresholdScreen;
                 sensorHighTemp[0] = sensorHigh[0];
                 sensorHighTemp[1] = sensorHigh[1];
                 sensorHighTemp[2] = sensorHigh[2];
                 sensorHighTemp[3] = sensorHigh[3];
                 sensorHighTemp[4] = sensorHigh[4];
                 sensorLowTemp[0] = sensorLow[0];
                 sensorLowTemp[1] = sensorLow[1];
                 sensorLowTemp[2] = sensorLow[2];
                 sensorLowTemp[3] = sensorLow[3];
                 sensorLowTemp[4] = sensorLow[4];
                 
                 displayBG();
                 //delay(20);
             }
             else
             {
               if (settingsHighlight == 2)
               {
                 currentScreen = dataSettingsScreen;
                 displayBG();
               } 
             }
          }
        }
        else
        {
          if (currentScreen == thresholdScreen)
           {    
             if (thresholdEditMode == true)
             {
                 thresholdEditMode = false;
             }
             else
             {
                 thresholdEditMode = true;
             }
           }
        }
        
        break;
      case 'u':
        if (currentScreen == settingsScreen)
        {
          settingsHighlight = settingsHighlight - 1;
          if (settingsHighlight < 0)
          {
            settingsHighlight = 0;
          }  
        }
        else
        {
           if (currentScreen == thresholdScreen)
           {
             if (thresholdEditMode == true)
             {
               if (thresholdsHighlight == 0)
               {
                 sensorHighTemp[currentThresholdScreen] = sensorHighTemp[currentThresholdScreen] + 50;
               }
               else
               {
                 sensorLowTemp[currentThresholdScreen] = sensorLowTemp[currentThresholdScreen] + 50;
               }
             }
             else
             {
               thresholdsHighlight = 0;
             }
           } 
        }
        break;
      case 'd':
        if (currentScreen == settingsScreen)
        {
          settingsHighlight = settingsHighlight + 1;
          if (settingsHighlight > 2)
          {
            settingsHighlight = 2;
          }  
        }
        else
        {
           if (currentScreen == thresholdScreen)
           {
             if (thresholdEditMode == true)
             {
               if (thresholdsHighlight == 0)
               {
                 sensorHighTemp[currentThresholdScreen] = sensorHighTemp[currentThresholdScreen] - 50;
               }
               else
               {
                 sensorLowTemp[currentThresholdScreen] = sensorLowTemp[currentThresholdScreen] - 50;
               }
             }
             else
             {
               thresholdsHighlight = 1;
             }
           } 
        }
        break;
      case 'l':
      //digitalWrite(13, HIGH);   // set the LED on
    //delay(50);              // wait for a second
    //digitalWrite(13, LOW);    // set the LED off
    //delay(50);              // wait for a second
        if (currentScreen < settingsScreen)
        {
          currentScreen = currentScreen - 1;
          if (currentScreen < 0)
          {
            currentScreen = 0;
          } 
          //drawScreen();
        }
        else
        {
           if (currentScreen == thresholdScreen)
           {
              currentThresholdScreen = currentThresholdScreen - 1;
              if (currentThresholdScreen < 0)
              {
                currentThresholdScreen = 0;
              } 
              //drawScreen();
           } 
        }
        break;
      case 'r':
     
        if (currentScreen < settingsScreen)
        {
          currentScreen = currentScreen + 1;
          if (currentScreen > 4)
          {
            currentScreen = 4;
          } 
          //drawScreen();
        }	
        else
        {
           if (currentScreen == thresholdScreen)
           {
               currentThresholdScreen = currentThresholdScreen + 1;
              if (currentThresholdScreen > 4)
              {
                currentThresholdScreen = 4;
              } 
              //drawScreen();
           } 
        }
        break;
     }
  }
}

This works for a period of time and will return what is expected but after a few minutes will then start returning values I do not expect such as # or / or even unprintables.
Once it has started returning these bad values it will continue to do so until a reset.
Any help would be greatly appreciated.

How do you know what character you're getting back? There doesn't seem to be anything in that code that logs it.

Since you say it works initially, and there is nothing obvious in that code fragment that would make the character detection stateful, I think the most likely cause is that you are running out of memory or suffering memory corruption. Since you haven't posted the complete code, it's impossible to look for any dangerous code constructs that might provoke that sort of problem. Have you tried to work out how much memory is being used?

If I was trying to locate the problem, I'd remove everything except the code to initialise and read from the keypad and confirm that it works properly over an extended period. Then add back in minimal code to initialise and output to the display driver and confirm it's still stable over an extended period. The same for any other devices attached to your system. Finally add back in your application logic piece by piece, and see at what point the problem appears.

I took out the debugging part that returned the incorrect values once I knew what I was getting.
I have attached the rest of the code, if there is anything you can see there that is causing memory issues then that would be good but otherwise I will do what you suggest and reduce the code and see what happens.
Thanks for your help.

apollo_v2.pde (27.2 KB)

threshold[0] = false;
  threshold[1] = false;
  threshold[2] = false;
  threshold[3] = false;
  threshold[4] = false;

I don't think you've been introduced to Mr For-Loop.

This looks suspect:

void readSerialString () {
  int sb;   
    
  if(Serial3.available()) { 
    while (Serial3.available()){ 
      sb = Serial3.read();                  
      serInString[serInIndx] = sb;
      serInIndx++;
    }        
  }  
}

What stops you running off the end of serInString ?

You may have a valid point with Mr For-Loop :slight_smile:

serInIndx gets reset to zero in the printSerialString function once the required number of characters have been read.

//********************************************************************
// printSerialString
//********************************************************************
void printSerialString() {
  if( serInIndx > 4) {
    if ((char)serInString[0] == '

)
    {   
      int address = serInString[1] - 65;
      if (address >= 0 && address < 9)
      {
        if ((serInString[2] - 48) < 10 && serInString[2] - 48 >= 0)
        {
          if ((serInString[3] - 48) < 10 && serInString[3] - 48 >= 0)
          {
            if ((serInString[4] - 48) > 9 || serInString[4] - 48 < 0)
            {
              serInString[4] = 48;
            }
            if ((serInString[5] - 48) > 9 || serInString[5] - 48 < 0)
            {
              serInString[5] = 48;
            }
            sensorTemps[address] = ((serInString[2] - 48) * 1000) + ((serInString[3] - 48) * 100) + ((serInString[4] - 48) * 10) + (serInString[5] - 48);
            checkThreshold(address);
            //Send back to main
//            digitalWrite(53, HIGH);
//            Serial3.print("$");
//            Serial3.print((char)serInString[1]);
//            Serial3.print((char)threshold[address]);
//            Serial3.print((char)1);
//            digitalWrite(53, LOW);
          }
        }
      }
    }
    serOutIndx = 0;
    serInIndx  = 0; 
    //Serial.println();
  }
}

int address = serInString[1] - 'A';
      if (address >= 0 && address < 9)
      { 
        if ((serInString[2] - '0') < 10 && serInString[2] - '0' >= 0)

is much easier to read and understand, IMHO.

markbucknell: serInIndx gets reset to zero in the printSerialString function once the required number of characters have been read.

Maybe that's your intention, but that code will keep chomping through memory as long as there are bytes available on Serial3. Maybe you'll never get in a situation where that happens, but it's good practice to make your code robust so that it doesn't fall over when unexpected things happen. In this case, you'd do that by checking the buffer index before you write to it.