Problema su buttonbox

Buonasera a tutti da Giuseppe !!
Vi scrivo perchè avrei bisogno di una mano per il mio progetto. Essendo impreparato sul linguaggio di programmazione e riguardo alle conoscenze basiche di elettronica, mi sento molto legato.
Vi spiego il mio progetto e problema:
Tramite internet ho trovato uno schizzo di un "bottone", (puoi trovarlo anche su youtube).
La "scatola dei bottoni" la utilizza per un simulatore di volo.
Ho impostato la mia leonardo come joystick e fin qui ok. Modificando lo schizzo, sono riuscito a configurare 25 tasti sui pin digitali, impostando le colonne e righe: pin 4 e 8 = tasto 1; pin 4 e 9 = tasto 2; pin 5 e 5 = tasto 10 e cosi via.
Non ci sono problemi se questi sono degli interruttori momentanei, in quanto ad ogni "cliccata" dell'interruttore parte un segnale al simulatore di fare quella determinata azione.
Io però vorrei mettere degli interruttori on-off NON momentanei, per un fatto di soddisfazione e estetica. E qui mi rivolgo dubbi e problemi.
Io vorrei che, quando metto l'interruttore su, il segnale su arduino non è continuo come se fosse un pulsante continuo, ma che sia solo un segnale.
Vorrei anche che quando un vado a chiude l'interruttore, quindi su off, arduino capisca di coraggio un altro segnale al mio tasto precedentemente assegnato.
Praticamente: sento che passa della corrente: do un segnale;
sento che non passa più corrente: do un altro segnale.

Chiedo scusa per la lunghezza del post, ma volevo essere il più chiaro possibile. Vi allego lo sketch se lo volete visionare.
Ringraziandovi anticipatamente, vi auguro una buona serata!

Giuseppe

//BUTTON BOX 
//25 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 3, 4, 5, 6, 7.



#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] = {3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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);
    };
  }
}

DCS_BUTTONBOX_v1.ino (4.06 KB)

Prova una cosa del genere (ho evidenziato le parti aggiunte o modificate):

//BUTTON BOX 
//25 bottoni
//colonne pin 8 9 10 11 12
//righe pin 3 4 5 6 7



#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] = {3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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);

// --- MODIFICA
KeyState prevKeyState[LIST_MAX];
// ------------
void setup() {
  Joystick.begin();
  rotary_init();

// --- MODIFICA
  for (int i=0; i<LIST_MAX; i++)
	  prevKeyState[i] = RELEASED;
// ------------
}

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:
// --- MODIFICA
                              if ( prevKeyState[i] == RELEASED ) {
                                Joystick.setButton(buttbx.key[i].kchar, 1);
                                break;
                              }
                    case RELEASED:
                    case IDLE:
                              if ( prevKeyState[i] == PRESSED ) {
                                Joystick.setButton(buttbx.key[i].kchar, 0);
                                break;
                              }
// ------------
             }
            }
// --- MODIFICA
           prevKeyState[i] == buttbx.key[i].kstate;
// ------------
         }
     }
}


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);
    };
  }
}

In pratica memorizzo l'ultimo stato del bottone ed attivo il comando solo se c'è un cambiamento (RELEASED->PRESSED o PRESSED->RELEASED)

Ciao docdoc, grazie per avermi risposto! sfortunatamente lo sketch non funziona: quando lo commuto su on, mi rileva un pulsante sempre premuto(il che non mi va bene, vorrei solo un segnale); se vado a commutarlo su off invece, arduino continua a rilevare un pulsante premuto.
Ti allego uno screen. gli interruttori sono stati messi su on, e poi su off.

Se vuoi anche alleggerire lo sketch, fai pure, togli encoders e altro, a me interessano solo i bottoni.
Ti allego lo sketch semplificato da me, con effettivi 32 bottoni, con la tua modifica

//DCS_BUTTONBOX_v1.2_CON_MODIFICA
//originalmente creato da AMSTUDIO il 20.8.17
//Aiuto di DOCDOC, utente forum arduino
//Giuseppe Lecis
//11.2.2019

//Versione 1.2:
//32 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 1, 2, 3, 4, 5, 6, 7.

//Non pienamente funzionante. Versione di prova non definitiva

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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,24},
  {25,26,27,28,29},
  {30,31}
};

byte rowPins[NUMROWS] = {1,2,3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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);

// --- MODIFICA
KeyState prevKeyState[LIST_MAX];
// ------------
void setup() {
  Joystick.begin();

// --- MODIFICA
  for (int i=0; i<LIST_MAX; i++)
    prevKeyState[i] = RELEASED;
// ------------
}

void loop() { 

  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:
// --- MODIFICA
                              if ( prevKeyState[i] == RELEASED ) {
                                Joystick.setButton(buttbx.key[i].kchar, 1);
                                break;
                              }
                    case RELEASED:
                    case IDLE:
                              if ( prevKeyState[i] == PRESSED ) {
                                Joystick.setButton(buttbx.key[i].kchar, 0);
                                break;
                              }
// ------------
             }
            }
// --- MODIFICA
           prevKeyState[i] == buttbx.key[i].kstate;
// ------------
         }
     }
}

Grazie

Giuseppe

Cattura.PNG

DCS_BUTTONBOX_v1.2_CON_MODIFICA.ino (2.15 KB)

DCS_BUTTONBOX_v1.2_PUSHBUTTON.ino (1.66 KB)

Allora ragazzi, ci sono riuscito. Non credevo potessi riuscirci :grinning: :grinning: :grinning:
Passiamo alla fase due della buttonbox: resistenze e quant'altro.
Prima di ogni interruttore è consigliabile mettere una resistenza o basta quella di PULL_UP?
Condensatori o altri comoponenti?

//DCS_BUTTONBOX_v1.3_INTERRUTTORE_ON_OFF
//originalmente creato da AMSTUDIO il 20.8.17
//Aiuto di DOCDOC, utente forum arduino
//Giuseppe Lecis
//11.2.2019

//Versione 1.2:
//32 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 1, 2, 3, 4, 5, 6, 7.
//Utilizzabile con pushbutton oppure interruttori momentanei


#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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,24},
  {25,26,27,28,29},
  {30,31}
};

byte rowPins[NUMROWS] = {1,2,3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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();
}

void loop() { 

  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:                                                //inizio della modifica agli stati dei bottoni
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
                    case RELEASED:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
            }
           }   
         }
     }
}

Grazie in anticipo!

Bepy93:
Allora ragazzi, ci sono riuscito. Non credevo potessi riuscirci :grinning: :grinning: :grinning:

Bene, ma fammi capire. Stando a quanto mi sembra di capire (non ho mai usato la libreria) il problema era ancora più semplice, ossia lo stato PRESSED si ha quando viene premuto la prima volta il pulsante, dopo di che resta su HOLD, quindi nello switch ti è bastato usare il solo PRESSED ed in risposta a questo attivare e poco dopo disattivare il pulsante con la setButton, e fare la stessa cosa al rilascio (RELEASE) ed ignorare quindi gli stati HOLD e IDLE.
E' così?

Esatto, io non volevo che fosse sempre HOLD, ma un HOLD e IDLE. Quindi dopo aver tolto quello, ho aggiunto una riga allo stato del joystick. Prima ti accendi, poi ti spegni. Stessa cosa quando si va a commutare di nuovo l'interruttore: HOLD e IDLE.
Se ora io volessi cambiare il funzionamento di un interruttore di 32, magari farlo diventare come in origine, quindi un semplice pushbutton come agisco? ho provato ieri ma senza risultati!!

Grazie

Giuseppe

Bepy93:
Se ora io volessi cambiare il funzionamento di un interruttore di 32, magari farlo diventare come in origine, quindi un semplice pushbutton come agisco? ho provato ieri ma senza risultati!!

Ti basta una "if" per fare il codice attuale se il numero del bottone attuale è diverso da quello "speciale", ed il normale comportamento (quello che avevi prima) se è il bottone "speciale".

Ma proprio con gli IF ho provato ieri, ma non mi andava.....


Ho spulciato sul profilo github del fondatore della libreria, e ho trovato qualcosa che puo essermi utile. Domani proverò e vi farò sapere.
Vi allego il link della libreria per chi volesse scaricarla

Buona serata

Giuseppe

Bepy93:
Ma proprio con gli IF ho provato ieri, ma non mi andava.....

In questi casi posta il nuovo codice e descrivi perché non funziona e vediamo...

Ciao docdoc. Sono da smartphone quindi mi è difficile scriverti i codici. In ogni caso, il codice è quello che c’è qui sopra, qualche post qui sopra, la versione “1.3”. Io vorrei far funzionare alcuni pulsanti come pushbutton, quindi che danno il segnale solo quando li tengo premuti. E capire come agire per selezionare il pulsante desiderato. Esempio: ho 32 interruttori on-off. Voglio che l’interrruttore 10 diventi un pulsante. Come faccio tramite sketch a dirgli a arduino che quel pulsante lo deve far funzionare come pushbutton? Ecco che qui possiamo usare (magari) i comandi PRESSED E IDLE che sono presenti nello sketch del primo post. Ma come faccio a indicargli quel specifico bottone?

Giuseppe

Avevo provato a suggerirtelo, comunque una cosa del genere:

#define SPECIAL_BUTTON 10
...
  switch (buttbx.key[i].kstate) {  
  case PRESSED:
    Joystick.setButton(buttbx.key[i].kchar, 1);
    if ( i == SPECIAL_BUTTON ) {
      delay(50);
      Joystick.setButton(buttbx.key[i].kchar, 0);
    }
    break;
  case RELEASED:
    if ( i == SPECIAL_BUTTON ) {
      Joystick.setButton(buttbx.key[i].kchar, 1);
      delay(50);
    }
    Joystick.setButton(buttbx.key[i].kchar, 0);
    break;
  }
  ...

Ma devo fargli un “#define special button 10” altrimenti non me lo riconosce giusto?

Scusami, ho letto di velocità a lavoro e non sono stato attento.... provo vi dico!!

Grazie 1000
Giuseppe

Not working..... appena ho un po di tempo, spero domenica, mi ci metto due orette e vedo cosa riesco a fare.

Sto giro quando si preme un pushbutton, li rileva TUTTI come sempre premuto e non si spengono più.
Grazie comunque ragazzi

Giuseppe

Bepy93:
Sto giro quando si preme un pushbutton, li rileva TUTTI come sempre premuto e non si spengono più.

Beh si, certo, forse ho capito male la tua frase "Voglio che l'interrruttore 10 diventi un pulsante" ma con quella modifica SOLAMENTE l'interruttore on-off 10 viene gestito come se fosse appunto un pulsante (ossia fa ON-OFF quando lo premi e nuovamente ON-OFF quando lo lasci) gli altri restano come sono (su PRESSED fanno solo ON e su RELEASED solo OFF), quindi non ho capito cosa intendi...
Hai messo solo il 10 come interruttore on-off e gli altri restano pushbutton? Se hai fatto il contrario (sono tutti on-off ed uno solo pushbutton) dovresti cambiare la if() mettendo "!=" invece di "==".

Spiegati meglio, e se non va, posta il tuo codice insieme a come sono questi interruttori-pulsanti.

Ciao docdoc! Allora: con lo sketch qui sotto, la versione v1.3, abbiamo 32 interruttori NON momentanei funzionanti, i quali, una volto commutati, danno solo un segnale. Questi, ri-commutati su off, danno un altro segnale, e cosi mi vanno benissimo. Io ho necessità di usare un pulsante di questi 32 come un normale pushbutton, quindi, quando lo si tiene premuto, arduino riceve un segnale continuo, quando lo si rilascia, il segnale svanisce.
Spiegartelo meglio non ne sono capace.
Con la modifica da te postata, utilizzando "!=" al posto di "==" sull' "if", TUTTI gli interruttori mi diventano dei pushbutton. Sembra che il "#define SPECIAL_BUTTON 10" non funzioni a dovere.
Ovviamente il tasto 0 corrisponde al Joy_button 1 fin0 al tasto 31 che corrisponde al Joy_button 32.
Il problema rimane sempre quello: capire come cambiar funzionamento di un singolo interruttore per trasformarlo in pushbutton

//DCS_BUTTONBOX_v1.3_INTERRUTTORE_ON_OFF
//originalmente creato da AMSTUDIO il 20.8.17
//Aiuto di DOCDOC, utente forum arduino
//Giuseppe Lecis
//11.2.2019

//Versione 1.3:
//32 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 1, 2, 3, 4, 5, 6, 7.
//Utilizzabile con interruttori fissi on-off


#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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,24},
  {25,26,27,28,29},
  {30,31}
};

byte rowPins[NUMROWS] = {1,2,3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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();
}

void loop() { 

  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:                                                //inizio della modifica agli stati dei bottoni
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
                    case RELEASED:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
            }
           }   
         }
     }
}

Casomai, scaricati la libreria, e prova collegando due pushbutton e un interruttore ad una breadbord, poi vai su proprietà del joystick, e vedi come rispondono i comandi

Grazie

Giuseppe

Sto provando e riprovando, e o va in un modo, o va nell'altro modo. no riesco a far funzionare in modo differente i due ingressi. mi sono aiutato seguendo le istruzioni per le tastiere matrix, ma niente :confused:

Ho provato a scrivere lo sketch, ma non vuole saperne di funzionare.

//DCS_BUTTONBOX_v1.3.2_WIP
//originalmente creato da AMSTUDIO il 20.8.17
//Aiuto di DOCDOC, utente forum arduino
//Giuseppe Lecis
//18.2.2019

//Versione 1.3.2 WIP
//32 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 1, 2, 3, 4, 5, 6, 7.
//Utilizzabile con interruttori on-off NON momentanei

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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, 24},
  {25, 26, 27, 28, 29},
  {30, 31}
};

byte rowPins[NUMROWS] = {1, 2, 3, 4, 5, 6, 7};
byte colPins[NUMCOLS] = {8, 9, 10, 11, 12};

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();
}

void loop() {

  if (buttbx.getKeys())
  {
    if ( buttbx.key[0].stateChanged )
    {
      switch (buttbx.key[0].kstate) {
        case PRESSED:
          Joystick.setButton(buttbx.key[0].kchar, 1);
          delay(100);
          Joystick.setButton(buttbx.key[0].kchar, 0);
          break;
        case RELEASED:
          Joystick.setButton(buttbx.key[0].kchar, 1);
          delay(100);
          Joystick.setButton(buttbx.key[0].kchar, 0);
          break;
      }
    }
    if ( buttbx.key[1].stateChanged )
    {
      switch (buttbx.key[1].kstate) {
        case PRESSED:
        case HOLD:
          Joystick.setButton(buttbx.key[1].kchar, 1);
          break;
        case RELEASED:
        case IDLE:
          Joystick.setButton(buttbx.key[1].kchar, 0);
          break;
      }
    }
    if ( buttbx.key[2].stateChanged )
    {
      switch (buttbx.key[2].kstate) {
        case PRESSED:
        case HOLD:
          Joystick.setButton(buttbx.key[2].kchar, 1);
          break;
        case RELEASED:
        case IDLE:
          Joystick.setButton(buttbx.key[2].kchar, 0);
          break;
      }
    }
  }
}

Ho provato anche a fare lo sketch seguendo altri esempi, ma addirittura qui i pulsanti fanno quello che vogliono....

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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, 24},
  {25, 26, 27, 28, 29},
  {30, 31}
};

byte rowPins[NUMROWS] = {1, 2, 3, 4, 5, 6, 7};
byte colPins[NUMCOLS] = {8, 9, 10, 11, 12};

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  32, 0,                  // Button Count, Hat Switch Count
  false, false, false,    // No X,Y,and Z Axis
  false, false, false,    // No Rx, Ry, or Rz
  false, false,           // No rudder or throttle
  false, false, false);   // No accelerator, brake, or steering

