sandb0x
09-24-2016, 03:27 AM
Hi folks!
This is a recipe how to make a 128 input DirectX interface using only two wires on Arduino Leonardo for around £15 (Board + I/O expanders).
Parts:
1. Arduino Leonardo or Micro (Mega and Uno may work with https://github.com/NicoHood/HoodLoader2) not tested by me.
2. 8 x MCP23017 http://uk.farnell.com/microchip/mcp23017-e-sp/ic-io-expander-16bit-i2c-28dip/dp/1332088
3. 2 x Breadboards or make your own PCB.
4. 8 x 10K resistors
5. Switches and Buttons
6. Arduino Libraries
a. https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
b. https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0
7. 128 buttons joystick tester: http://www.planetpointy.co.uk/joystick-test-application/
Notes:
To connect a button or a switch: one wire to ground, second to first MCP pin 21 (GPA0) - result DX button 1. No need for a resistor as it uses an internal pullout.
For a DX button 16 connect to first MCP pin 8 (GPB7)
For a DX button 17 connect to second MCP pin 21 (GPA0) and so on.
The interface is recognised by P3D and LINDA.
FSUIPC uses windows interface so it only recognises up to 32 buttons.
The joystick axes, hat switches can also be activated. Refer to joystick library documentation.
The interface can be father expanded by using shift registers but it simpler to make another one using different joystick address.
The Arduino code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Joystick.h>
Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;
Adafruit_MCP23017 mcp3;
Adafruit_MCP23017 mcp4;
Adafruit_MCP23017 mcp5;
Adafruit_MCP23017 mcp6;
Adafruit_MCP23017 mcp7;
Joystick_ Joystick = {
Joystick_(0x03, 128, 0, false, false, false, false, false, false, false, false, false, false, false)
};
void setup() {
mcp0.begin(0); // use address 0X20
for (int index = 0; index < 16; index++)
{
mcp0.pinMode(index, INPUT);
mcp0.pullUp(index, HIGH);
}
mcp1.begin(1); // use address 0X21
for (int index = 0; index < 16; index++)
{
mcp1.pinMode(index, INPUT);
mcp1.pullUp(index, HIGH);
}
mcp2.begin(2); // use address 0X22
for (int index = 0; index < 16; index++)
{
mcp2.pinMode(index, INPUT);
mcp2.pullUp(index, HIGH);
}
mcp3.begin(3); // use address 0X23
for (int index = 0; index < 16; index++)
{
mcp3.pinMode(index, INPUT);
mcp3.pullUp(index, HIGH);
}
mcp4.begin(4); // use address 0X24
for (int index = 0; index < 16; index++)
{
mcp4.pinMode(index, INPUT);
mcp4.pullUp(index, HIGH);
}
mcp5.begin(5); // use address 0X25
for (int index = 0; index < 16; index++)
{
mcp5.pinMode(index, INPUT);
mcp5.pullUp(index, HIGH);
}
mcp6.begin(6); // use address 0X26
for (int index = 0; index < 16; index++)
{
mcp6.pinMode(index, INPUT);
mcp6.pullUp(index, HIGH);
}
mcp7.begin(7); // use address 0X27
for (int index = 0; index < 16; index++)
{
mcp7.pinMode(index, INPUT);
mcp7.pullUp(index, HIGH);
}
// Initialize Joystick Library
Joystick.begin();
}
// Last state of the buttons
int lastButtonState0[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState2[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState3[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState4[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState5[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState6[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState7[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void loop() {
// Read pin values mcp0
for (int index = 0; index < 16; index++)
{
int currentButtonState0 = !mcp0.digitalRead(index);
if (currentButtonState0 != lastButtonState0[index])
{
Joystick.setButton(index, currentButtonState0);
lastButtonState0[index] = currentButtonState0;
}
}
// Read pin values mcp1
for (int index = 0; index < 16; index++)
{
int currentButtonState1 = !mcp1.digitalRead(index);
if (currentButtonState1 != lastButtonState1[index])
{
Joystick.setButton(index+16, currentButtonState1);
lastButtonState1[index] = currentButtonState1;
}
}
// Read pin values mcp2
for (int index = 0; index < 16; index++)
{
int currentButtonState2 = !mcp2.digitalRead(index);
if (currentButtonState2 != lastButtonState2[index])
{
Joystick.setButton(index+32, currentButtonState2);
lastButtonState2[index] = currentButtonState2;
}
}
// Read pin values mcp3
for (int index = 0; index < 16; index++)
{
int currentButtonState3 = !mcp3.digitalRead(index);
if (currentButtonState3 != lastButtonState3[index])
{
Joystick.setButton(index+48, currentButtonState3);
lastButtonState3[index] = currentButtonState3;
}
}
// Read pin values mcp4
for (int index = 0; index < 16; index++)
{
int currentButtonState4 = !mcp4.digitalRead(index);
if (currentButtonState4 != lastButtonState4[index])
{
Joystick.setButton(index+64, currentButtonState4);
lastButtonState4[index] = currentButtonState4;
}
}
// Read pin values mcp5
for (int index = 0; index < 16; index++)
{
int currentButtonState5 = !mcp5.digitalRead(index);
if (currentButtonState5 != lastButtonState5[index])
{
Joystick.setButton(index+80, currentButtonState5);
lastButtonState5[index] = currentButtonState5;
}
}
// Read pin values mcp6
for (int index = 0; index < 16; index++)
{
int currentButtonState6 = !mcp6.digitalRead(index);
if (currentButtonState6 != lastButtonState6[index])
{
Joystick.setButton(index+96, currentButtonState6);
lastButtonState6[index] = currentButtonState6;
}
}
// Read pin values mcp7
for (int index = 0; index < 16; index++)
{
int currentButtonState7 = !mcp7.digitalRead(index);
if (currentButtonState7 != lastButtonState7[index])
{
Joystick.setButton(index+112, currentButtonState7);
lastButtonState7[index] = currentButtonState7;
}
}
delay(50);
Joystick.sendState();
}
Connection diagram:
http://i.imgur.com/R9qKBPw.jpg
http://www.mycockpit.org/forums/attachment.php?attachmentid=11748&stc=1
MCP23017 pins layout:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11743&stc=1
MCP23017 Addresses:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11744&stc=1
Results in joystick tester:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11745&stc=1
Result in P3D:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11746&stc=1
Results in LINDA:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11747&stc=1
Example of 64 buttons DX device on stripboard:
http://www.mycockpit.org/forums/attachment.php?attachmentid=12510&stc=1
http://www.mycockpit.org/forums/attachment.php?attachmentid=12511&stc=1
This is a recipe how to make a 128 input DirectX interface using only two wires on Arduino Leonardo for around £15 (Board + I/O expanders).
Parts:
1. Arduino Leonardo or Micro (Mega and Uno may work with https://github.com/NicoHood/HoodLoader2) not tested by me.
2. 8 x MCP23017 http://uk.farnell.com/microchip/mcp23017-e-sp/ic-io-expander-16bit-i2c-28dip/dp/1332088
3. 2 x Breadboards or make your own PCB.
4. 8 x 10K resistors
5. Switches and Buttons
6. Arduino Libraries
a. https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
b. https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0
7. 128 buttons joystick tester: http://www.planetpointy.co.uk/joystick-test-application/
Notes:
To connect a button or a switch: one wire to ground, second to first MCP pin 21 (GPA0) - result DX button 1. No need for a resistor as it uses an internal pullout.
For a DX button 16 connect to first MCP pin 8 (GPB7)
For a DX button 17 connect to second MCP pin 21 (GPA0) and so on.
The interface is recognised by P3D and LINDA.
FSUIPC uses windows interface so it only recognises up to 32 buttons.
The joystick axes, hat switches can also be activated. Refer to joystick library documentation.
The interface can be father expanded by using shift registers but it simpler to make another one using different joystick address.
The Arduino code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Joystick.h>
Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;
Adafruit_MCP23017 mcp3;
Adafruit_MCP23017 mcp4;
Adafruit_MCP23017 mcp5;
Adafruit_MCP23017 mcp6;
Adafruit_MCP23017 mcp7;
Joystick_ Joystick = {
Joystick_(0x03, 128, 0, false, false, false, false, false, false, false, false, false, false, false)
};
void setup() {
mcp0.begin(0); // use address 0X20
for (int index = 0; index < 16; index++)
{
mcp0.pinMode(index, INPUT);
mcp0.pullUp(index, HIGH);
}
mcp1.begin(1); // use address 0X21
for (int index = 0; index < 16; index++)
{
mcp1.pinMode(index, INPUT);
mcp1.pullUp(index, HIGH);
}
mcp2.begin(2); // use address 0X22
for (int index = 0; index < 16; index++)
{
mcp2.pinMode(index, INPUT);
mcp2.pullUp(index, HIGH);
}
mcp3.begin(3); // use address 0X23
for (int index = 0; index < 16; index++)
{
mcp3.pinMode(index, INPUT);
mcp3.pullUp(index, HIGH);
}
mcp4.begin(4); // use address 0X24
for (int index = 0; index < 16; index++)
{
mcp4.pinMode(index, INPUT);
mcp4.pullUp(index, HIGH);
}
mcp5.begin(5); // use address 0X25
for (int index = 0; index < 16; index++)
{
mcp5.pinMode(index, INPUT);
mcp5.pullUp(index, HIGH);
}
mcp6.begin(6); // use address 0X26
for (int index = 0; index < 16; index++)
{
mcp6.pinMode(index, INPUT);
mcp6.pullUp(index, HIGH);
}
mcp7.begin(7); // use address 0X27
for (int index = 0; index < 16; index++)
{
mcp7.pinMode(index, INPUT);
mcp7.pullUp(index, HIGH);
}
// Initialize Joystick Library
Joystick.begin();
}
// Last state of the buttons
int lastButtonState0[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState2[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState3[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState4[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState5[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState6[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int lastButtonState7[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void loop() {
// Read pin values mcp0
for (int index = 0; index < 16; index++)
{
int currentButtonState0 = !mcp0.digitalRead(index);
if (currentButtonState0 != lastButtonState0[index])
{
Joystick.setButton(index, currentButtonState0);
lastButtonState0[index] = currentButtonState0;
}
}
// Read pin values mcp1
for (int index = 0; index < 16; index++)
{
int currentButtonState1 = !mcp1.digitalRead(index);
if (currentButtonState1 != lastButtonState1[index])
{
Joystick.setButton(index+16, currentButtonState1);
lastButtonState1[index] = currentButtonState1;
}
}
// Read pin values mcp2
for (int index = 0; index < 16; index++)
{
int currentButtonState2 = !mcp2.digitalRead(index);
if (currentButtonState2 != lastButtonState2[index])
{
Joystick.setButton(index+32, currentButtonState2);
lastButtonState2[index] = currentButtonState2;
}
}
// Read pin values mcp3
for (int index = 0; index < 16; index++)
{
int currentButtonState3 = !mcp3.digitalRead(index);
if (currentButtonState3 != lastButtonState3[index])
{
Joystick.setButton(index+48, currentButtonState3);
lastButtonState3[index] = currentButtonState3;
}
}
// Read pin values mcp4
for (int index = 0; index < 16; index++)
{
int currentButtonState4 = !mcp4.digitalRead(index);
if (currentButtonState4 != lastButtonState4[index])
{
Joystick.setButton(index+64, currentButtonState4);
lastButtonState4[index] = currentButtonState4;
}
}
// Read pin values mcp5
for (int index = 0; index < 16; index++)
{
int currentButtonState5 = !mcp5.digitalRead(index);
if (currentButtonState5 != lastButtonState5[index])
{
Joystick.setButton(index+80, currentButtonState5);
lastButtonState5[index] = currentButtonState5;
}
}
// Read pin values mcp6
for (int index = 0; index < 16; index++)
{
int currentButtonState6 = !mcp6.digitalRead(index);
if (currentButtonState6 != lastButtonState6[index])
{
Joystick.setButton(index+96, currentButtonState6);
lastButtonState6[index] = currentButtonState6;
}
}
// Read pin values mcp7
for (int index = 0; index < 16; index++)
{
int currentButtonState7 = !mcp7.digitalRead(index);
if (currentButtonState7 != lastButtonState7[index])
{
Joystick.setButton(index+112, currentButtonState7);
lastButtonState7[index] = currentButtonState7;
}
}
delay(50);
Joystick.sendState();
}
Connection diagram:
http://i.imgur.com/R9qKBPw.jpg
http://www.mycockpit.org/forums/attachment.php?attachmentid=11748&stc=1
MCP23017 pins layout:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11743&stc=1
MCP23017 Addresses:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11744&stc=1
Results in joystick tester:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11745&stc=1
Result in P3D:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11746&stc=1
Results in LINDA:
http://www.mycockpit.org/forums/attachment.php?attachmentid=11747&stc=1
Example of 64 buttons DX device on stripboard:
http://www.mycockpit.org/forums/attachment.php?attachmentid=12510&stc=1
http://www.mycockpit.org/forums/attachment.php?attachmentid=12511&stc=1