Harley
Personale a Terra
In attesa di volare con l'F16 sono già pronto con l'ICP per simulare alla grande questo stupendo aereo.
Riprendendo lo stesso progetto per l'UFC dell'A10C ho ricreato l'ICP.
Tutto quello che vi occorre è:
- Pulsanti a vostra scelta e switch On-Off-On momentaneamente aperti
- Encoder rotativi EC11
- Basetta millefori 12X10 cm
- Un micro joystick tipo quelli per arduino per ricreare il dcs a 4 vie dell'ICP. Personalmente lo ritengo poco solido e pertanto come vedrete l'ho costruito così la solidità è garantita.
- Interfaccia Arduino: Atmega32U4
- Software Arduino per programmare: https://www.arduino.cc/en/Main/Software
Codice da caricare nell'iterfaccia Arudino: https://github.com/AM-STUDIO/32-FUNCTION-BUTTON-BOX
Video esplicativo da cui ho creato i progetti: https://youtu.be/Z7Sc4MJ8RPM
Recuperato quanto sopra descritto ho creato la parte frontale dell'ICP facendola eseguire in Mdf con taglio laser. Purtroppo le scritte non sono molto precise e durante la colorazione ci sono delle leggere imperfezioni che risaltano, ma ciò è solo per l'aspetto estetico. Il tutto è avvitato su di una cassetta di derivazione in plastica opportunamente dipinta di nero. Il componente che più mi ha dato creato problemo è stato lo switch a 4 vie. Inizialmente avevo preso un micro joystick, quelli usati per esempio per telecomandi che hanno 5 vie (compreso di push centrale). Ma la solidità è veramente scarsa. Pertanto ho utilizzato 4 micro push button saldati su di un pezzo di millefori, una molla di penna a scatto, una vite da 4 mm, due dadi autobloccanti da 4 mm ed una rondella della dimensione opportuna per coprire tutti e quattro i push button. Nelle foto in sequenza potete vederne il montaggio. Assicuratevi solo di non stringere troppo la rondella sui pulsanti e provate per avere dei click che permettano ai quattro contatti di funzionare in modo indipendente.
Con questa piccola interfaccia Arduino ho impostato 24 pulsanti e 4 encoder per impostare HSI CRS e volume radio, ma ognuno può scegliere di impostare qualsiasi switch o rotary, infatti all'interno del simulatore potete assegnare qualsiasi comando. Questo perchè l'interfaccia arduino, una volta programmata con il codice, verrà riconosciuta come joystick a 32 pulsanti. Ricordate che una volta installato su windows il programma Arduino per la programmazione, dovete installare anche una libreria Keyboard, che potete scaricarla direttamente dal programma, potrebbe essere non necessaria, ma forse dipende dal tipo di installazione o aggiornamenti presenti nel programma Arduino. Senza di questa a me dava continuamente errori per la programmazione.
Riprendendo lo stesso progetto per l'UFC dell'A10C ho ricreato l'ICP.
Tutto quello che vi occorre è:
- Pulsanti a vostra scelta e switch On-Off-On momentaneamente aperti
- Encoder rotativi EC11
- Basetta millefori 12X10 cm
- Un micro joystick tipo quelli per arduino per ricreare il dcs a 4 vie dell'ICP. Personalmente lo ritengo poco solido e pertanto come vedrete l'ho costruito così la solidità è garantita.
- Interfaccia Arduino: Atmega32U4
- Software Arduino per programmare: https://www.arduino.cc/en/Main/Software
Codice da caricare nell'iterfaccia Arudino: https://github.com/AM-STUDIO/32-FUNCTION-BUTTON-BOX
//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 4
#define NUMBUTTONS 24
#define NUMROWS 5
#define NUMCOLS 5
byte buttons[NUMROWS][NUMCOLS] = {
{0,1,2,3,4},
{5,6,7,8,9},
{10,11,12,13,14},
{15,16,17,18,19},
{20,21,22,23},
};
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] = {21,20,19,18,15};
byte colPins[NUMCOLS] = {14,16,10,9,8};
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, 32, 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.stateChanged )
{
switch (buttbx.key.kstate) {
case PRESSED:
case HOLD:
Joystick.setButton(buttbx.key.kchar, 1);
break;
case RELEASED:
case IDLE:
Joystick.setButton(buttbx.key.kchar, 0);
break;
}
}
}
}
}
void rotary_init() {
for (int i=0;i<NUMROTARIES;i++) {
pinMode(rotaries.pin1, INPUT);
pinMode(rotaries.pin2, INPUT);
#ifdef ENABLE_PULLUPS
digitalWrite(rotaries.pin1, HIGH);
digitalWrite(rotaries.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.ccwchar, 1); delay(50); Joystick.setButton(rotaries.ccwchar, 0);
};
if (result == DIR_CW) {
Joystick.setButton(rotaries.cwchar, 1); delay(50); Joystick.setButton(rotaries.cwchar, 0);
};
}
}
//USE w ProMicro
//Tested in WIN10 + Assetto Corsa
//AMSTUDIO
//20.8.17
#include <Keypad.h>
#include <Joystick.h>
#define ENABLE_PULLUPS
#define NUMROTARIES 4
#define NUMBUTTONS 24
#define NUMROWS 5
#define NUMCOLS 5
byte buttons[NUMROWS][NUMCOLS] = {
{0,1,2,3,4},
{5,6,7,8,9},
{10,11,12,13,14},
{15,16,17,18,19},
{20,21,22,23},
};
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] = {21,20,19,18,15};
byte colPins[NUMCOLS] = {14,16,10,9,8};
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK, 32, 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.stateChanged )
{
switch (buttbx.key.kstate) {
case PRESSED:
case HOLD:
Joystick.setButton(buttbx.key.kchar, 1);
break;
case RELEASED:
case IDLE:
Joystick.setButton(buttbx.key.kchar, 0);
break;
}
}
}
}
}
void rotary_init() {
for (int i=0;i<NUMROTARIES;i++) {
pinMode(rotaries.pin1, INPUT);
pinMode(rotaries.pin2, INPUT);
#ifdef ENABLE_PULLUPS
digitalWrite(rotaries.pin1, HIGH);
digitalWrite(rotaries.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.ccwchar, 1); delay(50); Joystick.setButton(rotaries.ccwchar, 0);
};
if (result == DIR_CW) {
Joystick.setButton(rotaries.cwchar, 1); delay(50); Joystick.setButton(rotaries.cwchar, 0);
};
}
}
Video esplicativo da cui ho creato i progetti: https://youtu.be/Z7Sc4MJ8RPM
Recuperato quanto sopra descritto ho creato la parte frontale dell'ICP facendola eseguire in Mdf con taglio laser. Purtroppo le scritte non sono molto precise e durante la colorazione ci sono delle leggere imperfezioni che risaltano, ma ciò è solo per l'aspetto estetico. Il tutto è avvitato su di una cassetta di derivazione in plastica opportunamente dipinta di nero. Il componente che più mi ha dato creato problemo è stato lo switch a 4 vie. Inizialmente avevo preso un micro joystick, quelli usati per esempio per telecomandi che hanno 5 vie (compreso di push centrale). Ma la solidità è veramente scarsa. Pertanto ho utilizzato 4 micro push button saldati su di un pezzo di millefori, una molla di penna a scatto, una vite da 4 mm, due dadi autobloccanti da 4 mm ed una rondella della dimensione opportuna per coprire tutti e quattro i push button. Nelle foto in sequenza potete vederne il montaggio. Assicuratevi solo di non stringere troppo la rondella sui pulsanti e provate per avere dei click che permettano ai quattro contatti di funzionare in modo indipendente.
Con questa piccola interfaccia Arduino ho impostato 24 pulsanti e 4 encoder per impostare HSI CRS e volume radio, ma ognuno può scegliere di impostare qualsiasi switch o rotary, infatti all'interno del simulatore potete assegnare qualsiasi comando. Questo perchè l'interfaccia arduino, una volta programmata con il codice, verrà riconosciuta come joystick a 32 pulsanti. Ricordate che una volta installato su windows il programma Arduino per la programmazione, dovete installare anche una libreria Keyboard, che potete scaricarla direttamente dal programma, potrebbe essere non necessaria, ma forse dipende dal tipo di installazione o aggiornamenti presenti nel programma Arduino. Senza di questa a me dava continuamente errori per la programmazione.
Allegati
-
IMG_20190913_171855.jpg2,2 MB · Visite: 314
-
IMG_20190918_152548.jpg583,3 KB · Visite: 376
-
IMG_20190917_195147.jpg1,9 MB · Visite: 315
-
IMG_20190916_182406.jpg1,8 MB · Visite: 299
-
IMG_20190913_175416.jpg2,2 MB · Visite: 305
-
IMG_20190913_175402.jpg2,1 MB · Visite: 298
-
IMG_20190913_172656.jpg1,8 MB · Visite: 283
-
IMG_20190913_172244.jpg1,8 MB · Visite: 299
-
IMG_20190913_172001.jpg2 MB · Visite: 302