void setup() {

  Joystick.begin();
}
int lastButtonState[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


void loop() {

  for (int index = 0; index < 32; index++){
    int currentButtonState = !digitalRead(index);
    if (currentButtonState != lastButtonState[index]){
      switch (index) {
        case 1: PRESSED:
          Joystick.setButton(0, 1);
          delay(100);
          Joystick.setButton(0, 0);
          break;
        case 2: RELEASED:
          Joystick.setButton(0, 1);
          delay(100);
          Joystick.setButton(0, 0); 
        case 3:
          Joystick.setButton(1, currentButtonState);
          break;
        case 4:
          Joystick.setButton(2, currentButtonState);
          break;
        case 5:
          Joystick.setButton(10, currentButtonState);
          break;
      }                
      lastButtonState[index] = currentButtonState;
    }
  }
  delay(100);
}

:cry: :cry: :cry: :cry: :cry: :cry: :cry: :cry:

DCS_BUTTONBOX_v1.3.2_WIP.ino (2.2 KB)

prova_joistick_da_zero.ino (1.82 KB)

Ora forse ho capito meglio, grazie.
Praticamente con questo codice sotto dovrebbe fare come dici, ossia tutti i pulsanti mandano solo un impulso ON-OFF quando sono attivati ed uno ON-OFF quando li rilasci, mentre solo il 10 (qui impostato staticamente per prova) manda ON continuamente finché premuto, e OFF quando è rilasciato.

//DCS_BUTTONBOX_v1.4_INTERRUTTORE_ON_OFF
//originalmente creato da AMSTUDIO il 20.8.17
//Aiuto di DOCDOC, utente forum arduino
//Giuseppe Lecis
//11.2.2019

//Versione 1.4:
//32 bottoni
//colonne pin 8, 9, 10, 11, 12.
//righe pin 1, 2, 3, 4, 5, 6, 7.
//Utilizzabile con interruttori fissi on-off

// ESTENSIONE DI PROVA, PULSANTE 10 
#define SPECIAL_BUTTON 10

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 7
#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,24},
  {25,26,27,28,29},
  {30,31}
};

byte rowPins[NUMROWS] = {1,2,3,4,5,6,7}; 
byte colPins[NUMCOLS] = {8,9,10,11,12}; 

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();
}

void loop() { 

  CheckAllButtons();

}

void CheckAllButtons(void) {
  if (buttbx.getKeys())
  {
   for (int i=0; i<LIST_MAX; i++)   
  {
     if ( buttbx.key[i].stateChanged )   
    {
      if ( i != SPECIAL_BUTTON ) {
        // GESTIONE INTERRUTTORI NORMALI
        switch (buttbx.key[i].kstate) {  
          case PRESSED:
            Joystick.setButton(buttbx.key[i].kchar, 1);
            delay(50);
            Joystick.setButton(buttbx.key[i].kchar, 0);
            break;
          case RELEASED:
            Joystick.setButton(buttbx.key[i].kchar, 1);
            delay(50);
            Joystick.setButton(buttbx.key[i].kchar, 0);
            break;
        }
      }
	  else
	  {
         // GESTIONE PULSANTI "SPECIALI"
         switch (buttbx.key[i].kstate) {  
           case PRESSED:
           case HOLD:
             Joystick.setButton(buttbx.key[1].kchar, 1);
             break;
           case RELEASED:
           case IDLE:
             Joystick.setButton(buttbx.key[1].kchar, 0);
             break;
         }
      }   
   }
 }
}

Se la cosa funziona si può poi renderlo più parametrico per più pulsanti, ma prova e dammi intanto conferma se questo codice ti funziona o meno, poi ti posso aiutare anche per parametrizzarlo.

Ciao docdoc. GRazie, ma ancora non va..... Li continua a vedere tutti come interruttori. Forse creando due joystick riusciamo a risolvere. Un joystick con 25 tasti da farli funzionare come interruttori, e un'altro con 7 tasti da usarli come pushbutton.
Infine, con questa riga

for (int i = 0; i < LIST_MAX; i++)

noi diciamo che tutti gli interruttori devono funzionare nel modo in cui viene riportato sotto

      if ( buttbx.key[0].stateChanged )
      {
        if ( i != SPECIAL_BUTTON ) {                                   // GESTIONE INTERRUTTORI NORMALI
          switch (buttbx.key[0].kstate) {
            case PRESSED:
              Joystick.setButton(buttbx.key[0].kchar, 1);
              delay(50);
              Joystick.setButton(buttbx.key[0].kchar, 0);
              break;
            case RELEASED:
              Joystick.setButton(buttbx.key[0].kchar, 1);
              delay(50);
              Joystick.setButton(buttbx.key[0].kchar, 0);
              break;

Se noi facessimo questo?

for (int i = 0; i < 24; i++)

e l'altro joystick

for (int i = 0; i < 7; i++)

guarda qua uno schizzo fatto a caso in velocità

#include <Keypad.h>
#include <Joystick.h>

#define ENABLE_PULLUPS
#define NUMBUTTONS 32
#define NUMROWS 6
#define NUMCOLS 4
#define NUMROWS2 2                                    //modifica
#define NUMCOLS2 4                                     //modifica


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},
};
byte buttons2 [NUMROWS2][NUMCOLS] = {            //modifica
  {24,25,26,27},
  {28,29,30,31}
};

byte rowPins[NUMROWS] = {1,2,3,4,5,6}; 
byte colPins[NUMCOLS] = {8,9,10,11}; 
byte rowPins2[NUMROWS2] = {7};              //modifica
byte rowPins2[NUMCOLS2] = {12};              //modifica

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS); 
Keypad buttbx2 = Keypad( makeKeymap(buttons2), rowPins2, colPins2, NUMROWS2, NUMCOLS2);    //modifica

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();
}

void loop() { 

  CheckAllButtons();

}

void CheckAllButtons(void) {                                    //qui non ho ancora ragionato su come fare
      if (buttbx.getKeys())
    {
       for (int i=0; i<LIST_MAX; i++)   
        {
           if ( buttbx.key[i].stateChanged )   
            {
            switch (buttbx.key[i].kstate) {  
                    case PRESSED: 
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
                    case RELEASED:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              delay(50);
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
            }
           }   
         }
     }
}

Grazie docdoc, buona serata!!
Giuseppe

Bepy93:
Ciao docdoc. GRazie, ma ancora non va..... Li continua a vedere tutti come interruttori.

Allora, visto che questo che mi dici non mi convinceva, sono andato ad analizzare meglio il tuo codice e le librerie e credo di aver trovato il problema.

Nel tuo programma trovavo questa for():

...
void CheckAllButtons(void) {
  if (buttbx.getKeys())
  {
   for (int i=0; i<LIST_MAX; i++)   // <--- QUESTA!
  {
     if ( buttbx.key[i].stateChanged )   
    {
      if ( i != SPECIAL_BUTTON ) {
        // GESTIONE INTERRUTTORI NORMALI
        switch (buttbx.key[i].kstate) {  
  ...

Ora, quel simbolo LIST_MAX pensavo fosse roba tua invece l'ho trovato nella "Keypad.h":

#define LIST_MAX 10		// Max number of keys on the active list.

Quindi vista così sembra che quella libreria gestisca al MASSIMO 10 tasti, ossia da 0 a 9, e dato che il tasto "speciale" lo abbiamo definito il 10, quel "for (int i=0; i<LIST_MAX; i++)" non ci arriverà mai al tasto 10!!!

Prova intanto a mettere:

#define SPECIAL_BUTTON 1

dovrebbe funzionare (ovviamente quello che agirà da pulsante sarà il secondo tasto).

Se funziona, allora devi capire a cosa serve quel simbolo LIST_MAX e se si possa cambiare nella "Keypad.h" per usare più di 10 tasti.