Hallo zusammen,
mein Name ist Andreas, ich bin 44 Jahre alt, relativ neu in dem Thema Arduino und C++ und dies ist mein erster Beitrag in diesem Forum.
Ich habe ein Projekt realisiert, in welchem diverse Buttons, Head Switches und Encoder mithilfe eines Arduino Pro Micro und zweier Adafruit MCP23017 ausgelesen und dann via Joystick Bibliothek als Gamecontroller an den PC ausgegeben werden.
Anfangs habe ich mich mit Copy & Paste und ChatGPT durchgehangelt und nach und nach auch so ziemlich alles verstanden, was der Sketch so macht, so konnte ich noch einiges optimieren, allerdings bin ich jetzt bei einer Kleinigkeit an meine Grenzen gestossen und auch die Suche im Netz und hier im Forum bringt mich leider nicht weiter, also frage ich hier mal ganz dumm:
Ich habe in meinem Projekt zwei Alps-Alpine RKJXT1F42001 und zwei billige China Encoder, welche dem KY-040 entsprechen, verwendet. Der RKJXT1F42001 ist ein 7-Wege Multi-Switch, der vier Richtungen, eine Push-Funktion, sowie einen Drehencoder vereint. Mein Problem ist nun, dass wenn ich den Sketch im Half-Step-Modus laufen lasse, zwar die Encoder der RKJXT1F42001 einwandfrei funktionieren, die zwei KY-040 jedoch bei einer Rastung zwei mal auslösen. Kommentiere ich den Half-Step-Modus aus, dann funktionieren die zwei KY-040 einwandfrei, aber die Encoder der RKJXT1F42001 lösen nur bei jeder zweiten Rastung aus.
Die RKJXT1F42001 sind jeweils an den Pins 0 & 1 der MCP23017 angeschlossen, die KY-040 an den Pins 2 & 3.
Gibt es die Möglichkeit, den Sketch so umzuschreiben, dass jeder Encoder in seinem eigenen Step-Modus ausgelesen wird?
Ich habe mal alles andere aus dem Sketch gelöscht und nur die vier Encoder drin gelassen:
#include <Wire.h>
#include <Joystick.h>
#include <Adafruit_MCP23X17.h>
// Konfiguration der Portexpander
Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
// Konfiguration der Rotary Encoder
//#define HALF_STEP
#define NUMROTARIES 4
struct rotariesdef {
byte pin1;
byte pin2;
int ccwchar;
int cwchar;
volatile unsigned char state;
};
rotariesdef rotaries[NUMROTARIES] {
{0, 1, 17, 18, 0},
{2, 3, 21, 22, 0},
{0, 1, 19, 20, 0},
{2, 3, 23, 24, 0},
};
#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0
#ifdef HALF_STEP
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
// R_START (00)
{R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START},
// R_CCW_BEGIN
{R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START},
// R_CW_BEGIN
{R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START},
// R_START_M (11)
{R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START},
// R_CW_BEGIN_M
{R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW},
// R_CCW_BEGIN_M
{R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW},
};
#else
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6
const unsigned char ttable[7][4] = {
// R_START
{R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START},
// R_CW_FINAL
{R_CW_NEXT, R_START, R_CW_FINAL, R_START | DIR_CW},
// R_CW_BEGIN
{R_CW_NEXT, R_CW_BEGIN, R_START, R_START},
// R_CW_NEXT
{R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START},
// R_CCW_BEGIN
{R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START},
// R_CCW_FINAL
{R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | DIR_CCW},
// R_CCW_NEXT
{R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif
// Konfiguration des Joysticks
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, 25, 2,
false, false, false, false, false, false,
false, false, false, false, false);
void setup() {
Serial.begin(115200);
// Initialisierung der Joystick Bibliothek
Joystick.begin();
// Initialisierung des I2C Bus
Wire.begin();
// Initialisierung der beiden Port Expander
mcp1.begin_I2C(0x20);
mcp2.begin_I2C(0x21);
// Setzen der Bus-Geschwindigkeit
Wire.setClock(400000);
// Konfiguration der Pins des ersten Port Expanders als Inputs
mcp1.pinMode(0, INPUT_PULLUP);
mcp1.pinMode(1, INPUT_PULLUP);
mcp1.pinMode(2, INPUT_PULLUP);
mcp1.pinMode(3, INPUT_PULLUP);
// Konfiguration der Pins des zweiten Port Expanders als Inputs
mcp2.pinMode(0, INPUT_PULLUP);
mcp2.pinMode(1, INPUT_PULLUP);
mcp2.pinMode(2, INPUT_PULLUP);
mcp2.pinMode(3, INPUT_PULLUP);
}
void loop() {
CheckAllEncoders();
}
// Abfrage der Zustände der Rotary Encoder und Übergabe an den Joystick
unsigned char rotary_process(int _i) {
unsigned char pinstate = (mcp1.digitalRead(rotaries[_i].pin2) << 1) | mcp1.digitalRead(rotaries[_i].pin1);
rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
return (rotaries[_i].state & 0x30);
}
unsigned char rotary_process2(int _j) {
unsigned char pinstate = (mcp2.digitalRead(rotaries[_j].pin2) << 1) | mcp2.digitalRead(rotaries[_j].pin1);
rotaries[_j].state = ttable[rotaries[_j].state & 0xf][pinstate];
return (rotaries[_j].state & 0x30);
}
void CheckAllEncoders(void) {
for (int i = 0; i < 2; i++) {
unsigned char result = rotary_process(i);
if (result == DIR_CCW) {
Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
};
if (result == DIR_CW) {
Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
};
}
for (int i = 2; i < 4; i++) {
unsigned char result = rotary_process2(i);
if (result == DIR_CCW) {
Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
};
if (result == DIR_CW) {
Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
};
}
}
LG
Andreas