OLED experiment

This commit is contained in:
Ton 2024-03-06 11:26:32 +01:00
parent 9a88317df6
commit 8e47bf6f53

View File

@ -16,7 +16,6 @@
- digital Inputs - digital Inputs
- digital Outputs - digital Outputs
- Matrix Keypad - Matrix Keypad
- Multiplexed LEDs
- Quadrature encoders - Quadrature encoders
- Joysticks - Joysticks
@ -33,10 +32,9 @@
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: 0,1 Matrix Keypad = 'M' -write only -Pin State: Number of Matrix Key.
Communication Status = 'E' -read/Write -Pin State: 0:0 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 <Wire.h>
#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################################################### //###################################################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 = 8; //number of inputs using internal Pullup resistor. (short to ground to trigger)
int InPinmap[] = { 21, 22 }; int InPinmap[] = { 25, 26, 27, 17, 23, 19, 18, 5 };
#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.
@ -79,16 +89,16 @@ const int sInputs = 1; //number of inputs using internal Pullup resistor. (shor
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 = 4; //number of outputs
int OutPinmap[] = { 11, 12 }; int OutPinmap[] = { 32, 33, 34, 35 };
#endif #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. //#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 #ifdef PWMOUTPUTS
const int PwmOutputs = 2; //number of outputs const int PwmOutputs = 2; //number of outputs
int PwmOutPinmap[] = { 12, 11 }; int PwmOutPinmap[] = { 10, 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.
@ -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. 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[] = { 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 #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 const float scalingFactor = 0.01; // Scaling factor to control the impact of distanceFromMiddle
#endif #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. //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 // Slow Flash = Not Connected
// Steady on = connected // Steady on = connected
@ -197,14 +202,11 @@ const float scalingFactor = 0.01; // Scaling factor to control
#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 = 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 #endif
/* Instead of connecting LED's to Output pins, you can also connect digital LED's such as WS2812 or PL9823. /* 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. 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". 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}, . 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. 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 <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
const int DLEDcount = 8; //How Many DLED LED's are you going to connect? 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% const int DLEDBrightness = 70; //Brightness of the LED's 0-100%
int DledOnColors[DLEDcount][3] = { int DledOnColors[DLEDcount][3] = {
@ -246,12 +248,12 @@ int DledOnColors[DLEDcount][3] = {
int DledOffColors[DLEDcount][3] = { int DledOffColors[DLEDcount][3] = {
{ 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 },
{ 255, 0, 0 }, { 0, 0, 0 },
{ 255, 0, 0 }, { 0, 0, 0 },
{ 255, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 255 }, { 0, 0, 0 },
{ 0, 0, 255 }, { 0, 0, 0 },
{ 0, 0, 255 } { 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 // 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
//####################################### END OF CONFIG ########################### //####################################### END OF CONFIG ###########################
//###Misc Settings### //###Misc Settings###
@ -334,7 +309,6 @@ int oldOutPWMState[PwmOutputs];
#endif #endif
#ifdef AINPUTS #ifdef AINPUTS
int oldAinput[AInputs]; int oldAinput[AInputs];
unsigned long sumAinput[AInputs];
#endif #endif
#ifdef LPOTIS #ifdef LPOTIS
int Lpoti[LPotis]; int Lpoti[LPotis];
@ -346,9 +320,6 @@ int oldAbsEncState;
#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
@ -399,6 +370,26 @@ uint16_t value = 0;
void setup() { 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 #ifdef INPUTS
//setting Inputs with internal Pullup Resistors //setting Inputs with internal Pullup Resistors
for (int i = 0; i < Inputs; i++) { for (int i = 0; i < Inputs; i++) {
@ -421,7 +412,6 @@ void setup() {
for (int i = 0; i < AInputs; i++) { for (int i = 0; i < AInputs; i++) {
pinMode(AInPinmap[i], INPUT); pinMode(AInPinmap[i], INPUT);
oldAinput[i] = -1; oldAinput[i] = -1;
sumAinput[i] = 0;
} }
#endif #endif
#ifdef OUTPUTS #ifdef OUTPUTS
@ -498,15 +488,12 @@ 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() {
@ -597,13 +584,24 @@ void readEncoders() {
#endif #endif
void Debug_(String inStr, byte newLine = 1) {
if (newLine) {
Serial.println(inStr);
} else {
Serial.print(inStr);
}
}
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) {
readCommands(); readCommands();
flushSerial(); flushSerial();
Serial.println("E0:0"); //Serial.println("E0:0");
delay(200); //delay(200);
#ifdef STATUSLED #ifdef STATUSLED
StatLedErr(1000, 1000); StatLedErr(1000, 1000);
#endif #endif
@ -611,7 +609,7 @@ void comalive() {
connectionState = 1; connectionState = 1;
flushSerial(); flushSerial();
#ifdef DEBUG #ifdef DEBUG
Serial.println("first connect"); Debug_("first connect");
#endif #endif
} }
if (millis() - lastcom > timeout) { if (millis() - lastcom > timeout) {
@ -620,7 +618,7 @@ void comalive() {
#endif #endif
if (connectionState == 1) { if (connectionState == 1) {
#ifdef DEBUG #ifdef DEBUG
Serial.println("disconnected"); Debug_("disconnected");
#endif #endif
connectionState = 2; connectionState = 2;
} }
@ -635,17 +633,18 @@ void comalive() {
} else { } else {
digitalWrite(StatLedPin, HIGH); digitalWrite(StatLedPin, HIGH);
} }
#endif
} }
#endif
} }
void reconnect() { void reconnect() {
#ifdef DEBUG #ifdef DEBUG
Serial.println("reconnected"); Debug_("reconnected");
#endif #endif
#ifdef DEBUG #ifdef DEBUG
Serial.println("resending Data"); Debug_("resending Data");
#endif #endif
#ifdef INPUTS #ifdef INPUTS
@ -662,7 +661,6 @@ void reconnect() {
#ifdef AINPUTS #ifdef AINPUTS
for (int x = 0; x < AInputs; x++) { for (int x = 0; x < AInputs; x++) {
oldAinput[x] = -1; oldAinput[x] = -1;
sumAinput[x] = 0;
} }
#endif #endif
#ifdef LPOTIS #ifdef LPOTIS
@ -690,9 +688,7 @@ 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;
} }
@ -702,7 +698,15 @@ void sendData(char sig, int pin, int state) {
Serial.print(sig); Serial.print(sig);
Serial.print(pin); Serial.print(pin);
Serial.print(":"); 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() { void flushSerial() {
@ -769,21 +773,21 @@ void controlDLED(int Pin, int Stat) {
if (Stat == 1) { if (Stat == 1) {
strip.setPixelColor(Pin, strip.Color(DledOnColors[Pin][0], DledOnColors[Pin][1], DledOnColors[Pin][2])); strip.setPixelColor(Pin, strip.Color(DledOnColors[Pin][0], DledOnColors[Pin][1], DledOnColors[Pin][2]));
#ifdef DEBUG #ifdef DEBUGDLED
Serial.print("DLED No."); Debug_("DLED No.", 0);
Serial.print(Pin); Debug_(F(Pin), 0);
Serial.print(" set to:"); Debug_(" set to:", 0);
Serial.println(Stat); Debug_(F(Stat));
#endif #endif
} else { } else {
strip.setPixelColor(Pin, strip.Color(DledOffColors[Pin][0], DledOffColors[Pin][1], DledOffColors[Pin][2])); strip.setPixelColor(Pin, strip.Color(DledOffColors[Pin][0], DledOffColors[Pin][1], DledOffColors[Pin][2]));
#ifdef DEBUG #ifdef DEBUGDLED
Serial.print("DLED No."); Debug_("DLED No.", 0);
Serial.print(Pin); Debug_(F(Pin), 0);
Serial.print(" set to:"); Debug_(" set to:", 0);
Serial.println(Stat); Debug_(F(Stat));
#endif #endif
} }
@ -792,7 +796,7 @@ void controlDLED(int Pin, int Stat) {
#endif #endif
#ifdef LPOTIS #ifdef LPOTIS
void 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;
int pos = 1024 / (LPotiPins[i][1] - 1); int pos = 1024 / (LPotiPins[i][1] - 1);
@ -807,30 +811,22 @@ void readLPoti() {
#ifdef AINPUTS #ifdef AINPUTS
void readAInputs() { int readAInputs() {
static unsigned int samplecount = 0;
for (int i = 0; i < AInputs; i++) { for (int i = 0; i < AInputs; i++) {
unsigned long var = 0;
if (samplecount < smooth) { for (int d = 0; d < smooth; d++) { // take couple samples to denoise signal
sumAinput[i] = sumAinput[i] + analogRead(AInPinmap[i]); var = var + analogRead(AInPinmap[i]);
} else { }
sumAinput[i] = sumAinput[i] / smooth; var = var / smooth;
if (oldAinput[i] != sumAinput[i]) { if (oldAinput[i] != var) {
oldAinput[i] = sumAinput[i]; oldAinput[i] = var;
sendData('A', AInPinmap[i], oldAinput[i]); sendData('A', AInPinmap[i], oldAinput[i]);
} }
sumAinput[i] = 0;
}
}
if (samplecount < smooth) {
samplecount = samplecount + 1;
} else {
samplecount = 0;
} }
} }
#endif #endif
#ifdef INPUTS #ifdef INPUTS
void readInputs() { void readInputs() {
for (int i = 0; i < Inputs; i++) { for (int i = 0; i < Inputs; i++) {
@ -887,8 +883,8 @@ int readAbsKnob() {
var += 16; var += 16;
} }
if (var != oldAbsEncState) { if (var != oldAbsEncState) {
Serial.print("K0:"); Debug_("K0:", 0);
Serial.println(var); Debug_(F(var));
} }
oldAbsEncState = var; oldAbsEncState = var;
return (var); return (var);
@ -924,53 +920,6 @@ void readKeypad() {
} }
#endif #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) { void commandReceived(char cmd, uint16_t io, uint16_t value) {
#ifdef OUTPUTS #ifdef OUTPUTS
if (cmd == 'O') { if (cmd == 'O') {
@ -989,27 +938,13 @@ void commandReceived(char cmd, uint16_t io, uint16_t value) {
controlDLED(io, value); controlDLED(io, value);
lastcom = millis(); lastcom = millis();
#ifdef debug #ifdef debug
Serial.print("DLED:"); Serial.print("DLED:", 0);
Serial.print(io); Serial.print(F(io), 0);
Serial.print(" State:"); Serial.print(" State:", 0);
Serial.println(DLEDstate[io]); Debug_(F(DLEDstate[io]));
#endif #endif
} }
#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) {
@ -1019,11 +954,11 @@ void commandReceived(char cmd, uint16_t io, uint16_t value) {
#ifdef DEBUG #ifdef DEBUG
Serial.print("I Received= "); Debug_("I Received= ", 0);
Serial.print(cmd); Debug_(F(cmd), 0);
Serial.print(io); Debug_(F(io), 0);
Serial.print(":"); Debug_(":", 0);
Serial.println(value); Debug_(F(value));
#endif #endif
} }
@ -1050,7 +985,7 @@ void readCommands() {
} else { } else {
#ifdef DEBUG #ifdef DEBUG
Serial.print("Ungültiges zeichen: "); Serial.print("Ungültiges zeichen: ");
Serial.println(current); Debug_(F(current));
#endif #endif
} }
break; break;
@ -1064,8 +999,8 @@ void readCommands() {
state = STATE_CMD; state = STATE_CMD;
} else { } else {
#ifdef DEBUG #ifdef DEBUG
Serial.print("Ungültiges zeichen: "); Debug_("Ungültiges zeichen: ", 0);
Serial.println(current); Debug_(F(current));
#endif #endif
} }
break; break;