Support for WS2812 and PL9823 Digital LEDs
This Update includes the support of digital LEDs. Therefore we can now attach unlimited RGB LEDs to LinuxCNC. YAY
This commit is contained in:
parent
9fb2e54453
commit
fa6d5fa80a
@ -23,10 +23,13 @@
|
|||||||
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
|
||||||
|
Digital LED Outputs = 'D' -read only -Pin State: 0,1
|
||||||
Analog Inputs = 'A' -write only -Pin State: 0-1024
|
Analog Inputs = 'A' -write only -Pin State: 0-1024
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Command 'E0:0' is used for connectivity checks and is send every 5 seconds as keep alive signal
|
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
|
||||||
@ -46,33 +49,33 @@
|
|||||||
|
|
||||||
|
|
||||||
//###IO's###
|
//###IO's###
|
||||||
#define INPUTS
|
//#define INPUTS
|
||||||
#ifdef INPUTS
|
#ifdef INPUTS
|
||||||
const int Inputs = 16; //number of inputs using internal Pullup resistor. (short to ground to trigger)
|
const int Inputs = 16; //number of inputs using internal Pullup resistor. (short to ground to trigger)
|
||||||
int InPinmap[] = {32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48};
|
int InPinmap[] = {32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define OUTPUTS
|
//#define OUTPUTS
|
||||||
#ifdef OUTPUTS
|
#ifdef OUTPUTS
|
||||||
const int Outputs = 9; //number of outputs
|
const int Outputs = 9; //number of outputs
|
||||||
int OutPinmap[] = {10,9,8,7,6,5,4,3,2,21};
|
int OutPinmap[] = {10,9,8,7,6,5,4,3,2,21};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PWMOUTPUTS
|
//#define PWMOUTPUTS
|
||||||
#ifdef PWMOUTPUTS
|
#ifdef PWMOUTPUTS
|
||||||
const int PwmOutputs = 2; //number of outputs
|
const int PwmOutputs = 2; //number of outputs
|
||||||
int PwmOutPinmap[] = {12,11};
|
int PwmOutPinmap[] = {12,11};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define AINPUTS
|
//#define AINPUTS
|
||||||
#ifdef AINPUTS
|
#ifdef AINPUTS
|
||||||
const int AInputs = 1;
|
const int AInputs = 1;
|
||||||
int AInPinmap[] = {1}; //Potentiometer for SpindleSpeed override
|
int AInPinmap[] = {1}; //Potentiometer for SpindleSpeed override
|
||||||
int smooth = 200; //number of samples to denoise ADC, try lower numbers on your setup
|
int smooth = 200; //number of samples to denoise ADC, try lower numbers on your setup
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LPOTIS
|
//#define LPOTIS
|
||||||
#ifdef LPOTIS
|
#ifdef LPOTIS
|
||||||
const int LPotis = 2;
|
const int LPotis = 2;
|
||||||
int LPotiPins[LPotis][2] = {
|
int LPotiPins[LPotis][2] = {
|
||||||
@ -82,7 +85,7 @@
|
|||||||
int margin = 20; //giving it some margin so Numbers dont jitter, make this number smaller if your knob has more than 50 Positions
|
int margin = 20; //giving it some margin so Numbers dont jitter, make this number smaller if your knob has more than 50 Positions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ABSENCODER
|
//#define ABSENCODER
|
||||||
#ifdef ABSENCODER
|
#ifdef ABSENCODER
|
||||||
const int AbsEncPins[] = {27,28,31,29,30}; //1,2,4,8,16
|
const int AbsEncPins[] = {27,28,31,29,30}; //1,2,4,8,16
|
||||||
#endif
|
#endif
|
||||||
@ -90,11 +93,56 @@
|
|||||||
|
|
||||||
#define STATUSLED
|
#define STATUSLED
|
||||||
#ifdef STATUSLED
|
#ifdef STATUSLED
|
||||||
const int StatLedPin = 13; //Pin for Status LED
|
const int StatLedPin = 0; //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)
|
||||||
|
const int DLEDSTATUSLED = 1; //set to 1 to use Digital LED instead. set StatLedPin to the according LED number in the chain.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Instead of connecting LED's to Output pins, you can also connect digital LED's such as DLED or PL9823.
|
||||||
|
DLEDcount defines, how many Digital LED's you want to control. For Each a output Pin will be generated in LinuxCNC hal. There are two modes supported.
|
||||||
|
You set the color here. Set the Parameter as {Greeb,Red,Blue}. When LinuxCNC sends the state = 1, the LED will be set to the specified color. State = 0 will shut the LED to the specified off color.
|
||||||
|
This allows you to either turn the LED On at any specified color or to flip color to show Status change. (Red and Green for example)
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define DLED
|
||||||
|
#ifdef DLED
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
|
||||||
|
const int DLEDcount = 8; //How Many DLED LED's are you going to connect?
|
||||||
|
const int DLEDPin = 4;
|
||||||
|
|
||||||
|
|
||||||
|
int DledOnColors[DLEDcount][3] = {
|
||||||
|
{255,0,0},
|
||||||
|
{0,0,255},
|
||||||
|
{0,255,0},
|
||||||
|
{0,255,0},
|
||||||
|
{0,255,0},
|
||||||
|
{0,255,0},
|
||||||
|
{0,255,0},
|
||||||
|
{0,255,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int DledOffColors[DLEDcount][3] = {
|
||||||
|
{0,0,0},
|
||||||
|
{0,255,0},
|
||||||
|
{255,0,0},
|
||||||
|
{255,0,0},
|
||||||
|
{255,0,0},
|
||||||
|
{0,0,255},
|
||||||
|
{0,0,255},
|
||||||
|
{0,0,255}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Adafruit_NeoPixel strip(DLEDcount, DLEDPin, NEO_GRB + NEO_KHZ800);//Color sequence is different for LED Chipsets. Use RGB for WS2812 or GRB for PL9823.
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//###Misc Settings###
|
//###Misc Settings###
|
||||||
const int timeout = 10000; // timeout after 10 sec not receiving Stuff
|
const int timeout = 10000; // timeout after 10 sec not receiving Stuff
|
||||||
|
|
||||||
@ -187,6 +235,9 @@ void setup() {
|
|||||||
pinMode(AbsEncPins[4], INPUT_PULLUP);
|
pinMode(AbsEncPins[4], INPUT_PULLUP);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DLED
|
||||||
|
initDLED();
|
||||||
|
#endif
|
||||||
|
|
||||||
//Setup Serial
|
//Setup Serial
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
@ -222,31 +273,23 @@ void loop() {
|
|||||||
readAbsKnob(); //read ABS Encoder & send data
|
readAbsKnob(); //read ABS Encoder & send data
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void comalive(){
|
void comalive(){
|
||||||
|
#ifdef STATUSLED
|
||||||
if(millis() - lastcom > timeout){
|
if(millis() - lastcom > timeout){
|
||||||
StatLedErr(1000,10);
|
StatLedErr(1000,10);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
digitalWrite(StatLedPin, HIGH);
|
if(DLEDSTATUSLED){controlDLED(StatLedPin, 1);}
|
||||||
|
else{digitalWrite(StatLedPin, HIGH);}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatLedErr(int offtime, int ontime){
|
|
||||||
unsigned long newMillis = millis();
|
|
||||||
|
|
||||||
if (newMillis - oldmillis >= offtime){
|
|
||||||
|
|
||||||
digitalWrite(StatLedPin, HIGH);
|
|
||||||
}
|
|
||||||
if (newMillis - oldmillis >= offtime+ontime){{
|
|
||||||
digitalWrite(StatLedPin, LOW);
|
|
||||||
oldmillis = newMillis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendData(char sig, int pin, int state){
|
void sendData(char sig, int pin, int state){
|
||||||
Serial.print(sig);
|
Serial.print(sig);
|
||||||
@ -261,16 +304,78 @@ void flushSerial(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STATUSLED
|
||||||
|
void StatLedErr(int offtime, int ontime){
|
||||||
|
unsigned long newMillis = millis();
|
||||||
|
|
||||||
|
if (newMillis - oldmillis >= offtime){
|
||||||
|
|
||||||
|
if(DLEDSTATUSLED){controlDLED(StatLedPin, 1);}
|
||||||
|
else{digitalWrite(StatLedPin, HIGH);}
|
||||||
|
}
|
||||||
|
if (newMillis - oldmillis >= offtime+ontime){{
|
||||||
|
if(DLEDSTATUSLED){controlDLED(StatLedPin, 0);}
|
||||||
|
else{digitalWrite(StatLedPin, LOW);}
|
||||||
|
oldmillis = newMillis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OUTPUTS
|
||||||
void writeOutputs(int Pin, int Stat){
|
void writeOutputs(int Pin, int Stat){
|
||||||
digitalWrite(Pin, Stat);
|
digitalWrite(Pin, Stat);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PWMOUTPUTS
|
||||||
void writePwmOutputs(int Pin, int Stat){
|
void writePwmOutputs(int Pin, int Stat){
|
||||||
analogWrite(Pin, Stat);
|
analogWrite(Pin, Stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DLED
|
||||||
|
void initDLED(){
|
||||||
|
strip.begin();
|
||||||
|
strip.setBrightness(50);
|
||||||
|
|
||||||
|
for (int i = 0; i < DLEDcount; i++) {
|
||||||
|
strip.setPixelColor(i, strip.Color(DledOffColors[i][0],DledOffColors[i][1],DledOffColors[i][2]));
|
||||||
|
}
|
||||||
|
strip.show();
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("DLED initialised");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void controlDLED(int Pin, int Stat){
|
||||||
|
if(Stat == 1){
|
||||||
|
strip.setPixelColor(Pin, strip.Color(DledOnColors[Pin][0],DledOnColors[Pin][1],DledOnColors[Pin][2]));
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("DLED No.");
|
||||||
|
Serial.print(Pin);
|
||||||
|
Serial.print(" set to:");
|
||||||
|
Serial.println(Stat);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else{strip.setPixelColor(Pin, strip.Color(DledOffColors[Pin][0],DledOffColors[Pin][1],DledOffColors[Pin][2]));
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("DLED No.");
|
||||||
|
Serial.print(Pin);
|
||||||
|
Serial.print(" set to:");
|
||||||
|
Serial.println(Stat);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
strip.show();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LPOTI
|
||||||
int readLPoti(){
|
int readLPoti(){
|
||||||
for(int i= 0;i<LPotis; i++){
|
for(int i= 0;i<LPotis; i++){
|
||||||
int var = analogRead(LPotiPins[i][0])+margin;
|
int var = analogRead(LPotiPins[i][0])+margin;
|
||||||
@ -284,8 +389,10 @@ int readLPoti(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AINPUTS
|
||||||
int readAInputs(){
|
int readAInputs(){
|
||||||
unsigned long var = 0;
|
unsigned long var = 0;
|
||||||
for(int i= 0;i<AInputs; i++){
|
for(int i= 0;i<AInputs; i++){
|
||||||
@ -300,7 +407,8 @@ int readAInputs(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef INPUTS
|
||||||
void readInputs(){
|
void readInputs(){
|
||||||
for(int i= 0;i<Inputs; i++){
|
for(int i= 0;i<Inputs; i++){
|
||||||
int State = digitalRead(InPinmap[i]);
|
int State = digitalRead(InPinmap[i]);
|
||||||
@ -310,8 +418,9 @@ void readInputs(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ABSENCODER
|
||||||
int readAbsKnob(){
|
int readAbsKnob(){
|
||||||
int var = 0;
|
int var = 0;
|
||||||
if(digitalRead(AbsEncPins[0])==1){
|
if(digitalRead(AbsEncPins[0])==1){
|
||||||
@ -336,30 +445,39 @@ int readAbsKnob(){
|
|||||||
oldAbsEncState = var;
|
oldAbsEncState = var;
|
||||||
return (var);
|
return (var);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void commandReceived(char cmd, uint16_t io, uint16_t value){
|
void commandReceived(char cmd, uint16_t io, uint16_t value){
|
||||||
|
#ifdef OUTPUTS
|
||||||
if(cmd == 'O'){
|
if(cmd == 'O'){
|
||||||
writeOutputs(io,value);
|
writeOutputs(io,value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef PWMOUTPUTS
|
||||||
if(cmd == 'P'){
|
if(cmd == 'P'){
|
||||||
writePwmOutputs(io,value);
|
writePwmOutputs(io,value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(cmd == 'E'){
|
if(cmd == 'E'){
|
||||||
lastcom=millis();
|
lastcom=millis();
|
||||||
}
|
}
|
||||||
|
#ifdef DLED
|
||||||
|
if(cmd == 'D'){
|
||||||
|
controlDLED(io,value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Serial.print("I Received= ");
|
Serial.print("I Received= ");
|
||||||
Serial.print(cmd);
|
Serial.print(cmd);
|
||||||
Serial.print(io);
|
Serial.print(io);
|
||||||
Serial.print(":");
|
Serial.print(":");
|
||||||
Serial.println(value);
|
Serial.println(value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int isCmdChar(char cmd){
|
int isCmdChar(char cmd){
|
||||||
if(cmd == 'O'||cmd == 'P'||cmd == 'E') {return true;}
|
if(cmd == 'O'||cmd == 'P'||cmd == 'E'||cmd == 'L') {return true;}
|
||||||
else{return false;}
|
else{return false;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# LinuxCNC_ArduinoConnector
|
# LinuxCNC_ArduinoConnector
|
||||||
By Alexander Richter, info@theartoftinkering.com 2022
|
By Alexander Richter, info@theartoftinkering.com 2022
|
||||||
|
please consider supporting me on Patreon: https://www.patreon.com/theartoftinkering
|
||||||
|
|
||||||
For my CNC Machine i wanted to include more IO's than my Mesa card was offering. This Projekt enables to connect Arduino to LinuxCNC to include as many IO's as you wish.
|
For my CNC Machine i wanted to include more IO's than my Mesa card was offering. This Projekt enables to connect Arduino to LinuxCNC to include as many IO's as you wish.
|
||||||
|
|
||||||
|
17
arduino.py
17
arduino.py
@ -24,6 +24,7 @@ import serial, time, hal
|
|||||||
# 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
|
||||||
|
# Digital LED Outputs = 'D' -read only -Pin State: 0,1
|
||||||
# Analog Inputs = 'A' -write only -Pin State: 0-1024
|
# Analog Inputs = 'A' -write only -Pin State: 0-1024
|
||||||
# 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
|
||||||
@ -74,6 +75,8 @@ LPotiLatches = [[2,9],
|
|||||||
AbsKnob = 1
|
AbsKnob = 1
|
||||||
AbsKnobPos = 32
|
AbsKnobPos = 32
|
||||||
|
|
||||||
|
# Set how many Digital LED's you have connected.
|
||||||
|
DLEDcount = 8
|
||||||
|
|
||||||
|
|
||||||
Debug = 1
|
Debug = 1
|
||||||
@ -86,7 +89,7 @@ oldPwmOutStates=[0]*PwmOutputs
|
|||||||
# setup Input halpins
|
# setup Input halpins
|
||||||
for port in range(Inputs):
|
for port in range(Inputs):
|
||||||
c.newpin("dIn.{}".format(InPinmap[port]), hal.HAL_BIT, hal.HAL_OUT)
|
c.newpin("dIn.{}".format(InPinmap[port]), hal.HAL_BIT, hal.HAL_OUT)
|
||||||
c.newparam("dIn.{}-invert".format(InPinmap[port]), hal.HAL_BIT, hal.HAL_RW)
|
c.newparam("dIn.{}-invert".format(InPinmap[port]), hal.HAL_BIT, hal.HAL_OUT)
|
||||||
|
|
||||||
# setup Output halpins
|
# setup Output halpins
|
||||||
for port in range(Outputs):
|
for port in range(Outputs):
|
||||||
@ -111,6 +114,11 @@ if AbsKnob:
|
|||||||
for port in range(AbsKnobPos):
|
for port in range(AbsKnobPos):
|
||||||
c.newpin("AbsKnob.{}".format(port), hal.HAL_BIT, hal.HAL_OUT)
|
c.newpin("AbsKnob.{}".format(port), hal.HAL_BIT, hal.HAL_OUT)
|
||||||
|
|
||||||
|
# setup Digital LED halpins
|
||||||
|
if DLEDcount > 0:
|
||||||
|
for port in range(DLEDcount):
|
||||||
|
c.newpin("DLED.{}".format(port), hal.HAL_BIT, hal.HAL_IN)
|
||||||
|
|
||||||
c.ready()
|
c.ready()
|
||||||
|
|
||||||
#setup Serial connection
|
#setup Serial connection
|
||||||
@ -165,6 +173,13 @@ def managageOutputs():
|
|||||||
if (Debug):print ("Sending:{}".format(command.encode()))
|
if (Debug):print ("Sending:{}".format(command.encode()))
|
||||||
olddOutStates[port]= State
|
olddOutStates[port]= State
|
||||||
|
|
||||||
|
for port in range(DLEDcount):
|
||||||
|
State = int(c["DLED.{}".format(port)])
|
||||||
|
Sig = 'D'
|
||||||
|
Pin = int(port)
|
||||||
|
command = "{}{}:{}\n".format(Sig,Pin,State)
|
||||||
|
arduino.write(command.encode())
|
||||||
|
if (Debug):print ("Sending:{}".format(command.encode()))
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
Loading…
Reference in New Issue
Block a user