Hallo Forengemeinde,
um es vorweg zu nehmen, ich bin Neu hier und auf dem Gebiet Arduino und Programmierung ein Neuling. Als kleines Winterprojekt habe mir in den Kopf gesetzt, eine BottonBox fürs SimRacing selber zu bauen. Die Box ist fertig, alle Schalter und Knöpfe platziert und verdrahtet, aber leider komme ich an einer Stelle nicht weiter obwohl ich inzwischen einige Videos zum Thema DIY-ButtonBox gesehen habe.
Die Box besteht aus:
7 Drucktaster
(1x Start/Stopp-Knopf als PushButton, 6x PushButtons zum verstellen von z.B. ABS, Traktionskontrolle o.ä.)
5 Kippschalter
(1x Zündung AN-AUS, 4x z.B. zum An- und Ausschalten von Scheibenwischer, Licht o.ä.)
Das Ganze habe ich als 4x4 Matrix aufgebaut, Matrix siehe Bilder. Ich verwende ein Arduino Micro Pro.
Die Kippschalter haben 2 Funktion – AN und AUS. Ebenso die Drucktaster. Welche Kippschalter und Drucktaster ich verwendet habe, siehe Bilder.
Nun mein Problem: Wenn ich die Kippschalter betätige, bspw. ich möchte mit Kippschalter 1 die Scheibenwischer und mit Kippschalter 2 das Licht AN-schalten, leuchten im Windows-Gamecontroller 2 der 12 Kontrolllampen. Das passt, siehe Abbildung 1. Sobald ich jetzt aber mittels PushButton bspw. ABS erhöhen möchte, leuchten 6 der 12 Kontrolllampen, obwohl nur 3 leuchten dürften. (1x Scheibenwischer, 1x Licht, 1x ABS erhöhen), siehe Abbildung 2.
Ich habe sowohl mit SimHub als auch mit dem beigefügten Quell-Code die Box versucht zum laufen zu bringen. Ich habe mich jedoch für den beigefügten Quell-Code entschieden, da er mir transparenter erscheint.
Ich hoffe mein Problem verständlich geschildert zu haben und wäre um jede Unterstützung dankbar. Vermutlich liegt es am Quell-Code, der vermutlich angepasst werden muss aber ich weiß leider nicht an welcher Stelle und wie.
#include <Joystick.h>
//BUTTON BOX
//USE w ProMicro
//Tested in WIN10 + Assetto Corsa
//AMSTUDIO
//20.8.17
#include <Keypad.h>
#include <Joystick.h>
#define ENABLE_PULLUPS
#define NUMROTARIES 24
#define NUMBUTTONS 12
#define NUMROWS 4
#define NUMCOLS 4
byte buttons[NUMROWS][NUMCOLS] = {
{0,1,2,3},
{4,5,6,7},
{8,9},
{10,11}
};
struct rotariesdef {
byte pin1;
byte pin2;
int ccwchar;
int cwchar;
volatile unsigned char state;
};
rotariesdef rotaries[NUMROTARIES] {
{0,1,24,25,0},
{2,3,26,27,0},
{4,5,28,29,0},
{6,7,30,31,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
byte rowPins[NUMROWS] = {18,19,20,21};
byte colPins[NUMCOLS] = {7,8,14,15};
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, 12, 0,
false, false, false, false, false, false,
false, false, false, false, false);
void setup() {
Joystick.begin();
rotary_init();}
void loop() {
CheckAllEncoders();
CheckAllButtons();
}
void CheckAllButtons(void) {
if (buttbx.getKeys())
{
for (int i=0; i<LIST_MAX; i++)
{
if ( buttbx.key[i].stateChanged )
{
switch (buttbx.key[i].kstate) {
case PRESSED:
case HOLD:
Joystick.setButton(buttbx.key[i].kchar, 1);
break;
case RELEASED:
case IDLE:
Joystick.setButton(buttbx.key[i].kchar, 0);
break;
}
}
}
}
}
void rotary_init() {
for (int i=0;i<NUMROTARIES;i++) {
pinMode(rotaries[i].pin1, INPUT);
pinMode(rotaries[i].pin2, INPUT);
#ifdef ENABLE_PULLUPS
digitalWrite(rotaries[i].pin1, HIGH);
digitalWrite(rotaries[i].pin2, HIGH);
#endif
}
}
unsigned char rotary_process(int _i) {
unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
return (rotaries[_i].state & 0x30);
}
void CheckAllEncoders(void) {
for (int i=0;i<NUMROTARIES;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);
};
}
}