added multiplexed LED feature

This commit is contained in:
Alexander Richter 2023-09-13 18:09:38 +02:00
parent b5fbee0c37
commit 04840c0313
2 changed files with 122 additions and 20 deletions

View File

@ -64,14 +64,14 @@ Communication Status = 'E' -read/Write -Pin State: 0:0
//###################################################IO's################################################### //###################################################IO's###################################################
#define INPUTS //Use Arduino IO's as Inputs. Define how many Inputs you want in total and then which Pins you want to be Inputs. //#define INPUTS //Use Arduino IO's as Inputs. Define how many Inputs you want in total and then which Pins you want to be Inputs.
#ifdef INPUTS #ifdef INPUTS
const int Inputs = 2; //number of inputs using internal Pullup resistor. (short to ground to trigger) const int Inputs = 2; //number of inputs using internal Pullup resistor. (short to ground to trigger)
int InPinmap[] = {8,9}; int InPinmap[] = {8,9};
#endif #endif
//Use Arduino IO's as Toggle Inputs, which means Inputs (Buttons for example) keep HIGH State after Release and Send LOW only after beeing Pressed again. //Use Arduino IO's as Toggle Inputs, which means Inputs (Buttons for example) keep HIGH State after Release and Send LOW only after beeing Pressed again.
#define SINPUTS //Define how many Toggle Inputs you want in total and then which Pins you want to be Toggle Inputs. //#define SINPUTS //Define how many Toggle Inputs you want in total and then which Pins you want to be Toggle Inputs.
#ifdef SINPUTS #ifdef SINPUTS
const int sInputs = 1; //number of inputs using internal Pullup resistor. (short to ground to trigger) const int sInputs = 1; //number of inputs using internal Pullup resistor. (short to ground to trigger)
int sInPinmap[] = {10}; int sInPinmap[] = {10};
@ -89,7 +89,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 +113,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 +125,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
@ -261,7 +261,7 @@ Adafruit_NeoPixel strip(DLEDcount, DLEDPin, NEO_GRB + NEO_KHZ800);//Color sequen
Matrix Keypads are supported. The input is NOT added as HAL Pin to LinuxCNC. Instead it is inserted to Linux as Keyboard direktly. 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!) 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 #define KEYPAD
#ifdef KEYPAD #ifdef KEYPAD
const int numRows = 4; // Define the number of rows in the matrix const int numRows = 4; // Define the number of rows in the matrix
const int numCols = 4; // Define the number of columns in the matrix const int numCols = 4; // Define the number of columns in the matrix
@ -270,15 +270,35 @@ const int numCols = 4; // Define the number of columns in 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 DEBUG #define MULTIPLEXLEDS // Special mode for Multiplexed 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.
#ifdef MULTIPLEXLEDS
const int numVccPins = 4; // Number of rows in the matrix
const int numGndPins = 4; // Number of columns in the matrix
const int LedVccPins[] = {6, 3, 4, 5}; // Arduino pins connected to rows
const int LedGndPins[] = {2, 7, 8, 9}; // Arduino pins connected to columns
// Define the LED matrix
int ledStates[numVccPins*numGndPins] = {0};
unsigned long previousMillis = 0;
const unsigned long interval = 0; // Time (in milliseconds) per LED display
int currentLED = 0;
#endif
#define DEBUG
//####################################### END OF CONFIG ########################### //####################################### END OF CONFIG ###########################
//###Misc Settings### //###Misc Settings###
@ -319,6 +339,9 @@ const int debounceDelay = 50;
#ifdef KEYPAD #ifdef KEYPAD
byte KeyState = 0; byte KeyState = 0;
#endif #endif
#ifdef MULTIPLEXLEDS
byte KeyLedStates[numRows*numCols];
#endif
#if QUADENCS == 1 #if QUADENCS == 1
const int QuadEncs = 1; const int QuadEncs = 1;
#endif #endif
@ -470,7 +493,7 @@ void loop() {
#ifdef JOYSTICK #ifdef JOYSTICK
readJoySticks(); //read Encoders & send data readJoySticks(); //read Encoders & send data
#endif #endif
multiplexLeds();
} }
@ -563,9 +586,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){
@ -621,7 +642,7 @@ void reconnect(){
Serial.println("resending Data"); Serial.println("resending Data");
#endif #endif
#ifdef INPUT #ifdef INPUTS
for (int x = 0; x < Inputs; x++){ for (int x = 0; x < Inputs; x++){
InState[x]= -1; InState[x]= -1;
} }
@ -662,7 +683,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;
@ -862,7 +885,7 @@ int readAbsKnob(){
#ifdef KEYPAD #ifdef KEYPAD
void readKeypad(){ void readKeypad(){
//detect if Button is Pressed //detect if Button is Pressed
for (int col = 0; col < numCols; col++) { for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT); pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], LOW); digitalWrite(colPins[col], LOW);
// Read the state of the row pins // Read the state of the row pins
@ -873,6 +896,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,9 +909,45 @@ 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 #endif
void multiplexLeds() {
unsigned long currentMillis = millis();
//init Multiplex
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
}
if(ledStates[currentLED]==1){
digitalWrite(LedVccPins[currentLED%numVccPins],ledStates[currentLED]);
digitalWrite(LedGndPins[currentLED/numVccPins],LOW);
Serial.print(currentLED/numVccPins); //row
Serial.print(":");
Serial.println(currentLED%numVccPins); //column
//delay(1);
}
else{ //ignore LEDs that are shut off...
currentLED++;
previousMillis = currentMillis;
}
if (currentMillis - previousMillis >= interval) { // Check if it's time to update the LED matrix
previousMillis = currentMillis; // Save the last update time
currentLED++;
}
if(currentLED >= numVccPins*numGndPins){
currentLED= 0;
}
}
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'){
@ -916,6 +976,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){

View File

@ -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)
@ -166,16 +167,23 @@ Destination = [ #define, which Key should be inserted in LinuxCNC as Input or
# 12, 13, 14, 15 # 12, 13, 14, 15
# #
MultiplexLED = 1 # Set to 1 to Activate
LedVccPins = 4
LedGndPins = 4
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 +249,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:
@ -327,7 +340,21 @@ def managageOutputs():
oldDLEDStates[dled] = State oldDLEDStates[dled] = State
time.sleep(0.01) time.sleep(0.01)
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)
# setup MultiplexLED halpins
if MultiplexLED > 0:
for port in range(LedVccPins*LedGndPins):
c.newpin("mled.{}".format(port), hal.HAL_BIT, hal.HAL_OUT)
while True: while True: