Buongiorno a tutti,
avrei bisogno di sapere se quello che voglio fare, almeno dal punto di vista concettuale hardware sia corretto. Sto facendo una button box da usare con programmi di Sim Racing sia su PC che su PS5 (vedi foto allegata)
Per farla uso una Arduino Micro; il numero di bottoni sarà 23 (in realtà poi ci sarebbero anche delle rotelle ma una cosa alla volta) e ho usato i contatti A1 A2 A3 A4 A5 da una parte e 12 11 10 9 8 sull’altro ottenendo così 25 combinazioni possibili, dove due rimarranno vuote. Ora, guardando la diagnostica della periferica su windows, mi succede che alcuni bottoni funzionano perfettamente e per altri invece, a gruppi di tre, si accendono contemporaneamente gli stessi 3 contatti; per esempio i primi 3 bottoni dovrebbero accendermi il primo l’1 il secondo il 2 e il terzo il 3, in realtà tutti e tre mi accendono 123 contemporaneamente.
Partendo dal presupposto che il cablaggio sia corretto senza corti o altro e che potrebbe tranquillamente essere un problema di sketch, prima di analizzare anche quegli aspetti, vorrei sapere se è corretto quello che ho fatto come scelta dei pin o se magari ne andavano usati altri.
Spero di essere stato abbastanza chiaro e grazie a chi vorrà darmi una mano.
Giuseppe
Buongiorno e benvenuto nella sezione Italiana del forum,
cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie,
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto.
Grazie Guglielmo, avevo letto il regolamento ma ti dico onestamente che quella parte mi era sfuggita, avevo letto del fare ricerca tra i vecchi post, cosa che ho fatto ma quello che ho trovato era utile ma non potevo più scriverci dentro e altre cosa ma quello mi era proprio sfuggito. Provvedo appena torno a casa, grazie mille.
Giuseppe
In generale i PIN vanno bene
Però hai previsto dei diodi di separazione nel caso (certo) che ci siano più pulsanti schiacciati?
Poi non sarà questo il caso, adesso, ma contaci che ti capiterà a breve
Detto questo passiamo a schema e programma
Grazie per la risposta Salvorhardin, in realtà nel frattempo, avendo trovato nel forum un post simile al mio che si basa sullo stesso problema per realizzare la stessa cosa tratta da un DIY su youtube, ho cambiato i collegamenti del cablaggio, ma ancora non funziona. ho visto che esistono dei programmi per far vedere lo schema un pò più chiari del mio disegno a matita per cui ora lo faccio e metto l'esatta serie di colegamenti ...
Ho fatto lo schema, abbiate pietà è la prima volta...
Le due levette in alto a dx e sx sono a 2 contatti mentre le 4 in mezzo hanno 3 contatti. La prima fila di bottoni partendo dall'alto in realtà sono degli encoder (credo si chiamino così...) che però al momento uso, schiacciandoli, come bottoni)
Sbroglia quella cosa inguardabile
Se non impari a esporre le tue idee in maniera "semplice e lineare" rimarrai sempre nelle canne
Non capisco una cosa: perché lo stesso pulsante (N.B. i bottoni sono quelli delle camicie ) è collegato a due gpio diversi?
C'è una qualche logica dietro? Ed in caso positivo, non conviene realizzarla usando il software cosi da semplificare il cablaggio?
Io di solito abilito le resistenze di pullup interne del micro e faccio chiudere il pulsante sul GND riducendo al minimo componenti e collegamenti.
Appena riesco ci provo...
Uh, ricomincia daccapo descrivendo per ora non quali pin hai usato o cosa succede o non succede, ma spiegando meglio cosa vuoi ottenere.
Io (dalla foto se è quello che vorresti ottenere, ed in parte dalla tua descrizione), vedo 8 pulsanti, 4 deviatori a 3 posizioni, e 4 encoder con relativo pulsante (ossia si ruotano o si premono), e due deviatori (in alto). Ok?
Bene, ora però devi anche chiarire se i pulsanti si possano/debbano poter premere anche più di uno contemporaneamente, perché questo influisce sul tipo di collegamento. Tra l'altro gli encoder con pulsante (come i KY-040) hanno 5 pin di connessione quindi a parte Vcc e GND, hai bisogno di TRE pin per ogni encoder rotativo, il che significa che dovresti prevedere 12 pin dedicati a questo, e se pensi di usare un pin per ogni pulsante/deviatore, te ne servono altri 18, per un totale di 30 pin! Quindi è chiaro che non può essere così, e dal tuo schema (perdonami, non è molto chiaro) sembra che alcuni interruttori agiscano in cascata a pulsanti, eccetera.
Una volta chiarito questo aspetto (quindi spiega meglio come devono funzionare i vari elementi, e NON come adesso -non- funzionano), ti si potrà consigliare meglio.
E comunque se la tua richiesta riguarda il codice, magari dovresti anche postarlo (tra i tag "CODE" mi raccomando, e che sia decentemente indentato).
Non so se possa esserti utile come spunto, ma io qualche anno fa realizzai per mio figlio un pannello del Boeing 737 per Flight Simulator X, dove puoi vedere svariati interruttori, deviatori a 2 o 3 posizioni, e persino commutatori:
Tutto questo gestito con un normale Arduino Nano. Quindi per prima cosa ti consiglierei di pensare meglio a come collegare e gestire pulsanti, deviatori, e quant'altro.
Per finire, io ti consiglio di simulare con WokWi il tuo progetto prima di realizzarlo, per avere non solo la certezza dei collegamenti da realizzare (ed uno schema più leggibile, oltre a poterlo condividere con noi) ma anche del codice. Ovviamente userai temporaneamente la sua seriale come output visto che non puoi collegarci nulla, ma una volta che vedrai che cablaggi e la logica sono corretti, potrai portare il tutto nel progetto "fisico".
Grazie docdoc per la risposta.
Cominciamo da capo...io vorrei fare una Button Box da usare su programmi di SIM Racing sia su PC che su PS5. Questa Button Box deve essere vista come una periferica di gioco e vorrei, se fosse possibile, che i pulsanti vari fossero anche programmabili, nel senso che si potesse assegnargli delle macro tipo ctrl+F o simili.
Ho messo 8 pulsanti, 3 deviatori a 2 posizioni, 1 deviatore a 3 posizione, 4 encoder con pulsante, e in alto, due interruttori a levetta e un pulsante. Per la realizzazione mi sono ispirato a questo video [ MAKE THIS BUTTON BOX | 32 FUNCTION w ENCODERS - YouTube]. In teoria non ci sono pulsanti che vengono premuti contemporaneamente, a meno di errori nel premere, ma mi son reso conto realizzandola, che con i deviatori a 2 posizioni, un contatto è sempre attivo a meno che non lasci libero uno dei due contatti esterni. Perdonami se mi esprimo con termini non corretti ma, come avrai capito dal mio schema, la mia conoscenza in materia è scarsa. Più tardi ti metto il codice abbinato a questo progetto.
Grazie, a dopo.
Giuseppe
quindi come minimo serve di aggiungere un diodo per ogni contatto
e anche di definire bene come collegare i selettori con più posizioni, che non possono essere messi a caso
io direi di partire da mettere giù lo schema
se non cominci con lo schema dubito che arrivi da qualche parte
Questo era lo sketch abbinato al progetto che ho messo nel post precedente, ora vedo di mettere giù uno schema...
//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[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);
};
}
}
Ho provato a staccare il filo a uno dei contatti dei 3 deviatori a 2 posizioni, quelli che avevano sempre un contatto attivo, in modo di non avere il contatto sempre acceso e quello era il problema per cui gli altri pulsanti davano contatti multipli e ora tutti gli altri funzionano correttamente; procedo con lo schema e torno a voi...
Ho visto che in WokWi non c'è la Micro, come faccio?
Alla fine sto usando Eagle, ma mi trovo di fronte a un paio di problemi; lo schema va fatto tenendo conto della posizione che avranno effettivamente i componenti, quindi tipo così?
oppure non considero la posizione finale e lo faccio così?
Questi ovviamente non sono completi, ma prima di andare avanti vorrei sapere come procedere, grazie.
Giuseppe
No, lo schema (.sch) e la board (.brd) sono due cose differenti ...
... lo schema fallo in modo che sia ben chiaro e leggibile, la board devi piazzare tu i componenti come credi sia meglio.
Guglielmo
Ok ho rifatto lo schema, spero vada bene, di sicuro al momento, non sono in grado di fare meglio di così. Tenete presente che le levette S5 S6 S7 S8 hanno una posizione centrale che non fa contatto... non so se il simbolo che ho usato sia giusto ma non ho trovato di meglio. Tra l'altro, dopo aver sostituito le levette a due posizioni che c'erano prima, dove un contatto era sempre attivo, con queste, non ho più problemi di contatti multipli schiacciando altri pulsanti. Da quello che ho letto anche in altri post in merito, con questa disposizione dei pulsanti non è possibile fare selezioni contemporanee e, per farlo, ci vogliono dei diodi, ho capito giusto? ma dove vanno messi? e poi la cosa che mi preme di più... è possibile modificare lo sketch in modo da assegnare delle macro ai singoli comandi, tipo Ctrl+F o Shift+D?
Grazie e a presto.
Giuseppe
Votiamo per la seconda soluzione
Addirittura io "separerei" i due contatti dei selettori a scambio, in due file/colonne separate, naturalmente vicine e chiamati tipo S1A ed S1B
Per i diodi vanno uno per ogni contatto, in serie, orientati in maniera da lasciare passare la corrente durante la scansione, ma bloccare eventuali vie di ritorno
Esistono esempi, comunque nel pomeriggio ci guardo
Beh, giusto per informazione, diciamo che ai fini dello schema e dei test del codice non è essenziale, puoi anche metterci una Nano (basta che non usi pin della Nano che non ci sono sulla Micro, come A6 ed A7, o viceversa). Dico questo perché su WokWi puoi simulare e fare prove senza neanche dover toccare un filo, con Eagle (che fa schemi ottimi ovviamente!) no..