My deej mixer is running on an Arduino Pro Micro, it has 4 faders and 8 macro buttons, one of which doesn’t work, and one other switches between media keys and f-keys modes. The problem that I’m having is that in f-keys mode it just types letters (button 1 is h, button 2 is i, etc.) but all the media keys work fine. I’ve already tried asking chatgpt and I still haven’t been able to get it fixed. I’m still very new to C++ and the Arduino platform in general.
Code:
#include <HID-Project.h> // For media key support
// Slider definitions
const int NUM_SLIDERS = 4;
const int analogInputs[NUM_SLIDERS] = { A0, A1, A2, A3 };
int analogSliderValues[NUM_SLIDERS];
// Button definitions
#define BUTTON_PIN1 3
#define BUTTON_PIN2 10
#define BUTTON_PIN3 6
#define BUTTON_PIN4 16
#define BUTTON_PIN5 7 // Mode toggle button now
#define BUTTON_PIN6 14
#define BUTTON_PIN7 4
#define BUTTON_PIN8 15
const uint8_t NumButtons = 8;
const uint8_t ledPin = 17;
// Toggle button for switching modes
const uint8_t toggleButtonPin = 7; // Changed to Button 5 (Pin 7)
bool mode = 0; // 0 = Function Keys (F13-F20), 1 = Media Control Keys
bool lastToggleState = HIGH;
// Define function keys (F13-F20)
#define BUTTON_KEY1 KEY_F13
#define BUTTON_KEY2 KEY_F14
#define BUTTON_KEY3 KEY_F15
#define BUTTON_KEY4 KEY_F16
#define BUTTON_KEY5 KEY_F17
#define BUTTON_KEY6 KEY_F18
#define BUTTON_KEY7 KEY_F19
#define BUTTON_KEY8 KEY_F20
// Media key definitions (without volume control keys)
const int mediaKeys[8] = {
MEDIA_PLAY_PAUSE,
MEDIA_STOP,
MEDIA_PREVIOUS,
MEDIA_NEXT,
};
// Button helper class for handling press/release and debouncing
class button {
public:
const uint8_t pin;
button(uint8_t p) : pin(p) {}
// Overload the press method to handle both function keys and media keys
void press(boolean state, uint8_t key) {
if (state == pressed || (millis() - lastPressed <= debounceTime)) {
return;
}
lastPressed = millis();
if (state) {
if (key >= KEY_F13 && key <= KEY_F20) {
Keyboard.press(key); // Function keys (F13-F20)
} else {
Consumer.write(key); // Media keys
}
} else {
if (key >= KEY_F13 && key <= KEY_F20) {
Keyboard.release(key); // Release function keys (F13-F20)
} else {
Consumer.write(0); // Release media keys
}
}
pressed = state;
}
void update(uint8_t buttonIndex) {
bool currentState = !digitalRead(pin);
if (mode == 0) {
// Use the correct function key based on the button index
switch (buttonIndex) {
case 0: press(currentState, BUTTON_KEY1); break;
case 1: press(currentState, BUTTON_KEY2); break;
case 2: press(currentState, BUTTON_KEY3); break;
case 3: press(currentState, BUTTON_KEY4); break;
case 4: press(currentState, BUTTON_KEY5); break;
case 5: press(currentState, BUTTON_KEY6); break;
case 6: press(currentState, BUTTON_KEY7); break;
case 7: press(currentState, BUTTON_KEY8); break;
}
} else {
press(currentState, mediaKeys[buttonIndex]); // Media keys
}
}
private:
const unsigned long debounceTime = 30;
unsigned long lastPressed = 0;
boolean pressed = 0;
};
// Button objects, organized in array
button buttons[] = {
button(BUTTON_PIN1),
button(BUTTON_PIN2),
button(BUTTON_PIN3),
button(BUTTON_PIN4),
button(BUTTON_PIN5), // Mode toggle on Button 5 (Pin 7)
button(BUTTON_PIN6),
button(BUTTON_PIN7),
button(BUTTON_PIN8)
};
void setup() {
// Slider setup
for (int i = 0; i < NUM_SLIDERS; i++) {
pinMode(analogInputs[i], INPUT);
}
Serial.begin(9600);
// Safety check. Ground pin #1 (RX) to cancel keyboard inputs.
pinMode(1, INPUT_PULLUP);
if (!digitalRead(1)) {
failsafe();
}
// Set LEDs Off. Active low.
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
TXLED0;
for (int i = 0; i < NumButtons; i++) {
pinMode(buttons[i].pin, INPUT_PULLUP);
}
// Toggle button setup
pinMode(toggleButtonPin, INPUT_PULLUP);
// Start the HID-Project library for media keys
Keyboard.begin();
Consumer.begin();
}
void loop() {
// Check for mode toggle button press (Button 5, Pin 7)
if (digitalRead(toggleButtonPin) == LOW && lastToggleState == HIGH) {
mode = !mode; // Toggle the mode
delay(300); // Debounce delay to avoid toggling too quickly
}
lastToggleState = digitalRead(toggleButtonPin);
// Update and send slider values
updateSliderValues();
sendSliderValues();
// Check the other buttons for keypresses, skipping button 5
for (int i = 0; i < NumButtons; i++) {
// Skip button 5 (toggle button)
if (i != 4) { // Button 5 is at index 4 in the array
buttons[i].update(i);
}
}
delay(10);
}
void updateSliderValues() {
for (int i = 0; i < NUM_SLIDERS; i++) {
analogSliderValues[i] = analogRead(analogInputs[i]);
}
}
void sendSliderValues() {
String builtString = String("");
for (int i = 0; i < NUM_SLIDERS; i++) {
builtString += String((int)analogSliderValues[i]);
if (i < NUM_SLIDERS - 1) {
builtString += String("|");
}
}
Serial.println(builtString);
}
void failsafe() {
for (;;) {} // Just going to hang out here for awhile :D
}
It should be pressing keys f13-f20 when on the macro button mode but just types letters.
Any help is appreciated!