#include <Arduino.h>
#include <BleGamepad.h>
// botones
struct ButtonADC
{
int pin;
int buttonBLE;
uint16_t state;
uint16_t lastState;
unsigned long lastDebounceTime;
String name1;
String name2;
};
struct ButtonDig
{
int pin;
int buttonBLE;
bool state;
bool lastState;
unsigned long lastDebounceTime;
String name;
};
ButtonADC buttonsADC[] = {
{14, 0, 0, 0, 0, "ButtonL1", "ButtonL2"},
{12, 2, 0, 0, 0, "ButtonL3", "ButtonL2"},
{13, 4, 0, 0, 0, "ButtonM1", "ButtonM2"},
{0, 6, 0, 0, 0, "ButtonR1", "ButtonR2"},
{4, 8, 0, 0, 0, "ButtonR3", "ButtonR4"}};
ButtonDig buttonsDg[] = {
{16, 10, false, false, 0, "JoystickL"},
{17, 11, false, false, 0, "JoystickR"}};
const int numButtonsADC = sizeof(buttonsADC) / sizeof(buttonsADC[0]);
const int numButtonsDg = sizeof(buttonsDg) / sizeof(buttonsDg[0]);
const int debounceDelay = 10;
// potenciometros
const int potPins[] = {35, 27, 34}; // Array para los pines de los potenciómetros
const int numPots = sizeof(potPins) / sizeof(potPins[0]);
int potValue1 = 2048;
int potValue2 = 2048;
int potValueRotation = 2048;
// Joysticks
const int joy1Ver = 33; // Pin analógico para la vertical del primer joystick
const int joy1Hor = 32; // Pin analógico para la horizontal del primer joystick
const int joy2Ver = 26; // Pin analógico para la vertical del segundo joystick
const int joy2Hor = 25; // Pin analógico para la horizontal del segundo joystick
int joyValVer1 = 2048;
int joyValHor1 = 2048;
int joyValVer2 = 2048;
int joyValHor2 = 2048;
// bluetooth
const int ledPin = 15;
unsigned long previousMillis = 0;
const long interval = 500; // Intervalo de parpadeo (1 segundo)
bool ledState = false;
// controllador
BleGamepad bleGamepad("ESP32 Volante", "Mi Marca", 100);
void setup()
{
Serial.begin(115200);
bleGamepad.begin();
// Buttons
for (int i = 0; i < numButtonsADC; i++)
{
pinMode(buttonsADC[i].pin, INPUT);
buttonsADC[i].state = 0;
buttonsADC[i].lastState = 0;
}
// Joysticks buttons
for (int i = 0; i < numButtonsDg; i++)
{
pinMode(buttonsDg[i].pin, INPUT_PULLUP);
buttonsDg[i].state = digitalRead(buttonsDg[i].pin);
buttonsDg[i].lastState = buttonsDg[i].state;
}
// Potenciometros y Joysticks Potenciometros
for (int i = 0; i < numPots; i++)
{
pinMode(potPins[i], INPUT);
}
// led
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
}
float mapFloat(int value, int fromLow, int fromHigh, float toLow, float toHigh)
{
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
void readAndPrintPot(int &lastValue, int pin, const char *label)
{
int currentValue = analogRead(pin);
if (currentValue != lastValue)
{
lastValue = currentValue;
float mappedValue = mapFloat(currentValue, 0, 4095, 0.0, 360.0);
Serial.print(label);
Serial.print(": ");
Serial.print(mappedValue);
Serial.print(" (Raw: ");
Serial.print(currentValue);
Serial.println(")");
}
}
void readAndPrintJoystick(int &lastVer, int &lastHor, int verPin, int horPin, const char *label)
{
int currentVer = analogRead(verPin);
int currentHor = analogRead(horPin);
if (currentVer != lastVer || currentHor != lastHor)
{
Serial.print(label);
if (currentVer != lastVer)
{
lastVer = currentVer;
}
Serial.print(" Vertical: ");
Serial.print(lastVer);
if (currentHor != lastHor)
{
lastHor = currentHor;
}
Serial.print(" Horizontal: ");
Serial.println(lastHor);
}
}
void updateButtonState(ButtonDig &button, unsigned long currentMillis)
{
bool reading = digitalRead(button.pin);
if (reading != button.lastState)
{
button.lastDebounceTime = currentMillis;
}
if ((currentMillis - button.lastDebounceTime) > debounceDelay)
{
if (reading != button.state)
{
button.state = reading;
if (button.state == LOW)
{
Serial.print("Button ");
Serial.print(button.name);
Serial.println(" pressed");
bleGamepad.press(button.buttonBLE);
}
else
{
bleGamepad.release(button.buttonBLE);
}
}
}
button.lastState = reading;
}
uint16_t whichButtonGivenVoltage(int voltage)
{
if (voltage <= 10) // ninguno
{
return 0;
}
else if (voltage < 1400)
{
return 1;
}
else if (voltage < 2200)
{
return 2;
}
else
{
return 3;
}
}
void updateButtonStateAnalog(ButtonADC &button, unsigned long currentMillis)
{
Serial1.print("Button: ");
Serial.print(analogRead(button.pin));
Serial.print(" ");
Serial1.println(whichButtonGivenVoltage(analogRead(button.pin)));
int reading = whichButtonGivenVoltage(analogRead(button.pin));
if (reading != button.lastState)
{
button.lastDebounceTime = currentMillis;
}
if ((currentMillis - button.lastDebounceTime) > debounceDelay)
{
if (reading != button.state)
{
button.state = reading;
if (button.state == 1)
{
Serial.print("Button ");
Serial.print(button.name1);
Serial.println(" pressed");
bleGamepad.press(button.buttonBLE);
bleGamepad.release(button.buttonBLE + 1);
}
else if (button.state == 2)
{
Serial.print("Button ");
Serial.print(button.name2);
Serial.println(" pressed");
bleGamepad.press(button.buttonBLE + 1);
bleGamepad.release(button.buttonBLE);
}
else if (button.state == 3)
{
Serial.print("Button ");
Serial.print(button.name1);
Serial.println(" pressed");
bleGamepad.press(button.buttonBLE);
Serial.print("Button ");
Serial.print(button.name2);
Serial.println(" pressed");
bleGamepad.press(button.buttonBLE + 1);
}
else
{
bleGamepad.release(button.buttonBLE);
bleGamepad.release(button.buttonBLE + 1);
}
}
}
button.lastState = reading;
}
void loop()
{
unsigned long currentMillis = millis();
// bluetooth
if (!bleGamepad.isConnected())
{
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(ledPin, ledState ? HIGH : LOW);
}
}
else
{
digitalWrite(ledPin, HIGH);
for (int i = 0; i < numButtonsADC; i++)
{
updateButtonStateAnalog(buttonsADC[i], currentMillis);
}
// Buttons Dig
for (int i = 0; i < numButtonsDg; i++)
{
updateButtonState(buttonsDg[i], currentMillis);
}
// Potenciometros
readAndPrintPot(potValue1, potPins[0], "Potenciómetro 1");
readAndPrintPot(potValue2, potPins[1], "Potenciómetro 2");
readAndPrintPot(potValueRotation, potPins[2], "Potenciómetro Rotacion Volante");
bleGamepad.setLeftTrigger(potValue1 / 16);
bleGamepad.setRightTrigger(potValue2 / 16);
int mappedRotation = map(potValueRotation, 0, 4095, -127, 127);
bleGamepad.setZ(mappedRotation);
// Joysticks
readAndPrintJoystick(joyValVer1, joyValHor1, joy1Ver, joy1Hor, "Joystick 1");
readAndPrintJoystick(joyValVer2, joyValHor2, joy2Ver, joy2Hor, "Joystick 2");
bleGamepad.setLeftThumb(joyValHor1 / 16, joyValVer1 / 16);
bleGamepad.setRightThumb(joyValHor2 / 16, joyValVer2 / 16);
bleGamepad.sendReport();
}
delay(10);
}