adding Arduino Support for Matrix Keyboards

This Feature was requested in Discord.
With This Update your Arduino now can read Matrix Keyboards.
Keys are send with Identifier "M".
This commit is contained in:
Alexander Richter 2023-03-28 16:24:39 +02:00
parent 474c57a8e1
commit f49181389a

View File

@ -20,6 +20,8 @@
To begin Transmitting Ready is send out and expects to receive E: to establish connection. Afterwards Data is exchanged. To begin Transmitting Ready is send out and expects to receive E: to establish connection. Afterwards Data is exchanged.
Data is only send everythime it changes once. Data is only send everythime it changes once.
LinuxCNC HAL Pins:
Inputs = 'I' -write only -Pin State: 0,1 Inputs = 'I' -write only -Pin State: 0,1
Outputs = 'O' -read only -Pin State: 0,1 Outputs = 'O' -read only -Pin State: 0,1
PWM Outputs = 'P' -read only -Pin State: 0-255 PWM Outputs = 'P' -read only -Pin State: 0-255
@ -28,9 +30,17 @@
Latching Potentiometers = 'L' -write only -Pin State: 0-max Position Latching Potentiometers = 'L' -write only -Pin State: 0-max Position
Absolute Encoder input = 'K' -write only -Pin State: 0-32 Absolute Encoder input = 'K' -write only -Pin State: 0-32
Keyboard Input:
Matrix Keypad = 'M' -write only -Pin State: Number of Matrix Key.
Communication Status = 'E' -read/Write -Pin State: 0:0
The Keyboard is encoded in the Number of the Key in the Matrix. The according Letter is defined in the receiving end in the Python Skript.
Here you only define the Size of the Matrix.
Command 'E0:0' is used for connectivity checks and is send every 5 seconds as keep alive signal. If the Signal is not received again, the Status LED will Flash.
The Board will still work as usual and try to send it's data, so this feature is only to inform the User.
Command 'E0:0' is used for connectivity checks and is send every 5 seconds as keep alive signal
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -79,7 +89,7 @@
#endif #endif
//#define LPOTIS
/*This is a special mode of AInputs. My machine had originally Selector Knobs with many Pins on the backside to select different Speed Settings. /*This is a special mode of AInputs. My machine had originally Selector Knobs with many Pins on the backside to select different Speed Settings.
I turned them into a "Potentiometer" by connecting all Pins with 10K Resistors in series. Then i applied GND to the first and 5V to the last Pin. I turned them into a "Potentiometer" by connecting all Pins with 10K Resistors in series. Then i applied GND to the first and 5V to the last Pin.
Now the Selector is part of an Voltage Divider and outputs different Voltage for each Position. This function generates Pins for each Position in Linuxcnc Hal. Now the Selector is part of an Voltage Divider and outputs different Voltage for each Position. This function generates Pins for each Position in Linuxcnc Hal.
@ -94,6 +104,7 @@
Note that Analog Pin numbering is different to the Print on the PCB. Note that Analog Pin numbering is different to the Print on the PCB.
*/ */
//#define LPOTIS
#ifdef LPOTIS #ifdef LPOTIS
const int LPotis = 2; const int LPotis = 2;
int LPotiPins[LPotis][2] = { int LPotiPins[LPotis][2] = {
@ -109,7 +120,7 @@
#endif #endif
//#define STATUSLED //The Software will detect if there is an communication issue. When you power on your machine, the Buttons etc won't work, till LinuxCNC is running. THe StatusLED will inform you about the State of Communication. //The Software will detect if there is an communication issue. When you power on your machine, the Buttons etc won't work, till LinuxCNC is running. THe StatusLED will inform you about the State of Communication.
// Slow Flash = Not Connected // Slow Flash = Not Connected
// Steady on = connected // Steady on = connected
// short Flash = connection lost. // short Flash = connection lost.
@ -117,6 +128,7 @@
// if connection is lost, something happened. (Linuxcnc was closed for example or USB Connection failed.) It will recover when Linuxcnc is restartet. (you could also run "unloadusr arduino", "loadusr arduino" in Hal) // if connection is lost, something happened. (Linuxcnc was closed for example or USB Connection failed.) It will recover when Linuxcnc is restartet. (you could also run "unloadusr arduino", "loadusr arduino" in Hal)
// Define an Pin you want to connect the LED to. it will be set as Output indipendand of the OUTPUTS function, so don't use Pins twice. // Define an Pin you want to connect the LED to. it will be set as Output indipendand of the OUTPUTS function, so don't use Pins twice.
// If you use Digital LED's such as WS2812 or PL9823 (only works if you set up the DLED settings below) you can also define a position of the LED. In this case StatLedPin will set the number of the Digital LED Chain. // If you use Digital LED's such as WS2812 or PL9823 (only works if you set up the DLED settings below) you can also define a position of the LED. In this case StatLedPin will set the number of the Digital LED Chain.
//#define STATUSLED
#ifdef STATUSLED #ifdef STATUSLED
const int StatLedPin = 5; //Pin for Status LED const int StatLedPin = 5; //Pin for Status LED
const int StatLedErrDel[] = {1000,10}; //Blink Timing for Status LED Error (no connection) const int StatLedErrDel[] = {1000,10}; //Blink Timing for Status LED Error (no connection)
@ -125,7 +137,7 @@
//#define DLED
/* Instead of connecting LED's to Output pins, you can also connect digital LED's such as WS2812 or PL9823. /* Instead of connecting LED's to Output pins, you can also connect digital LED's such as WS2812 or PL9823.
This way you can have how many LED's you want and also define it's color with just one Pin. This way you can have how many LED's you want and also define it's color with just one Pin.
@ -144,6 +156,8 @@
If you use STATUSLED, it will also take the colors of your definition here. If you use STATUSLED, it will also take the colors of your definition here.
*/ */
//#define DLED
#ifdef DLED #ifdef DLED
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
@ -178,8 +192,29 @@ Adafruit_NeoPixel strip(DLEDcount, DLEDPin, NEO_GRB + NEO_KHZ800);//Color sequen
#endif #endif
/*
Matrix Keypads are supported. The input is NOT added as HAL Pin to LinuxCNC. Instead it is inserted to Linux as Keyboard direktly.
So you could attach a QWERT* Keyboard to the arduino and you will be able to write in Linux with it (only while LinuxCNC is running!)
*/
#define KEYPAD
#ifdef KEYPAD
const int numRows = 4; // Define the number of rows in the matrix
const int numCols = 4; // Define the number of columns in the matrix
// Define the pins connected to the rows and columns of the matrix
const int rowPins[numRows] = {2, 3, 4, 5};
const int colPins[numCols] = {6, 7, 8, 9};
int keys[numRows][numCols] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16}
};
int lastKey= 0;
#endif
//###Misc Settings### //###Misc Settings###
@ -210,7 +245,9 @@ const int timeout = 10000; // timeout after 10 sec not receiving Stuff
#ifdef ABSENCODER #ifdef ABSENCODER
int oldAbsEncState; int oldAbsEncState;
#endif #endif
#ifdef KEYPAD
byte KeyState = 0;
#endif
//### global Variables setup### //### global Variables setup###
@ -278,6 +315,14 @@ void setup() {
initDLED(); initDLED();
#endif #endif
#ifdef KEYPAD
for(int col = 0; col < numCols; col++) {
for (int row = 0; row < numRows; row++) {
keys[row][col] = row * numRows + col+1;
}
}
#endif
//Setup Serial //Setup Serial
Serial.begin(115200); Serial.begin(115200);
while (!Serial){} while (!Serial){}
@ -289,7 +334,6 @@ void setup() {
StatLedErr(1000,1000); StatLedErr(1000,1000);
#endif #endif
} }
} }
@ -312,6 +356,10 @@ void loop() {
readAbsKnob(); //read ABS Encoder & send data readAbsKnob(); //read ABS Encoder & send data
#endif #endif
#ifdef KEYPAD
readKeypad(); //read Keyboard & send data
#endif
} }
@ -486,6 +534,40 @@ int readAbsKnob(){
} }
#endif #endif
void readKeypad(){
//detect if Button is Pressed
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], LOW);
// Read the state of the row pins
for (int row = 0; row < numRows; row++) {
pinMode(rowPins[row], INPUT_PULLUP);
if (digitalRead(rowPins[row]) == LOW && lastKey != keys[row][col]) {
// A button has been pressed
Serial.print("M");
Serial.print(keys[row][col]);
Serial.print(":");
Serial.println(1);
lastKey = keys[row][col];
row = numRows;
}
if (digitalRead(rowPins[row]) == HIGH && lastKey == keys[row][col]) {
// The Last Button has been unpressed
Serial.print("M");
Serial.print(keys[row][col]);
Serial.print(":");
Serial.println(0);
lastKey = 0;
row = numRows;
}
}
// Set the column pin back to input mode
pinMode(colPins[col], INPUT);
}
}
void commandReceived(char cmd, uint16_t io, uint16_t value){ void commandReceived(char cmd, uint16_t io, uint16_t value){
#ifdef OUTPUTS #ifdef OUTPUTS
if(cmd == 'O'){ if(cmd == 'O'){
@ -497,11 +579,12 @@ void commandReceived(char cmd, uint16_t io, uint16_t value){
writePwmOutputs(io,value); writePwmOutputs(io,value);
} }
#endif #endif
//#ifdef DLED #ifdef DLED
if(cmd == 'D'){ if(cmd == 'D'){
controlDLED(io,value); controlDLED(io,value);
} }
//#endif #endif
if(cmd == 'E'){ if(cmd == 'E'){
lastcom=millis(); lastcom=millis();
} }
@ -516,6 +599,7 @@ void commandReceived(char cmd, uint16_t io, uint16_t value){
#endif #endif
} }
//This Funktion checks if Received Command is valid. Insert your custom Letter here by inserting another "||cmd == 'X'"
int isCmdChar(char cmd){ int isCmdChar(char cmd){
if(cmd == 'O'||cmd == 'P'||cmd == 'E'||cmd == 'D') {return true;} if(cmd == 'O'||cmd == 'P'||cmd == 'E'||cmd == 'D') {return true;}
else{return false;} else{return false;}