Pro-micro multi-function controls (WIP)

General GBZ-related chat goes here. Share ideas, tips and tricks, or ask questions that don't fit into the hardware/software help forums.
Post Reply
User avatar
fraggle
Posts: 50
Joined: Mon Mar 06, 2017 2:28 pm
Has thanked: 18 times
Been thanked: 16 times

Pro-micro multi-function controls (WIP)

Post by fraggle » Tue Apr 25, 2017 10:07 am

Hi,

I've been tinkering with a third GBZ (even though my second isn't finished :)) - really because I had all the parts and I wanted to test the super cheap pro-micro clones I got. In doing this I've written quite a nice little program for handling multiple input modes - accessed by long-pressing a tactile "function button" placed in the GB power input hole (credit to Macx). This button itself has multiple functions based on click, double-click and long-press via the OneButton library.

Pressing the function button once sends RETURN double clicking sends ESCAPE and long pressing steps through the control modes, gamepad, keyboard, alternate, etc.

My rational for doing this is to support both gamepad and keyboards modes - extra keyboards etc that may have one off requirements can easily be added.

Anyhow here is the code/hardware I have put together in testing, hopefully it should be fairly self explanatory.
Really I thought I'd share to see what others think and because the code at least may be of use to others.

...one idea I had was to also make the start and select buttons "OneButtons" too - so that they also have double-click, etc.

Software:

Code: Select all

#include <OneButton.h>
#include <Keyboard.h>
#include <Bounce2.h>
#include <Gamepad.h>

#define A 10
#define B 16
#define X 8
#define Y 9
#define START 14
#define SELECT 15
#define UP 20
#define DOWN 19
#define RIGHT 18
#define LEFT 21
#define R1 2
#define R2 3
#define L1 4
#define L2 5
#define FN 1

const int pins[] = { A, B, X, Y, START, SELECT, UP, DOWN, LEFT, RIGHT, L1, L2, R1, R2 };
const char keys1[] = { 'a', 'b', 'x', 'y', '1', '5', KEY_UP_ARROW, KEY_DOWN_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_F1, KEY_F2, KEY_F11, KEY_F12 };
const char keys2[] = { 'p', 'l', 'o', 'k', 'v', 'b', 'w', 's', 'a', 'd', 'q', 'e', KEY_F5, KEY_F11 };
enum Mode { pad = 0, keyboard, keyboard2, _END };

const int NUM_PINS = sizeof(pins) / sizeof(int);
struct Button { int number; Bounce* bounce; };
Gamepad gamepad;
Button buttons[NUM_PINS];
OneButton fnButton(FN, true);
Mode mode = pad;

void setup() {
  fnButton.attachClick([]() { Keyboard.write(KEY_RETURN); });
  fnButton.attachDoubleClick([]() { Keyboard.write(KEY_ESC); });
  fnButton.attachLongPressStart([]() { mode = (mode < _END - 1) ? mode + 1 : pad; });
  for (int i = 0; i < NUM_PINS; i++, buttons[i]) {
    pinMode(pins[i], INPUT_PULLUP);
    Button *e = new Button;
    e->number = i;
    e->bounce = new Bounce(pins[i], 10);
    buttons[i] = *e;
  }
}

void loop() {
  fnButton.tick();
  for (int i = 0; i < NUM_PINS; i++) {
    buttons[i].bounce->update();
    int change = !buttons[i].bounce->read();
    switch (mode) {
      case pad: gamepad.setButtonState(buttons[i].number, change); break;
      case keyboard: if (change) Keyboard.write(keys1[i]); break;
      case keyboard2: if (change) Keyboard.write(keys2[i]); break;
    }
  }
}
Hardware photos
20170425_163659.jpg
20170425_163659.jpg (380.03 KiB) Viewed 2019 times
20170425_163440.jpg
20170425_163440.jpg (474.79 KiB) Viewed 2019 times
20170425_163056.jpg
20170425_163056.jpg (446.97 KiB) Viewed 2019 times

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest