Hello, I have a few gamepads/flightsticks I made a few years back using Pro Micro's to help me physically plays games and I wanted to add/or make them bluetooth. Finding out now that's a lot easier said than done I've opted to grab some new boards ProMicro nRF52840's. that resemble the ones that I already use, size wise and the same pins to just swap boards without adding things and/or causing me to redesign the cad models and print them again. Now I've managed to get all of them functioning with buttons but I can't get any of them to read analog inputs from joysticks. (Hall effect joycon stick and basic analog)
Using one as a example/starting point. I have a one-handed, 15 button, 1 joystick gamepad I use ALOT as 2 hands are not a option.. all 15 buttons function as intend but I can not get analog readings from my joystick (x, y). I'm reaching out to anyone with experience to help finish the code on this one in particular as it would help with my other 13 custom HID's as its the same issue with all.
#include <Adafruit_TinyUSB.h>
/*********************************************************************
Single Handed Gamepad, 15 Buttons, 1 Joystick
********************************************************************/
#include <bluefruit.h>
#include <Bounce2.h> //button debounce library
BLEDis bledis;
BLEHidGamepad blegamepad;
// define each function and its input pin number comments describe physical switches
#define X_PIN A1 //JOY X
#define Y_PIN A2 //JOY Y
#define BTN1_PIN 0 //Pinky1
#define BTN2_PIN 1 //Pinky2
#define BTN3_PIN 2 //Pinky3
#define BTN4_PIN 3 //Ring4
#define BTN5_PIN 4 //Ring5
#define BTN6_PIN 5 //Ring6
#define BTN7_PIN 6 //Middle7
#define BTN8_PIN 7 //Middle8
#define BTN9_PIN 8 //Middle8
#define BTN10_PIN 9 //Pointer10
#define BTN11_PIN 13 //Pointer11
#define BTN12_PIN 12 //Pointer12
#define BTN13_PIN 11 //Thumb13
#define BTN14_PIN 10 //Menu14
#define BTN15_PIN 16 //Start15
//defining the pin array
uint8_t x = {X_PIN};
uint8_t y = {Y_PIN};
uint8_t myPins[] = {BTN1_PIN, BTN2_PIN, BTN3_PIN, BTN4_PIN, BTN5_PIN, BTN6_PIN, BTN7_PIN,
BTN8_PIN, BTN9_PIN, BTN10_PIN, BTN11_PIN, BTN12_PIN, BTN13_PIN, BTN14_PIN, BTN15_PIN};
//defines the array length
uint8_t pinCount = sizeof(myPins)/sizeof(myPins[0]);
uint8_t unusedPins[] = {};
uint8_t unusedPinCount = 0;
uint8_t lastButtonState[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Bounce * buttons = new Bounce[pinCount]; //start the bounce container
// defined in hid.h from Adafruit_TinyUSB_Arduino
hid_gamepad_report_t gp;
void setup()
{
// LOW POWER MODE!
// Pins default to INPUT mode. To save power, turn them all to OUTPUT
// initially, so only those being used will be turn on. See:
// http://www.pjrc.com/teensy/low_power.html
for (uint8_t pin=0; pin < unusedPinCount; pin++ )
{
pinMode(unusedPins[pin], OUTPUT);
}
// set up pins as input for bounce 2 library and digital read
for (uint8_t i=0; i < pinCount; i++)
{
buttons[i].attach( myPins[i] , INPUT_PULLUP ); //setup the bounce instance for current button
buttons[i].interval(5); // interval in ms
}
Serial.begin(115200);
#if CFG_DEBUG
// Blocking wait for connection when debug mode is enabled via IDE
while ( !Serial ) delay(10);
#endif
Serial.println("ChazronBLE");
Serial.println("------------------------------------\n");
Serial.println("FileName: Chazron.ino");
Serial.println();
Serial.println("Go to your devices's Bluetooth settings to pair your device");
Serial.println("then open an application that accepts gamepad input");
Bluefruit.begin();
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
Bluefruit.setName("Chazron");
// Configure and Start Device Information Service
bledis.setManufacturer("InMyRoom Productions");
bledis.setModel("Chucke Ergo - nRF52840");
bledis.begin();
/* Start BLE HID
* Note: Apple requires BLE device must have min connection interval >= 20m
* ( The smaller the connection interval the faster we could send data).
* However for HID and MIDI device, Apple could accept min connection interval
* up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
* connection interval to 11.25 ms and 15 ms respectively for best performance.
*/
blegamepad.begin();
/* Set connection interval (min, max) to your perferred value.
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
*/
/* Bluefruit.Periph.setConnInterval(9, 12); */
// Set up and start advertising
startAdv();
}
void startAdv(void)
{
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_GAMEPAD);
// Include BLE HID service
Bluefruit.Advertising.addService(blegamepad);
// There is enough room for the dev name in the advertising packet
Bluefruit.Advertising.addName();
/* Start Advertising
* - Enable auto advertising if disconnected
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
* - Timeout for fast mode is 30 seconds
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
*
* For recommended advertising interval
* https://developer.apple.com/library/content/qa/qa1931/_index.html
*/
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
}
void loop()
{
// nothing to do if not connected or
if ( !Bluefruit.connected() ) return;
for (uint8_t i=0; i < pinCount; i++)
{
buttons[i].update();
uint8_t currentButtonState = buttons[i].read(); //Initialize current state of buttons array
if (currentButtonState != lastButtonState[i]) //compare current state to previous state and run proccess to update the gp report
{
gp.buttons = 0; //clears button mask before entering new values for each button
gp.buttons |= !digitalRead(BTN1_PIN) << 0; //assigns current state value to button 1
gp.buttons |= !digitalRead(BTN2_PIN) << 1;
gp.buttons |= !digitalRead(BTN3_PIN) << 2;
gp.buttons |= !digitalRead(BTN4_PIN) << 3;
gp.buttons |= !digitalRead(BTN5_PIN) << 4;
gp.buttons |= !digitalRead(BTN6_PIN) << 5;
gp.buttons |= !digitalRead(BTN7_PIN) << 6;
gp.buttons |= !digitalRead(BTN8_PIN) << 7;
gp.buttons |= !digitalRead(BTN9_PIN) << 8;
gp.buttons |= !digitalRead(BTN10_PIN) << 9;
gp.buttons |= !digitalRead(BTN11_PIN) << 10;
gp.buttons |= !digitalRead(BTN12_PIN) << 11;
gp.buttons |= !digitalRead(BTN13_PIN) << 12;
gp.buttons |= !digitalRead(BTN14_PIN) << 13;
gp.buttons |= !digitalRead(BTN15_PIN) << 14; //assigns current state value to button 15
lastButtonState[i] = currentButtonState;
}
}
blegamepad.report(&gp);
}