Skip to content

Instantly share code, notes, and snippets.

@Robotto
Created September 24, 2024 09:22
Show Gist options
  • Save Robotto/b8e0b289df59a686979292ca2418d4a2 to your computer and use it in GitHub Desktop.
Save Robotto/b8e0b289df59a686979292ca2418d4a2 to your computer and use it in GitHub Desktop.
ESP32 BLE gamepad with single axis (throttle) - hacked together from examples to this library: https://github.com/lemmingDev/ESP32-BLE-Gamepad/
/*
* Reads a potentiometer on pin 34 and maps the reading to the X axis
*
* Potentiometers can be noisy, so the sketch can take multiple samples to average out the readings
*/
#include <Arduino.h>
#include <BleGamepad.h>
//BleGamepad bleGamepad;
BleGamepad bleGamepad("MARKs ESP32 gamepad", "orksat.me", 100); // Set custom device name, manufacturer and initial battery level
BleGamepadConfiguration bleGamepadConfig; // Create a BleGamepadConfiguration object to store all of the options
const int potPin = 34; // Potentiometer is connected to GPIO 34 (Analog ADC1_CH6)
const int numberOfPotSamples = 5; // Number of pot samples to take (to smooth the values)
const int delayBetweenSamples = 4; // Delay in milliseconds between pot samples
const int delayBetweenHIDReports = 5; // Additional delay in milliseconds between HID reports
void setup()
{
Serial.begin(115200);
Serial.println("Starting BLE work!");
//bleGamepad.begin();
bleGamepadConfig.setAutoReport(true);
bleGamepadConfig.setControllerType(CONTROLLER_TYPE_GAMEPAD); // CONTROLLER_TYPE_JOYSTICK, CONTROLLER_TYPE_GAMEPAD (DEFAULT), CONTROLLER_TYPE_MULTI_AXIS
bleGamepadConfig.setButtonCount(0);
bleGamepadConfig.setHatSwitchCount(0);
bleGamepadConfig.setWhichSpecialButtons(false, false, false, false, false, false, false, false);
bleGamepadConfig.setWhichAxes(false, false, false, false, false, false, false, false);
bleGamepadConfig.setIncludeThrottle(true);
bleGamepadConfig.setVid(0xe502);
bleGamepadConfig.setPid(0xabcd);
bleGamepadConfig.setModelNumber("1.0");
bleGamepadConfig.setSoftwareRevision("Software Rev 1");
bleGamepadConfig.setSerialNumber("24404972");
bleGamepadConfig.setFirmwareRevision("2.0");
bleGamepadConfig.setHardwareRevision("0.1");
// Some non-Windows operating systems and web based gamepad testers don't like min axis set below 0, so 0 is set by default
//bleGamepadConfig.setAxesMin(0x8001); // -32767 --> int16_t - 16 bit signed integer - Can be in decimal or hexadecimal
bleGamepadConfig.setAxesMin(0x0000); // 0 --> int16_t - 16 bit signed integer - Can be in decimal or hexadecimal
bleGamepadConfig.setAxesMax(0x7FFF); // 32767 --> int16_t - 16 bit signed integer - Can be in decimal or hexadecimal
bleGamepad.begin(&bleGamepadConfig); // Begin gamepad with configuration options
}
void loop()
{
if (bleGamepad.isConnected())
{
int potValues[numberOfPotSamples]; // Array to store pot readings
int potValue = 0; // Variable to store calculated pot reading average
// Populate readings
for (int i = 0; i < numberOfPotSamples; i++)
{
potValues[i] = analogRead(potPin);
potValue += potValues[i];
delay(delayBetweenSamples);
}
// Calculate the average
potValue = potValue / numberOfPotSamples;
// Map analog reading from 0 ~ 4095 to 32737 ~ 0 for use as an axis reading
int adjustedValue = map(potValue, 0, 4095, 32737, 0);
// Update throttle axis and auto-send report
bleGamepad.setThrottle(adjustedValue);
delay(delayBetweenHIDReports);
// The code below (apart from the 2 closing braces) is for pot value degugging, and can be removed
// Print readings to serial port
Serial.print("Sent: ");
Serial.print(adjustedValue);
Serial.print("\tRaw Avg: ");
Serial.print(potValue);
Serial.print("\tRaw: {");
// Iterate through raw pot values, printing them to the serial port
for (int i = 0; i < numberOfPotSamples; i++)
{
Serial.print(potValues[i]);
// Format the values into a comma seperated list
if (i == numberOfPotSamples - 1)
{
Serial.println("}");
}
else
{
Serial.print(", ");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment