Arduino 3x4 Keypad returning random values at random times

I am using an ELEGOO MEGA R3 Board with a 4x3 keypad.
I want to return the key pressed and activate a specific function depending on the key.
But, when I run the code I only receive 4's and 1's at seemingly random intervals.
In the system is a QMC5883L magnetometer and a roboclaw 2x60 motorcontroller.

Code:

/*
  PPR: 975
  Circumference: 25 pi
*/

#include <SoftwareSerial.h>
#include "RoboClaw.h"
#include "Keypad.h"
#include <QMC5883LCompass.h>

QMC5883LCompass compass;

// Units: In
double path[][2] = {{0,0},{100,100}};
double bHeading = 0;

const byte ROWS = 4;
const byte COLS = 3; 

char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

SoftwareSerial serial(10,11);	
RoboClaw roboclaw(&serial,10000);

#define address 0x80

#define Kp 1.0
#define Ki 0.5
#define Kd 0.25
#define qpps 44000


bool isKeyPressed = false;

void setup() {
  Serial.begin(57600);
  compass.init();
  //Communicate at 38400bps
  roboclaw.begin(38400);
  roboclaw.SetM1VelocityPID(address,Kd,Kp,Ki,qpps);
  roboclaw.SetM2VelocityPID(address,Kd,Kp,Ki,qpps);

  /*
   *   call setSmoothing(STEPS, ADVANCED);
   *   
   *   STEPS     = int   The number of steps to smooth the results by. Valid 1 to 10.
   *                     Higher steps equals more smoothing but longer process time.
   *                     
   *   ADVANCED  = bool  Turn advanced smmothing on or off. True will remove the max and min values from each step and then process as normal.
   *                     Turning this feature on will results in even more smoothing but will take longer to process.
   *                     
   */
   
  compass.setSmoothing(4,true);  

  compass.setCalibrationOffsets(739.00, 741.00, -12.00);
  compass.setCalibrationScales(1.38, 0.84, 0.92);



}

void loop()
{
  char key = keypad.getKey();
  int x, y, z;
  float heading;

  compass.read();

  x = compass.getX();
  y = compass.getY();
  z = compass.getZ();
  heading = atan2(y, x)*180/3.1415926;
  
  if (key != NO_KEY) {
    Serial.println(key);
    /*
    if (key == '*' && !isKeyPressed) {
      roboclaw.SpeedM1(address, 0);
      roboclaw.SpeedM2(address, 0);
      isKeyPressed = true;
    }
    */
    if (key == '0' && !isKeyPressed) {
      Serial.print("Heading: ");
      Serial.println(heading);
      isKeyPressed = true;
    }
    if (key == '5' && !isKeyPressed) {
      roboclaw.SpeedDistanceM1M2(address,750,3000,750,3000,0);
      roboclaw.SpeedDistanceM1M2(address,-400,1600,400,1600,0);
      isKeyPressed = true;
    }

    if (key == '1' && !isKeyPressed) {
      int rows = sizeof path / sizeof path[0];
      double distance = 0;
      double tHeading = 0;
      int count = 0;
      int countMax = 0;

      for(int r=1;r<rows;r++){
        distance = sqrt(sq(path[r][0])+sq(path[r][1]));
        while(true){
          x = compass.getX();
          y = compass.getY();
          z = compass.getZ();
          heading = atan2(y, x)*180/3.1415926;
          tHeading = findHeading(path[r][0]-path[r-1][0],path[r][1]-path[r-1][1]);

          //tHeading -= heading;

          //turn until within 1 degree of tHeading

          if(tHeading - heading > 0){
            roboclaw.SpeedM1(address, -400);
            roboclaw.SpeedM2(address, 400);
          }
          else{
            roboclaw.SpeedM1(address, 400);
            roboclaw.SpeedM2(address, -400);
          }

          /*
            If there is a sudden jump in the bots axis of rotation's position the straight line follower does not work.
            An accelerometer to detect non desired acceleration may be useful: if there is a sudden bump find the change in position and
            then directly and perpendicularly return to the path and original algorithm.
          */

          if(abs(heading-tHeading)<1){
            roboclaw.SpeedDistanceM1M2(address,750,975*(distance/(25*3.1415926*countMax)),750,975*(distance/(25*3.1415926*countMax)),0);

            if(count == countMax){
              roboclaw.SpeedM1(address, 0);
              roboclaw.SpeedM2(address, 0);
              break;
            }
          }
        }
      }
    }

  } else {
    isKeyPressed = false;
  }

  /* 
   *  If heading is > 1.5 degrees off of desired heading then lessen the required motor's speed by 50(?) PPR
   *  This will be done in loop such that it will adjust to the heading
  */
}

double findHeading(double dx, double dy){
  double heading = atan2(dy, dx)*180/3.1415926;
  return heading;
}


The values:
image

Connections:
rows = {9, 8, 7, 6}
cols = {5, 4, 3}
All are directly from the keypad to the pins through a decently long wire (2ft).

If a photo of the connections for the keypad are needed I will send at request. I cannot do so at the moment since I am school.

Due note: this error has fixed itself once (the keypad worked correctly) and then it returned to this weird state. I am unsure whether that was due to a code change or wire position.

Probably loose wires. A minimal keypad sketch can let you know...

#include <Keypad.h>

const uint8_t ROWS = 4;
const uint8_t COLS = 3;
char keys[ROWS][COLS] = {
  { '1', '2', '3'},
  { '4', '5', '6'},
  { '7', '8', '9'},
  { '*', '0', '#'}
};

uint8_t colPins[COLS] = { 5, 4, 3};
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 };

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

void setup() {
  Serial.begin(9600);
}

void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.