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:

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.