Merge branch 'keyboard_dev'
This commit is contained in:
commit
363e8582ef
@ -16,6 +16,7 @@
|
|||||||
- digital Inputs
|
- digital Inputs
|
||||||
- digital Outputs
|
- digital Outputs
|
||||||
- Matrix Keypad
|
- Matrix Keypad
|
||||||
|
- Multiplexed LEDs
|
||||||
- Quadrature encoders
|
- Quadrature encoders
|
||||||
- Joysticks
|
- Joysticks
|
||||||
|
|
||||||
@ -32,9 +33,10 @@
|
|||||||
binary encoded Selector = 'K' -write only -Pin State: 0-32
|
binary encoded Selector = 'K' -write only -Pin State: 0-32
|
||||||
rotary encoder = 'R' -write only -Pin State: up/ down / -2147483648 to 2147483647
|
rotary encoder = 'R' -write only -Pin State: up/ down / -2147483648 to 2147483647
|
||||||
joystick = 'R' -write only -Pin State: up/ down / -2147483648 to 2147483647
|
joystick = 'R' -write only -Pin State: up/ down / -2147483648 to 2147483647
|
||||||
|
multiplexed LEDs = 'M' -read only -Pin State: 0,1
|
||||||
|
|
||||||
Keyboard Input:
|
Keyboard Input:
|
||||||
Matrix Keypad = 'M' -write only -Pin State: Number of Matrix Key.
|
Matrix Keypad = 'M' -write only -Pin State: 0,1
|
||||||
|
|
||||||
Communication Status = 'E' -read/Write -Pin State: 0:0
|
Communication Status = 'E' -read/Write -Pin State: 0:0
|
||||||
|
|
||||||
@ -77,7 +79,7 @@ Communication Status = 'E' -read/Write -Pin State: 0:0
|
|||||||
int sInPinmap[] = {10};
|
int sInPinmap[] = {10};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define OUTPUTS //Use Arduino IO's as Outputs. Define how many Outputs you want in total and then which Pins you want to be Outputs.
|
#define OUTPUTS //Use Arduino IO's as Outputs. Define how many Outputs you want in total and then which Pins you want to be Outputs.
|
||||||
#ifdef OUTPUTS
|
#ifdef OUTPUTS
|
||||||
const int Outputs = 2; //number of outputs
|
const int Outputs = 2; //number of outputs
|
||||||
int OutPinmap[] = {11,12};
|
int OutPinmap[] = {11,12};
|
||||||
@ -89,7 +91,7 @@ Communication Status = 'E' -read/Write -Pin State: 0:0
|
|||||||
int PwmOutPinmap[] = {12,11};
|
int PwmOutPinmap[] = {12,11};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define AINPUTS //Use Arduino ADC's as Analog Inputs. Define how many Analog Inputs you want in total and then which Pins you want to be Analog Inputs.
|
//#define AINPUTS //Use Arduino ADC's as Analog Inputs. Define how many Analog Inputs you want in total and then which Pins you want to be Analog Inputs.
|
||||||
//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.
|
||||||
#ifdef AINPUTS
|
#ifdef AINPUTS
|
||||||
const int AInputs = 1;
|
const int AInputs = 1;
|
||||||
@ -113,7 +115,7 @@ Then in the Array, {which Pin, How many Positions}
|
|||||||
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
|
//#define LPOTIS
|
||||||
#ifdef LPOTIS
|
#ifdef LPOTIS
|
||||||
const int LPotis = 2;
|
const int LPotis = 2;
|
||||||
const int LPotiPins[LPotis][2] = {
|
const int LPotiPins[LPotis][2] = {
|
||||||
@ -125,7 +127,7 @@ Note that Analog Pin numbering is different to the Print on the PCB.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BINSEL //Support of an Rotating Knob that was build in my Machine. It encodes 32 Positions with 5 Pins in Binary. This will generate 32 Pins in LinuxCNC Hal.
|
//#define BINSEL //Support of an Rotating Knob that was build in my Machine. It encodes 32 Positions with 5 Pins in Binary. This will generate 32 Pins in LinuxCNC Hal.
|
||||||
#ifdef BINSEL
|
#ifdef BINSEL
|
||||||
const int BinSelKnobPins[] = {2,6,4,3,5}; //1,2,4,8,16
|
const int BinSelKnobPins[] = {2,6,4,3,5}; //1,2,4,8,16
|
||||||
#endif
|
#endif
|
||||||
@ -166,7 +168,7 @@ Encoder Encoder1(31,33); //A,B Pin
|
|||||||
const int QuadEncSig[] = {2,2}; //define wich kind of Signal you want to generate.
|
const int QuadEncSig[] = {2,2}; //define wich kind of Signal you want to generate.
|
||||||
//1= send up or down signal (typical use for selecting modes in hal)
|
//1= send up or down signal (typical use for selecting modes in hal)
|
||||||
//2= send position signal (typical use for MPG wheel)
|
//2= send position signal (typical use for MPG wheel)
|
||||||
const int QuadEncMp[] = {1,4}; //some Rotary encoders send multiple Electronical Impulses per mechanical pulse. How many Electrical impulses are send for each mechanical Latch?
|
const int QuadEncMp[] = {4,4}; //some Rotary encoders send multiple Electronical Impulses per mechanical pulse. How many Electrical impulses are send for each mechanical Latch?
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -269,15 +271,39 @@ const int numCols = 4; // Define the number of columns in the matrix
|
|||||||
// Define the pins connected to the rows and columns of the matrix
|
// Define the pins connected to the rows and columns of the matrix
|
||||||
const int rowPins[numRows] = {2, 3, 4, 5};
|
const int rowPins[numRows] = {2, 3, 4, 5};
|
||||||
const int colPins[numCols] = {6, 7, 8, 9};
|
const int colPins[numCols] = {6, 7, 8, 9};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int keys[numRows][numCols] = {0};
|
int keys[numRows][numCols] = {0};
|
||||||
|
|
||||||
int lastKey= -1;
|
int lastKey= -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//#define MULTIPLEXLEDS // Special mode for Multiplexed LEDs. This mode is experimental and implemented to support Matrix Keyboards with integrated Key LEDs.
|
||||||
|
// check out this thread on LinuxCNC Forum for context. https://forum.linuxcnc.org/show-your-stuff/49606-matrix-keyboard-controlling-linuxcnc
|
||||||
|
// for Each LED an Output Pin is generated in LinuxCNC.
|
||||||
|
|
||||||
|
//If your Keyboard shares pins with the LEDs, you have to check polarity.
|
||||||
|
//rowPins[numRows] = {} are Pullup Inputs
|
||||||
|
//colPins[numCols] = {} are GND Pins
|
||||||
|
//the matrix keyboard described in the thread shares GND Pins between LEDs and KEys, therefore LedGndPins[] and colPins[numCols] = {} use same Pins.
|
||||||
|
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
|
||||||
|
const int numVccPins = 8; // Number of rows in the matrix
|
||||||
|
const int numGndPins = 8; // Number of columns in the matrix
|
||||||
|
const int LedVccPins[] = {30,31,32,33,34,35,36,37}; // Arduino pins connected to rows
|
||||||
|
const int LedGndPins[] = {40,41,42,43,44,45,46,47}; // Arduino pins connected to columns
|
||||||
|
|
||||||
|
// Define the LED matrix
|
||||||
|
int ledStates[numVccPins*numGndPins] = {0};
|
||||||
|
|
||||||
|
unsigned long previousMillis = 0;
|
||||||
|
const unsigned long interval = 500; // Time (in milliseconds) per LED display
|
||||||
|
|
||||||
|
int currentLED = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
//####################################### END OF CONFIG ###########################
|
//####################################### END OF CONFIG ###########################
|
||||||
|
|
||||||
@ -319,6 +345,9 @@ const int debounceDelay = 50;
|
|||||||
#ifdef KEYPAD
|
#ifdef KEYPAD
|
||||||
byte KeyState = 0;
|
byte KeyState = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
byte KeyLedStates[numVccPins*numGndPins];
|
||||||
|
#endif
|
||||||
#if QUADENCS == 1
|
#if QUADENCS == 1
|
||||||
const int QuadEncs = 1;
|
const int QuadEncs = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -467,13 +496,15 @@ void loop() {
|
|||||||
#ifdef QUADENC
|
#ifdef QUADENC
|
||||||
readEncoders(); //read Encoders & send data
|
readEncoders(); //read Encoders & send data
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JOYSTICK
|
#ifdef JOYSTICK
|
||||||
readJoySticks(); //read Encoders & send data
|
readJoySticks(); //read Encoders & send data
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
multiplexLeds();// cycle through the 2D LED Matrix}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef JOYSTICK
|
#ifdef JOYSTICK
|
||||||
|
|
||||||
void readJoySticks() {
|
void readJoySticks() {
|
||||||
@ -563,9 +594,7 @@ void readEncoders(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
void initialiseIO(){
|
|
||||||
|
|
||||||
}
|
|
||||||
void comalive(){
|
void comalive(){
|
||||||
if(lastcom == 0){ //no connection yet. send E0:0 periodicly and wait for response
|
if(lastcom == 0){ //no connection yet. send E0:0 periodicly and wait for response
|
||||||
while (lastcom == 0){
|
while (lastcom == 0){
|
||||||
@ -662,7 +691,9 @@ void reconnect(){
|
|||||||
#ifdef BINSEL
|
#ifdef BINSEL
|
||||||
readAbsKnob(); //read ABS Encoder & send data
|
readAbsKnob(); //read ABS Encoder & send data
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
multiplexLeds(); //Flash LEDS.
|
||||||
|
#endif
|
||||||
|
|
||||||
connectionState = 1;
|
connectionState = 1;
|
||||||
|
|
||||||
@ -873,6 +904,7 @@ void readKeypad(){
|
|||||||
sendData('M',keys[row][col],1);
|
sendData('M',keys[row][col],1);
|
||||||
lastKey = keys[row][col];
|
lastKey = keys[row][col];
|
||||||
row = numRows;
|
row = numRows;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (digitalRead(rowPins[row]) == HIGH && lastKey == keys[row][col]) {
|
if (digitalRead(rowPins[row]) == HIGH && lastKey == keys[row][col]) {
|
||||||
// The Last Button has been unpressed
|
// The Last Button has been unpressed
|
||||||
@ -885,6 +917,54 @@ void readKeypad(){
|
|||||||
// Set the column pin back to input mode
|
// Set the column pin back to input mode
|
||||||
pinMode(colPins[col], INPUT);
|
pinMode(colPins[col], INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
void multiplexLeds() {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
//init Multiplex
|
||||||
|
#ifdef KEYPAD //if Keyboard is presend disable Pullup Resistors to not mess with LEDs while a Button is pressed.
|
||||||
|
for (int row = 0; row < numRows; row++) {
|
||||||
|
pinMode(rowPins[row], OUTPUT);
|
||||||
|
digitalWrite(rowPins[row], LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < numVccPins; i++) {
|
||||||
|
pinMode(LedVccPins[i], OUTPUT);
|
||||||
|
digitalWrite(LedVccPins[i], LOW); // Set to LOW to disable all Vcc Pins
|
||||||
|
}
|
||||||
|
for (int i = 0; i < numGndPins; i++) {
|
||||||
|
pinMode(LedGndPins[i], OUTPUT);
|
||||||
|
digitalWrite(LedGndPins[i], HIGH); // Set to HIGH to disable all GND Pins
|
||||||
|
}
|
||||||
|
|
||||||
|
for(currentLED = 0; currentLED < numVccPins*numGndPins ;currentLED ++){
|
||||||
|
if(ledStates[currentLED] == 1){ //only handle turned on LEDs
|
||||||
|
digitalWrite(LedVccPins[currentLED/numVccPins],HIGH); //turn current LED on
|
||||||
|
digitalWrite(LedGndPins[currentLED%numVccPins],LOW);
|
||||||
|
|
||||||
|
Serial.print("VCC: ");
|
||||||
|
Serial.print(LedVccPins[currentLED/numVccPins]);
|
||||||
|
Serial.print(" GND: ");
|
||||||
|
Serial.println(LedGndPins[currentLED%numVccPins]);
|
||||||
|
|
||||||
|
delayMicroseconds(interval); //wait couple ms
|
||||||
|
digitalWrite(LedVccPins[currentLED/numVccPins],LOW); //turn off and go to next one
|
||||||
|
digitalWrite(LedGndPins[currentLED%numVccPins],HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
}
|
||||||
|
if(ledStates[currentLED]==0){//If currentLED is Off, manage next one.
|
||||||
|
currentLED++;
|
||||||
|
}
|
||||||
|
if(currentLED >= numVccPins*numGndPins){
|
||||||
|
currentLED= 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -916,6 +996,21 @@ void commandReceived(char cmd, uint16_t io, uint16_t value){
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MULTIPLEXLEDS
|
||||||
|
if(cmd == 'M'){
|
||||||
|
ledStates[io] = value; // Set the LED state
|
||||||
|
lastcom=millis();
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("multiplexed Led No:");
|
||||||
|
Serial.print(io);
|
||||||
|
Serial.print("Set to:");
|
||||||
|
Serial.println(ledStates[io]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if(cmd == 'E'){
|
if(cmd == 'E'){
|
||||||
lastcom=millis();
|
lastcom=millis();
|
||||||
if(connectionState == 2){
|
if(connectionState == 2){
|
||||||
|
16
README.md
16
README.md
@ -32,6 +32,9 @@ It also supports Digital LEDs such as WS2812 or PL9823. This way you can have as
|
|||||||
| binary encoded Selector Switch | 1 | 1 | 1 |
|
| binary encoded Selector Switch | 1 | 1 | 1 |
|
||||||
| Quadrature Encoder Input | 3 or more | 1 or more | 1 or more |
|
| Quadrature Encoder Input | 3 or more | 1 or more | 1 or more |
|
||||||
| Joystick Support (2Axis) | 8 | 6 | 3 |
|
| Joystick Support (2Axis) | 8 | 6 | 3 |
|
||||||
|
| Matrix Keyboard | 1 | 1 | 1 |
|
||||||
|
| Multiplexed LEDs | ~ 1000 | ~ 1000 | ~ 1000 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Compatiblity
|
# Compatiblity
|
||||||
@ -168,6 +171,19 @@ If it doesn't, something is not working and this program will not work either. P
|
|||||||
|
|
||||||
In the Settings a cheap 4x4 Keyboard is used such as https://theartoftinkering.com/recommends/matrix-keyboard/ (referral link)
|
In the Settings a cheap 4x4 Keyboard is used such as https://theartoftinkering.com/recommends/matrix-keyboard/ (referral link)
|
||||||
|
|
||||||
|
# Multiplexed LEDs
|
||||||
|
Special mode for Multiplexed LEDs. This mode is experimental and implemented to support Matrix Keyboards with integrated Key LEDs. Please provide feedback if u use this feature.
|
||||||
|
check out this thread on LinuxCNC Forum for context. https://forum.linuxcnc.org/show-your-stuff/49606-matrix-keyboard-controlling-linuxcnc
|
||||||
|
for Each LED an Output Pin is generated in LinuxCNC.
|
||||||
|
|
||||||
|
If your Keyboard shares pins with the LEDs, you have to check polarity. The Matrix Keyboard uses Pins as such:
|
||||||
|
|
||||||
|
rowPins[numRows] = {} are Pullup Inputs
|
||||||
|
colPins[numCols] = {} are GND Pins
|
||||||
|
|
||||||
|
the matrix keyboard described in the thread shares GND Pins between LEDs and KEYs, therefore LedGndPins[] and colPins[numCols] = {} use same Pins, LedVccPins[] are Outputs and drive the LEDs.
|
||||||
|
|
||||||
|
|
||||||
# Quadrature Encoders
|
# Quadrature Encoders
|
||||||
Quadrature Encoders require a Library to be installed.
|
Quadrature Encoders require a Library to be installed.
|
||||||
More Info about the used Library can be found here: https://www.pjrc.com/teensy/td_libs_Encoder.html
|
More Info about the used Library can be found here: https://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||||
|
@ -29,6 +29,7 @@ import serial, time, hal
|
|||||||
# Latching Potentiometers = 'L' -write only -Pin State: 0-max Position
|
# Latching Potentiometers = 'L' -write only -Pin State: 0-max Position
|
||||||
# binary encoded Selector = 'K' -write only -Pin State: 0-32
|
# binary encoded Selector = 'K' -write only -Pin State: 0-32
|
||||||
# Matrix Keypad = 'M' -write only -Pin State: 0,1
|
# Matrix Keypad = 'M' -write only -Pin State: 0,1
|
||||||
|
# Multiplexed LEDs = 'M' -read only -Pin State: 0,1
|
||||||
# Quadrature Encoders = 'R' -write only -Pin State: 0(down),1(up),-2147483648 to 2147483647(counter)
|
# Quadrature Encoders = 'R' -write only -Pin State: 0(down),1(up),-2147483648 to 2147483647(counter)
|
||||||
# Joystick Input = 'R' -write only -Pin State: -2147483648 to 2147483647(counter)
|
# Joystick Input = 'R' -write only -Pin State: -2147483648 to 2147483647(counter)
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ DLEDcount = 0
|
|||||||
|
|
||||||
|
|
||||||
Keypad = 0 # Set to 1 to Activate
|
Keypad = 0 # Set to 1 to Activate
|
||||||
LinuxKeyboardInput = 1 #Activate direct Keyboard integration to Linux.
|
LinuxKeyboardInput = 0 # set to 1 to Activate direct Keyboard integration to Linux.
|
||||||
|
|
||||||
|
|
||||||
Columns = 4
|
Columns = 4
|
||||||
@ -166,16 +167,25 @@ Destination = [ #define, which Key should be inserted in LinuxCNC as Input or
|
|||||||
# 12, 13, 14, 15
|
# 12, 13, 14, 15
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# this is an experimental feature, meant to support MatrixKeyboards with integrated LEDs in each Key but should work with any other LED Matrix too.
|
||||||
|
# It creates Output Halpins that can be connected to signals in LinuxCNC
|
||||||
|
MultiplexLED = 0 # Set to 1 to Activate
|
||||||
|
LedVccPins = 3
|
||||||
|
LedGndPins = 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Debug = 0 #only works when this script is run from halrun in Terminal. "halrun","loadusr arduino" now Debug info will be displayed.
|
Debug = 0 #only works when this script is run from halrun in Terminal. "halrun","loadusr arduino" now Debug info will be displayed.
|
||||||
|
|
||||||
######## End of Config! ########
|
######## End of Config! ########
|
||||||
|
|
||||||
|
|
||||||
|
# global Variables for State Saving
|
||||||
|
|
||||||
olddOutStates= [0]*Outputs
|
olddOutStates= [0]*Outputs
|
||||||
oldPwmOutStates=[0]*PwmOutputs
|
oldPwmOutStates=[0]*PwmOutputs
|
||||||
oldDLEDStates=[0]*DLEDcount
|
oldDLEDStates=[0]*DLEDcount
|
||||||
|
oldMledStates = [0]*LedVccPins*LedGndPins
|
||||||
|
|
||||||
if LinuxKeyboardInput:
|
if LinuxKeyboardInput:
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -241,6 +251,11 @@ if Keypad > 0:
|
|||||||
if Destination[port] == 0 & LinuxKeyboardInput:
|
if Destination[port] == 0 & LinuxKeyboardInput:
|
||||||
c.newpin("keypad.{}".format(Chars[port]), hal.HAL_BIT, hal.HAL_IN)
|
c.newpin("keypad.{}".format(Chars[port]), hal.HAL_BIT, hal.HAL_IN)
|
||||||
|
|
||||||
|
# setup MultiplexLED halpins
|
||||||
|
if MultiplexLED > 0:
|
||||||
|
for port in range(LedVccPins*LedGndPins):
|
||||||
|
c.newpin("mled.{}".format(port), hal.HAL_BIT, hal.HAL_OUT)
|
||||||
|
|
||||||
|
|
||||||
#setup JoyStick Pins
|
#setup JoyStick Pins
|
||||||
if JoySticks > 0:
|
if JoySticks > 0:
|
||||||
@ -326,8 +341,17 @@ def managageOutputs():
|
|||||||
if (Debug):print ("Sending:{}".format(command.encode()))
|
if (Debug):print ("Sending:{}".format(command.encode()))
|
||||||
oldDLEDStates[dled] = State
|
oldDLEDStates[dled] = State
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
if MultiplexLED > 0:
|
||||||
|
for mled in range(LedVccPins*LedGndPins):
|
||||||
|
State = int(c["mled.{}".format(mled)])
|
||||||
|
if oldMledStates[mled] != State: #check if states have changed
|
||||||
|
Sig = 'M'
|
||||||
|
Pin = mled
|
||||||
|
command = "{}{}:{}\n".format(Sig,Pin,State)
|
||||||
|
arduino.write(command.encode())
|
||||||
|
if (Debug):print ("Sending:{}".format(command.encode()))
|
||||||
|
oldMledStates[mled] = State
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
Loading…
Reference in New Issue
Block a user