diff --git a/LinuxCNC_ArduinoConnector.ino b/LinuxCNC_ArduinoConnector.ino index 727d459..b97b131 100644 --- a/LinuxCNC_ArduinoConnector.ino +++ b/LinuxCNC_ArduinoConnector.ino @@ -16,7 +16,6 @@ - digital Inputs - digital Outputs - Matrix Keypad - - Multiplexed LEDs - Quadrature encoders - Joysticks @@ -33,10 +32,9 @@ binary encoded Selector = 'K' -write only -Pin State: 0-32 rotary encoder = '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: - Matrix Keypad = 'M' -write only -Pin State: 0,1 + Matrix Keypad = 'M' -write only -Pin State: Number of Matrix Key. Communication Status = 'E' -read/Write -Pin State: 0:0 @@ -61,15 +59,27 @@ Communication Status = 'E' -read/Write -Pin State: 0:0 */ +#define DEBUG +//#define OLED +#ifdef OLED +#include +#include "SSD1306Ascii.h" +#include "SSD1306AsciiWire.h" +// 0X3C+SA0 - 0x3C or 0x3D +#define I2C_ADDRESS 0x3C +// Define proper RST_PIN if required. +#define RST_PIN -1 +SSD1306AsciiWire oled; +#endif //###################################################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. #ifdef INPUTS -const int Inputs = 2; //number of inputs using internal Pullup resistor. (short to ground to trigger) -int InPinmap[] = { 21, 22 }; +const int Inputs = 8; //number of inputs using internal Pullup resistor. (short to ground to trigger) +int InPinmap[] = { 25, 26, 27, 17, 23, 19, 18, 5 }; #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. @@ -79,16 +89,16 @@ const int sInputs = 1; //number of inputs using internal Pullup resistor. (shor int sInPinmap[] = { 10 }; #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 -const int Outputs = 2; //number of outputs -int OutPinmap[] = { 11, 12 }; +const int Outputs = 4; //number of outputs +int OutPinmap[] = { 32, 33, 34, 35 }; #endif //#define PWMOUTPUTS //Use Arduino PWM Capable IO's as PWM Outputs. Define how many PWM Outputs you want in total and then which Pins you want to be PWM Outputs. #ifdef PWMOUTPUTS const int PwmOutputs = 2; //number of outputs -int PwmOutPinmap[] = { 12, 11 }; +int PwmOutPinmap[] = { 10, 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. @@ -168,7 +178,7 @@ Encoder Encoder1(31, 33); //A,B Pin 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) //2= send position signal (typical use for MPG wheel) -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? +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? #endif @@ -181,11 +191,6 @@ const int deadband = 20; // Deadband range around the const float scalingFactor = 0.01; // Scaling factor to control the impact of distanceFromMiddle #endif - - - - - //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 // Steady on = connected @@ -197,14 +202,11 @@ const float scalingFactor = 0.01; // Scaling factor to control #define 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 DLEDSTATUSLED = 0; //set to 1 to use Digital LED instead. set StatLedPin to the according LED number in the chain. +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 WS2812 or PL9823. This way you can have how many LED's you want and also define it's color with just one Pin. @@ -219,7 +221,7 @@ depending on the Chipset of your LED's Colors might be in a different order. You You need to define a color to DledOffColors too. Like the Name suggests it defines the color of each LED when turned "off". If you want the LED to be off just define {0,0,0}, . - +cccccc If you use STATUSLED, it will also take the colors of your definition here. */ @@ -229,7 +231,7 @@ If you use STATUSLED, it will also take the colors of your definition here. #include const int DLEDcount = 8; //How Many DLED LED's are you going to connect? -const int DLEDPin = 4; //Where is DI connected to? +const int DLEDPin = 14; //Where is DI connected to? const int DLEDBrightness = 70; //Brightness of the LED's 0-100% int DledOnColors[DLEDcount][3] = { @@ -246,12 +248,12 @@ int DledOnColors[DLEDcount][3] = { int DledOffColors[DLEDcount][3] = { { 0, 0, 0 }, { 0, 0, 0 }, - { 255, 0, 0 }, - { 255, 0, 0 }, - { 255, 0, 0 }, - { 0, 0, 255 }, - { 0, 0, 255 }, - { 0, 0, 255 } + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 } }; @@ -271,40 +273,13 @@ 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] = { 0 }; + int lastKey = -1; #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 //####################################### END OF CONFIG ########################### //###Misc Settings### @@ -334,7 +309,6 @@ int oldOutPWMState[PwmOutputs]; #endif #ifdef AINPUTS int oldAinput[AInputs]; -unsigned long sumAinput[AInputs]; #endif #ifdef LPOTIS int Lpoti[LPotis]; @@ -346,9 +320,6 @@ int oldAbsEncState; #ifdef KEYPAD byte KeyState = 0; #endif -#ifdef MULTIPLEXLEDS -byte KeyLedStates[numVccPins * numGndPins]; -#endif #if QUADENCS == 1 const int QuadEncs = 1; #endif @@ -399,6 +370,26 @@ uint16_t value = 0; void setup() { +#ifdef OLED + Wire.begin(); + //Wire.setClock(400000L); + +#if RST_PIN >= 0 + oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); +#else // RST_PIN >= 0 + oled.begin(&Adafruit128x64, I2C_ADDRESS); +#endif // RST_PIN >= 0 + + oled.setFont(System5x7); + +#if INCLUDE_SCROLLING == 0 +#error INCLUDE_SCROLLING must be non-zero. Edit SSD1306Ascii.h +#endif // INCLUDE_SCROLLING + // Set auto scrolling at end of window. + oled.setScrollMode(SCROLL_MODE_AUTO); + +#endif + #ifdef INPUTS //setting Inputs with internal Pullup Resistors for (int i = 0; i < Inputs; i++) { @@ -421,7 +412,6 @@ void setup() { for (int i = 0; i < AInputs; i++) { pinMode(AInPinmap[i], INPUT); oldAinput[i] = -1; - sumAinput[i] = 0; } #endif #ifdef OUTPUTS @@ -498,15 +488,12 @@ void loop() { #ifdef QUADENC readEncoders(); //read Encoders & send data #endif - #ifdef JOYSTICK readJoySticks(); //read Encoders & send data #endif -#ifdef MULTIPLEXLEDS - multiplexLeds(); // cycle through the 2D LED Matrix} -#endif } + #ifdef JOYSTICK void readJoySticks() { @@ -597,13 +584,24 @@ void readEncoders() { #endif +void Debug_(String inStr, byte newLine = 1) { + if (newLine) { + Serial.println(inStr); + } else { + Serial.print(inStr); + } +} + + +void initialiseIO() { +} void comalive() { if (lastcom == 0) { //no connection yet. send E0:0 periodicly and wait for response while (lastcom == 0) { readCommands(); flushSerial(); - Serial.println("E0:0"); - delay(200); + //Serial.println("E0:0"); + //delay(200); #ifdef STATUSLED StatLedErr(1000, 1000); #endif @@ -611,7 +609,7 @@ void comalive() { connectionState = 1; flushSerial(); #ifdef DEBUG - Serial.println("first connect"); + Debug_("first connect"); #endif } if (millis() - lastcom > timeout) { @@ -620,7 +618,7 @@ void comalive() { #endif if (connectionState == 1) { #ifdef DEBUG - Serial.println("disconnected"); + Debug_("disconnected"); #endif connectionState = 2; } @@ -635,17 +633,18 @@ void comalive() { } else { digitalWrite(StatLedPin, HIGH); } -#endif } + +#endif } void reconnect() { #ifdef DEBUG - Serial.println("reconnected"); + Debug_("reconnected"); #endif #ifdef DEBUG - Serial.println("resending Data"); + Debug_("resending Data"); #endif #ifdef INPUTS @@ -662,7 +661,6 @@ void reconnect() { #ifdef AINPUTS for (int x = 0; x < AInputs; x++) { oldAinput[x] = -1; - sumAinput[x] = 0; } #endif #ifdef LPOTIS @@ -690,9 +688,7 @@ void reconnect() { #ifdef BINSEL readAbsKnob(); //read ABS Encoder & send data #endif -#ifdef MULTIPLEXLEDS - multiplexLeds(); //Flash LEDS. -#endif + connectionState = 1; } @@ -702,7 +698,15 @@ void sendData(char sig, int pin, int state) { Serial.print(sig); Serial.print(pin); Serial.print(":"); - Serial.println(state); + Serial.println(F(state)); + // Print to the screen +#ifdef OLED + oled.print("Line "); + oled.print(F(sig)); + oled.print(F(pin)); + oled.print(":"); + oled.println(F(state)); +#endif } void flushSerial() { @@ -769,21 +773,21 @@ 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); +#ifdef DEBUGDLED + Debug_("DLED No.", 0); + Debug_(F(Pin), 0); + Debug_(" set to:", 0); + Debug_(F(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); +#ifdef DEBUGDLED + Debug_("DLED No.", 0); + Debug_(F(Pin), 0); + Debug_(" set to:", 0); + Debug_(F(Stat)); #endif } @@ -792,7 +796,7 @@ void controlDLED(int Pin, int Stat) { #endif #ifdef LPOTIS -void readLPoti() { +int readLPoti() { for (int i = 0; i < LPotis; i++) { int var = analogRead(LPotiPins[i][0]) + margin; int pos = 1024 / (LPotiPins[i][1] - 1); @@ -807,30 +811,22 @@ void readLPoti() { #ifdef AINPUTS -void readAInputs() { - static unsigned int samplecount = 0; +int readAInputs() { for (int i = 0; i < AInputs; i++) { - - if (samplecount < smooth) { - sumAinput[i] = sumAinput[i] + analogRead(AInPinmap[i]); - } else { - sumAinput[i] = sumAinput[i] / smooth; - if (oldAinput[i] != sumAinput[i]) { - oldAinput[i] = sumAinput[i]; - sendData('A', AInPinmap[i], oldAinput[i]); - } - sumAinput[i] = 0; + unsigned long var = 0; + for (int d = 0; d < smooth; d++) { // take couple samples to denoise signal + var = var + analogRead(AInPinmap[i]); + } + var = var / smooth; + if (oldAinput[i] != var) { + oldAinput[i] = var; + sendData('A', AInPinmap[i], oldAinput[i]); } - } - - if (samplecount < smooth) { - samplecount = samplecount + 1; - } else { - samplecount = 0; } } #endif + #ifdef INPUTS void readInputs() { for (int i = 0; i < Inputs; i++) { @@ -887,8 +883,8 @@ int readAbsKnob() { var += 16; } if (var != oldAbsEncState) { - Serial.print("K0:"); - Serial.println(var); + Debug_("K0:", 0); + Debug_(F(var)); } oldAbsEncState = var; return (var); @@ -924,53 +920,6 @@ void readKeypad() { } #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 - void commandReceived(char cmd, uint16_t io, uint16_t value) { #ifdef OUTPUTS if (cmd == 'O') { @@ -989,27 +938,13 @@ void commandReceived(char cmd, uint16_t io, uint16_t value) { controlDLED(io, value); lastcom = millis(); #ifdef debug - Serial.print("DLED:"); - Serial.print(io); - Serial.print(" State:"); - Serial.println(DLEDstate[io]); + Serial.print("DLED:", 0); + Serial.print(F(io), 0); + Serial.print(" State:", 0); + Debug_(F(DLEDstate[io])); #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') { lastcom = millis(); if (connectionState == 2) { @@ -1019,11 +954,11 @@ void commandReceived(char cmd, uint16_t io, uint16_t value) { #ifdef DEBUG - Serial.print("I Received= "); - Serial.print(cmd); - Serial.print(io); - Serial.print(":"); - Serial.println(value); + Debug_("I Received= ", 0); + Debug_(F(cmd), 0); + Debug_(F(io), 0); + Debug_(":", 0); + Debug_(F(value)); #endif } @@ -1050,7 +985,7 @@ void readCommands() { } else { #ifdef DEBUG Serial.print("Ungültiges zeichen: "); - Serial.println(current); + Debug_(F(current)); #endif } break; @@ -1064,8 +999,8 @@ void readCommands() { state = STATE_CMD; } else { #ifdef DEBUG - Serial.print("Ungültiges zeichen: "); - Serial.println(current); + Debug_("Ungültiges zeichen: ", 0); + Debug_(F(current)); #endif } break;