I have a project that is basically an extension of a devices' controls. It consists of serial to interface with the device, a 64x256 display driven with u8glib, a 5x5 keypad, and a volume pot sampled with analog read.
When the user presses a key it sends a hex array corresponding to the button pushed to the device via serial. The device returns the updated display information via serial then the sketch/arduino processes and displays that updated response. Pretty simple, and it works well except the keypad is very slow at times and appears to be suffering from "interference" from the u8glib display loop. If I comment the display loop out the keypad responds normally. With u8glib's (while do) loop in the sketch the keypad code will usually recognize a key PRESS but the event listener will almost always miss the RELEASE state and initiate a HELD state.
For testing purposes I stripped down the keypad size to a 2x2 and only used four keys.
Has anyone encountered a similar problem? Is there simply just too much going on to work effectively?
#include <Keypad.h>
#include "U8glib.h"
U8GLIB_NHD31OLED_2X_GR u8g(10, 9);
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(15, 16); // RX, TX
const byte ROWS = 2; //four rows
const byte COLS = 2; //four columns
char keys[ROWS][COLS] = {
{
'X', 'arrowDown'
}
,
{
'MENU', 'Enter'
}
};
byte colPins[COLS] = {
38, 40,
}; //connect to the column pinouts of the keypad
byte rowPins[ROWS] = {
42, 44
}; //connect to the row pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
char holdKey;
unsigned long t_hold;
byte X[20] = {
0x24, 0x05, 0x18, 0x36, 0xFE, 0x7B, 0xEF, 0x01, 0xE0, 0x03
};
byte arrowDown[10] = {
0x24, 0x05, 0x18, 0x36, 0xDF, 0x7B, 0xEF, 0x01, 0xC1, 0x03
};
byte buttonMENU[10] = {
0x24, 0x05, 0x18, 0x36, 0xFF, 0x7B, 0xEF, 0x00, 0xE0, 0x03
};
byte buttonEnter[10] = {
0x24, 0x05, 0x18, 0x36, 0xFF, 0x7B, 0xED, 0x01, 0xDF, 0x03
};
byte buttonRelease[10] = {
0x24, 0x05, 0x18, 0x36, 0xFF, 0x7B, 0xEF, 0x01, 0xE1, 0x03
};
byte specialReports[9] = {
0x24, 0x04, 0x18, 0x29, 0x00, 0x01, 0x2E, 0x98, 0x03
}; // enable serial control
byte acknowledge[6] = {
0x24, 0x01, 0x10, 0xF3, 0x28, 0x03
}; // acknowledge receipt of data from device, unitiate next data packet
boolean checkSumGood = false;
int8_t sum = 0;
int8_t a = 0;
int8_t sumCounter = 0;
char dataBuffer[49];
char dataBufferShifted[49];
char elevenCharacterString[12];
int8_t startOfMessage;
int8_t lengthOfMessage;
int8_t sourceDestination;
int8_t opCode;
int8_t subOpCode;
char controlHeadStringData_2;
uint8_t checkSum;
uint8_t checkSumByte;
uint8_t endOfMessage;
int8_t sumIndex = 0;
int8_t i = 0;
int8_t displayMessages = 0x2E;
int8_t elevenCharacterStringSubOpCode = 0x03;
int8_t elevenCharacterStringStart = 7; //loop start
int8_t elevenCharacterStringEnd = 17; //loop end
int8_t displayString = 0x02;
int8_t subOpCodeData_1;
int8_t subOpCodeData_2;
char fiveCharacterString_Line_0[5];
void setup(void) {
Serial.begin(9600, SERIAL_8O1);
Serial.write(specialReports, 9);
keypad.setHoldTime(500);
keypad.setDebounceTime(10);
keypad.addEventListener(keypadEvent);
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255, 255, 255);
}
mySerial.begin(9600);
}
void loop() {
//checkSumGood = false;
char key = keypad.getKey();
if (Serial.available() != 0) {
for (i = 0; i < 48; i++) {
dataBuffer[i] = Serial.read();
dataBuffer[i + 1] = '\0';
delay(1);
}
startOfMessage = dataBuffer[0]; // 0x24
lengthOfMessage = dataBuffer[1]; // variable
sourceDestination = dataBuffer[2]; // 0x81
opCode = dataBuffer[3]; // variable
subOpCode = dataBuffer[4]; // variable
subOpCodeData_1 = dataBuffer[5]; // variable
subOpCodeData_2 = dataBuffer[6]; // variable
checkSumByte = dataBuffer[lengthOfMessage + 3]; // variable
endOfMessage = dataBuffer[lengthOfMessage + 4]; // 0x03
// strcpy( dataBufferShifted, dataBuffer );
for (sumIndex = 0; sumIndex < lengthOfMessage + 3; sumIndex ++) //summing loop to add up packet data
{
checkSum += dataBuffer[sumIndex];
}
if (checkSum == checkSumByte) {
checkSumGood = true;
}
if (opCode == 0xF3 && subOpCodeData_2 == 0x24 ) { // test for prependedACK and adjust display loop
//Serial.write(acknowledge, 6);
elevenCharacterStringStart = 13;
elevenCharacterStringEnd = 23;
}
else if (opCode == displayMessages && checkSumGood == true ) {
elevenCharacterStringStart = 7;
elevenCharacterStringEnd = 17;
}
if (opCode != 0xF3 && checkSumGood == true ) {
Serial.write(acknowledge, 6);
}
}
//EXAMPLE MENU PACKET 24 09 81 2E 02 02 55 4D 45 4E 55 20 8A 03 (display 0, 0)
if (opCode == displayMessages && subOpCode == elevenCharacterStringSubOpCode ) {
for (int i = elevenCharacterStringStart, j = 0; i <= elevenCharacterStringEnd; i++, j++) { // 7 - 17
elevenCharacterString[j] = dataBuffer[i];
elevenCharacterString[j + 1] = '\0';
}
}
u8g.firstPage();
do {
draw();
}
while ( u8g.nextPage() );
}
void draw(void) {
u8g.setFont(u8g_font_fub25r);
u8g.drawStr( 0, 45, elevenCharacterString);
}
void keypadEvent(KeypadEvent key) {
switch (keypad.getState()) {
case PRESSED:
switch (key) {
case 'X':
Serial.write(X, 10);
// mySerial.write(X, 10);
break;
case 'arrowDown':
Serial.write(arrowDown, 10);
break;
case 'MENU':
Serial.write(buttonMENU, 10);
break;
case 'Enter':
Serial.write(buttonEnter, 10);
break;
}
break;
case HOLD:
switch (key) {
case 'X':
Serial.write(X, 10);
break;
case 'arrowDown':
Serial.write(arrowDown, 10);
break;
case 'MENU':
Serial.write(buttonMENU, 10);
break;
case 'Enter':
Serial.write(buttonEnter, 10);
break;
}
break;
case RELEASED:
switch (key) {
case 'X':
Serial.write(buttonRelease, 10);
//mySerial.write(buttonRelease, 10);
break;
}
}
}