Go Down

Topic: Button BOX (Read 352 times) previous topic - next topic

mariyo

Hola comunidad, este es mi primer post y mi primera experiencia con arduino, así que mil disculpas desde ya por los conceptos errados que voy a tener y las boludeces que voy a decir.

Como muchos en la cuarentena aproveché el tiempo muerto para darle vida a un proyecto que tenía hace mucho en mente que era construir una botonera. Empece el año pasado a comprar los pulsadores y a investigar como se hacía y hace poco encontré el tiempo para llevarla adelante.

Siguiendo éste video fue como lo llevé adelante.

Usé un Arduino Pro Micro al igual que en el video, pero en vez de usar 4 encoders con pulsador usé 3. Mi lógica fue que al usar un encoder menos podría agregar más botones a la botonera. Acá fue donde surgió el problema, me encontré (por lo que leí en alguna página en inglés) que windows limita a 32 botones los joystick y mi aparato es de 42 (una matriz de 6x6, dentro de la matriz están los 3 pulsadores de los encoders, más las 6 pulsaciones que me dan los encoders).

El aparato funciona con un código modificado por mí en el que por supuesto no entiendo nada que hice y sólo usé lógica.

Code: [Select]
//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 3
#define NUMBUTTONS 36
#define NUMROWS 6
#define NUMCOLS 6


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,32,33,34,35},
};

struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;
};

rotariesdef rotaries[NUMROTARIES] {
  {0,1,36,37,0},
  {2,3,38,39,0},
  {4,5,40,41,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,14};
byte colPins[NUMCOLS] = {16,10,9,8,7,6};

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

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_JOYSTICK, 42, 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);
    };
  }
}


Hice algunas modificaciones locas en el código pero dejaban de funcionar botones o los encoders y no sabía si era por mala programación o por el límite este de windows.

Mi pregunta es la siguiente... Puedo dividir la botonera en 2 y emular dos joysticks al conectarla? Me encantaría que funcionaran los 42 botones porque ya está construida, sinó la limitaré a 32 y me armaré otra más adelante de 10.

Muchas gracias a los que se tomaron el tiempo de leer todo esto.

mariyo

Bueno, parece que no se puede emular 2 joystick con la placa para poder usar todos los botones.

Al seguir el tutorial conecté la matriz de 6 (A3, A3, A1, A0, 15, 14) x 6 (16, 10, 9, 8, 7, 6) y el primer encoder a TX y RX, el segundo a 2 y 3, y el tercero a 4 y 5.

Con esta configuración puedo pasar de joystick a keyboard y asignarle macros a los botones? Sobre todo a la rotación de los encoders.

Y si alguien me puede orientar un poco, porque la realidad es que armé todo pensando en usarlo como joystick y no entiendo del tema como para pasarlo solo a teclado.

Muchas gracias.

surbyte

Quote
Mi lógica fue que al usar un encoder menos podría agregar más botones a la botonera.
Mi primero comentario es : porque no compras un enconder mas y sigues al pie de la letra el video?
Si no entiendes que hace para que lo modificas?

Ahora en tu código hay algunas discrepancias con lo que yo hubiera hecho
ttable usa definiciones del tipo [6][4] = 24 y [7][4] = 32
Code: [Select]
#define NUMBUTTONS 24
y tu tienes 3 encoders y no 4 asi que tus tablas debieran ser distintas no te parece?
Code: [Select]
#define NUMBUTTONS 36

Como armar esas tables no lo sé en este momento porque no he mirado detenidamente la lógica que usa el autor.
Solo me parece que hay una discrepancia entre tu enfoque y el código que usas.


mariyo

Mi primero comentario es : porque no compras un enconder mas y sigues al pie de la letra el video?
Realmente porque estaba interesado en adaptarlo a mis necesidades y no a las del autor original. De hecho con 2 encoders me alcanzaba.

Si no entiendes que hace para que lo modificas?
Para aprender! Sino todavía le seguiría pidiendo a mis padres que me corten la comida :)

Lo de las tablas tienes razón, no lo había captado al momento de hacer al post porque como comenté soy totalmente novato en esto, es mi primer proyecto.

Igualmente se podría decir que he solucionado el tema, terminé haciéndolo un teclado y he logrado hacer funcionar los 36 botones y los 3 encoders correctamente.
De momento no ha dado problemas en las pruebas que he hecho, mañana veré ya que lo utilizaré en vivo realmente. El fin de la botonera era crear un "switch" de video para transmisiones online y poder manejar tanto los cambios de camaras, transiciones y disparar zocalos como la tituladora.

surbyte

Bueno me alegro que lo resolvieras.

Corresponde mas allá que no pude ayudarte mucho que pongas como lo resolviste mas que nada a nivel de software porque si alguien se interesa.
Interesante la aplicación con el SIMCAR. No la conocía.

Go Up