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###################################################
#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
const int Inputs = 2; //number of inputs using internal Pullup resistor. (short to ground to trigger)
int InPinmap[] = {8,9};
#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.
#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
const int sInputs = 1; //number of inputs using internal Pullup resistor. (short to ground to trigger)
int sInPinmap[] = {10};
@ -89,7 +89,7 @@ Communication Status = 'E' -read/Write -Pin State: 0:0
int PwmOutPinmap[] = {12,11};
#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.
#ifdef AINPUTS
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.
*/
#define LPOTIS
//#define LPOTIS
#ifdef LPOTIS
const int 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
const int BinSelKnobPins[] = {2,6,4,3,5}; //1,2,4,8,16
#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.
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
const int numRows = 4; // Define the number of rows 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 colPins[numCols] = {6, 7, 8, 9};
int keys[numRows][numCols] = {0};
int lastKey= -1;
#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 ###########################
//###Misc Settings###
@ -319,6 +339,9 @@ const int debounceDelay = 50;
#ifdef KEYPAD
byte KeyState = 0;
#endif
#ifdef MULTIPLEXLEDS
byte KeyLedStates[numRows*numCols];
#endif
#if QUADENCS == 1
const int QuadEncs = 1;
#endif
@ -470,7 +493,7 @@ void loop() {
#ifdef JOYSTICK
readJoySticks(); //read Encoders & send data
#endif
multiplexLeds();
}
@ -563,9 +586,7 @@ void readEncoders(){
}
#endif
void initialiseIO(){
}
void comalive(){
if(lastcom == 0){ //no connection yet. send E0:0 periodicly and wait for response
while (lastcom == 0){
@ -621,7 +642,7 @@ void reconnect(){
Serial.println("resending Data");
#endif
#ifdef INPUT
#ifdef INPUTS
for (int x = 0; x < Inputs; x++){
InState[x]= -1;
}
@ -662,7 +683,9 @@ void reconnect(){
#ifdef BINSEL
readAbsKnob(); //read ABS Encoder & send data
#endif
#ifdef MULTIPLEXLEDS
multiplexLeds(); //Flash LEDS.
#endif
connectionState = 1;
@ -862,7 +885,7 @@ int readAbsKnob(){
#ifdef KEYPAD
void readKeypad(){
//detect if Button is Pressed
for (int col = 0; col < numCols; col++) {
for (int col = 0; col < numCols; col++) {
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], LOW);
// Read the state of the row pins
@ -873,6 +896,7 @@ void readKeypad(){
sendData('M',keys[row][col],1);
lastKey = keys[row][col];
row = numRows;
}
if (digitalRead(rowPins[row]) == HIGH && lastKey == keys[row][col]) {
// The Last Button has been unpressed
@ -885,9 +909,45 @@ void readKeypad(){
// Set the column pin back to input mode
pinMode(colPins[col], INPUT);
}
}
#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){
#ifdef OUTPUTS
if(cmd == 'O'){
@ -916,6 +976,21 @@ void commandReceived(char cmd, uint16_t io, uint16_t value){
}
#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'){
lastcom=millis();
if(connectionState == 2){

View File

@ -29,6 +29,7 @@ import serial, time, hal
# Latching Potentiometers = 'L' -write only -Pin State: 0-max Position
# binary encoded Selector = 'K' -write only -Pin State: 0-32
# 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)
# 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
#
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.
######## End of Config! ########
# global Variables for State Saving
olddOutStates= [0]*Outputs
oldPwmOutStates=[0]*PwmOutputs
oldDLEDStates=[0]*DLEDcount
oldMledStates = [0]*LedVccPins*LedGndPins
if LinuxKeyboardInput:
import subprocess
@ -241,6 +249,11 @@ if Keypad > 0:
if Destination[port] == 0 & LinuxKeyboardInput:
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
if JoySticks > 0:
@ -326,8 +339,22 @@ def managageOutputs():
if (Debug):print ("Sending:{}".format(command.encode()))
oldDLEDStates[dled] = State
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: