Engineer
UNITED STATES OF AMERICA • + Follow
Edit Project
Tools, APP Software Used etc.
![]() |
Autodesk Fusion 360Autodesk
|
|
![]() |
KiCADKicad
|
Description
Wireless Bike Media Controller
I wanted an easy way to control my music while biking without having to look at my phone. This project solves that issue. This wireless device features a rotary encoder for volume and a mute button, plus three keys for previous track, play/pause, and next track. It also has a LiPo battery so no cables are needed. Just attach the bottom plate to the handlebar mount which fits your handlebars and you won't have to worry about looking down to switch songs!
Controls
- Left Button: Previous Track
- Center Button: Play/Pause
- Right Button: Next Track
- Knob CW: Volume Down
- Knob CCW: Volume Up
- Knob Button: Mute/Unmute
Hardware
- Seeed Studio XIAO ESP32C3
- 3x MX Switches
- 5x 10k Ohm Resistors
- Rotary Encoder
- 3.7v LiPo Battery
- 4x M3 x 6mm Screws
- 4x M3 heat set inserts
Code
Arduino Code for Seeed XIAO ESP32C3
C/C++
#include <BleKeyboard.h> #include <RotaryEncoder.h> const int button1Pin = 5; const int button2Pin = 6; const int button3Pin = 7; const int encoderAPin = 4; const int encoderBPin = 3; const int encoderSwitchPin = 2; bool button1Pressed = false; bool button2Pressed = false; bool button3Pressed = false; bool encoderSwitchPressed = false; BleKeyboard bleKeyboard; RotaryEncoder encoder(encoderAPin, encoderBPin, RotaryEncoder::LatchMode::TWO03); void setup() { Serial.begin(9600); pinMode(button1Pin, INPUT_PULLUP); pinMode(button2Pin, INPUT_PULLUP); pinMode(button3Pin, INPUT_PULLUP); pinMode(encoderAPin, INPUT_PULLUP); pinMode(encoderBPin, INPUT_PULLUP); pinMode(encoderSwitchPin, INPUT_PULLUP); bleKeyboard.begin(); } void loop() { // Check button inputs if (digitalRead(button1Pin) == LOW && !button1Pressed) { button1Pressed = true; Serial.write("Prev\n"); bleKeyboard.press(KEY_MEDIA_PREVIOUS_TRACK); } else if (digitalRead(button1Pin) == HIGH && button1Pressed) { button1Pressed = false; bleKeyboard.release(KEY_MEDIA_PREVIOUS_TRACK); } if (digitalRead(button2Pin) == LOW && !button2Pressed) { button2Pressed = true; Serial.write("Play/Pause\n"); bleKeyboard.press(KEY_MEDIA_PLAY_PAUSE); } else if (digitalRead(button2Pin) == HIGH && button2Pressed) { button2Pressed = false; bleKeyboard.release(KEY_MEDIA_PLAY_PAUSE); } if (digitalRead(button3Pin) == LOW && !button3Pressed) { button3Pressed = true; Serial.write("Next\n"); bleKeyboard.press(KEY_MEDIA_NEXT_TRACK); } else if (digitalRead(button3Pin) == HIGH && button3Pressed) { button3Pressed = false; bleKeyboard.release(KEY_MEDIA_NEXT_TRACK); } if (digitalRead(encoderSwitchPin) == LOW && !encoderSwitchPressed) { encoderSwitchPressed = true; Serial.write("Mute\n"); bleKeyboard.press(KEY_MEDIA_MUTE); } else if (digitalRead(encoderSwitchPin) == HIGH && encoderSwitchPressed) { encoderSwitchPressed = false; bleKeyboard.release(KEY_MEDIA_MUTE); } // Check encoder rotation static int pos = 0; encoder.tick(); int newPos = encoder.getPosition(); if (pos != newPos) { int dir = (-1) * (int)(encoder.getDirection()); if (dir > 0) { bleKeyboard.press(KEY_MEDIA_VOLUME_UP); delay(200); // Increase this delay for larger moves bleKeyboard.release(KEY_MEDIA_VOLUME_UP); Serial.write("Volume Up\n"); } else { bleKeyboard.press(KEY_MEDIA_VOLUME_DOWN); delay(200); // Increase this delay for larger moves bleKeyboard.release(KEY_MEDIA_VOLUME_DOWN); Serial.write("Volume Down\n"); } pos = newPos; } }
Schematic and Layout
Schematic: OPTIONAL: Connect Lipo Battery to Battery +/- on the back of the Seeed Studio XIAO with a switch to interrupt power.
BMC Schematic.png

CAD-Custom parts and enclosures
Dec 14,2023
742 views
end-flag
Wireless Bike Media Controller
Control your music and keep your eyes on the road with this handlebar mounted bluetooth media controller.
742
2
2
Published: Dec 14,2023
Purchase
Donation Received ($)
PCBWay Donate 10% cost To Author
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
Copy this HTML into your page to embed a link to order this shared project
Copy
Under the
Attribution-NonCommercial (CC BY-NC)
License.
VOTING
0 votes
- 0 USER VOTES
0.00
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Design
1/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Usability
2/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Creativity
3/4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Content
4/4
More by Engineer
You may also like
-
-
Instrumentation Input, high impedance with 16 bit 1MSPS ADC for SPI
274 0 0 -
RGB LED Matrix input module for the Framework Laptop 16
459 0 2 -
-
📦 StackBox: Modular MDF Storage Solution 📦
284 0 2 -
-
It should work with both, but I have only tested it with android.