ESP32 UNO - DIYables Bluetooth App Rotator
Overview
Turn your phone into a wireless dial for the ESP32 Uno with the Bluetooth rotator app. You drag a disc on the screen, and the ESP32 Uno form board gets the angle as a number from 0 to 360 degrees. Use that knob angle to point a servo, set a stepper position or change a volume level. The board can link by BLE (Android and iPhone) or by Classic Bluetooth (Android).
By the end, you can:
- Install the DIYables Bluetooth library in Arduino IDE
- Flash a BLE or a Classic Bluetooth rotator sketch to the board
- Link the phone app and read each knob angle in the Serial Monitor
- Switch between a free 360° spin and a fixed angle window
- Drive a servo, a PWM output or a stepper driver from the angle

※ NOTE THAT:
The ESP32 Uno chip carries two Bluetooth radios: BLE and Classic. BLE is the pick when an iPhone must connect, and it needs no pairing step. Classic Bluetooth runs on Android phones only and asks you to pair in the phone settings first.
What the Rotator App Gives You
Use this table to see what the app does for you and what your sketch still handles.
| Feature | Details |
|---|---|
| On-screen disc | You touch it and drag it in a circle, like a real knob |
| Free spin mode | ROTATOR_MODE_CONTINUOUS goes all the way to 360° and wraps to 0° |
| Window mode | ROTATOR_MODE_LIMITED keeps the angle between a min and a max, such as 0° to 180° |
| Angle data | A float value reaches the board each time the disc moves |
| Two-way sync | The board can push an angle back, so the disc shows the real position |
| Radio choice | BLE for Android and iOS, Classic Bluetooth for Android only |
| Power | BLE uses less current than Classic Bluetooth |
Components You Need
| 1 | × | ESP32 Uno-form Board | |
| 1 | × | USB Cable Type-A to Type-C (for USB-A PC) | |
| 1 | × | USB Cable Type-C to Type-C (for USB-C PC) | |
| 1 | × | (optional) Servo Motor | |
| 1 | × | Breadboard | |
| 1 | × | Jumper Wires |
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Buy Note: For controlling multiple servo motors, use the PCA9685 16 Channel PWM Servo Driver Module to save MCU pins and simplify wiring.
ESP32 Uno Pinout
Your sketch never uses the printed Uno labels. It uses the GPIO number behind each label, so look it up on this map before you add a servo or a driver.

Good to know: the main rotator sketch needs no wires. The optional servo signal goes to D9 (GPIO13), so SERVO_PIN in the code is 13.
| Servo Wire | ESP32 Uno Pin |
|---|---|
| Red (VCC) | 5V |
| Brown (GND) | GND |
| Orange (Signal) | D9 (GPIO13) |
Upload and Test the ESP32 Uno Code
At the end of this part, the board shows up on your phone and every knob move prints a new angle.
Step 1 — Prepare Arduino IDE
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above. For the first run, you can leave every pin free.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Give Bluetooth more flash: in the menu bar, go to Tools > Partition Scheme and choose Huge APP (3MB No OTA/1MB SPIFFS). The normal layout keeps only about 1.2 MB for your program.
- Find the book-shaped Libraries icon in the left toolbar and click it.
- Type "DIYables Bluetooth" in the search box and find the entry by DIYables.
- Press Install.
- Search for DIYables Bluetooth created by DIYables and click the Install button.
- Add the helper libraries: a dialog lists more packages. Press Install All.
Now upload ONE of the sketches below. They show the same knob. Only the radio type differs.
Step 2 — Option A: ESP32 Uno Classic Bluetooth Sketch (Android only)
Good to know: an iPhone cannot see a Classic Bluetooth device. iOS users go to Option B.
- Open the example: File Examples DIYables Bluetooth Esp32Bluetooth_Rotator, or paste the code below into an empty sketch.
- Flash it: click the arrow-shaped Upload button.
- Start the Serial Monitor at 115200 baud. After a reset it prints:
Step 2 — Option B: ESP32 Uno BLE Sketch (Android and iOS)
- Open the example: File Examples DIYables Bluetooth Esp32BLE_Rotator, or paste the code below.
- Upload it.
- Start the Serial Monitor at 115200 baud:
- Pro tip: the Classic sketch already holds the servo lines as comments. Delete the // marks in front of them after you install ESP32Servo, and the servo follows the knob with no other change.
Step 3 — Connect the Phone App
When this step is done, the knob on your phone talks to the board.
- Classic sketch only — pair first: on the Android phone open Settings > Bluetooth, switch it on, tap "ESP32_Rotator", accept (no PIN), and wait until "Paired" shows. With the BLE sketch, skip this.
- Start the app and allow the access it asks for on first launch:
- Nearby Devices (Android 12 or newer) or Bluetooth (iOS) — needed to find and join devices
- Location (Android 11 or older) — old Android needs it for a BLE scan

- Choose your board: "ESP32_Rotator" for Classic, or "ESP32BLE_Rotator" for BLE. After the link is up, the app jumps back to the home screen.
- Open the knob: tap Rotator in the app menu.

- Turn it: drag the disc around with one finger.

- Pro tip: the gear icon on the home screen hides the apps you do not need. Every screen is covered in the DIYables Bluetooth App User Manual.
Look at the Serial Monitor again. The link message and each new angle appear there:
How the Sketch Works
Here is the job of each part in the ESP32 Uno rotator sketch.
| Code Part | What It Does |
|---|---|
| DIYables_Esp32BLE or DIYables_Esp32Bluetooth | Starts the radio under the name the phone lists |
| DIYables_BluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180) | Creates the knob and holds it inside 0° to 180° |
| addApp(&bluetoothRotator) | Puts the Rotator screen on the Bluetooth server |
| setOnConnected() | Sends the last known angle as soon as a phone links |
| onRotatorAngle() | Runs each time the disc moves and stores the new angle |
| bluetoothServer.loop() | Handles incoming data, so call it often in loop() |
The result is a knob that always opens at the right position and reports every move at once.
ESP32 Uno vs UNO R4 for This Project
Moving this rotator from the UNO R4 WiFi to the ESP32 Uno swaps the radio library and the servo library, and adds a second Bluetooth mode.
| Item | Arduino UNO R4 WiFi | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| Bluetooth | BLE only | BLE and Classic Bluetooth |
| Library platform file | DIYables_ArduinoBLE.h | DIYables_Esp32BLE.h or DIYables_Esp32Bluetooth.h |
| Servo library | Servo.h | ESP32Servo.h |
| Servo signal pin | D9 | D9 (GPIO13) |
| Arduino IDE board | Arduino UNO R4 WiFi | ESP32 Dev Module with Huge APP partition |
The servo stays on the same D9 header spot, so the wiring does not move. The 3.3V signal out of the board drives most hobby servos fine. Just never send a 5V signal back into an ESP32 Uno pin.
Shape the Knob for Your Project
At the end of this part, the knob behaves the way your build needs.
Pick a Mode
The mode is set by the constructor. A call to setRotatorMode() swaps it at run time, and three getters report what is active.
React to a New Angle
Put your own action inside onRotatorAngle(). The app calls it for every move of the disc.
Reply When the App Asks for the State
The app may request the current state when the Rotator screen opens. Answer with the stored angle.
Move the Disc from the Board
The ESP32 Uno can turn the disc on the phone by itself, or send a short text.
Watch Link Events
These two callbacks fire when a phone joins or leaves. Pushing the angle on join keeps both sides equal.
Reading the Knob Screen
Use this table to know each part of the Rotator screen.
| Screen Part | Meaning |
|---|---|
| Round disc | Drag it in a circle to set the angle |
| Number in the center | The angle the app sends right now |
| Marker on the edge | Points at the current position |
| Mode value 0 | ROTATOR_MODE_CONTINUOUS, a full turn that wraps back to 0° |
| Mode value 1 | ROTATOR_MODE_LIMITED, the angle stops at the min and max |
Real Output Examples
Each block below is a part of a sketch. Add it to the full BLE or Classic example from above.
Example 1 — Servo on D9
Window mode from 0° to 180° fits a hobby servo, so the angle goes straight to write(). First add "ESP32Servo" (author Kevin Harrington) from Library Manager, because the classic Servo library will not compile for the ESP32 Uno. Wire the servo as shown in the pinout section: signal to D9 (GPIO13), red to 5V, brown to GND.
For a pan-tilt head, put the second (tilt) servo on D10 (GPIO5) and drive it from another control, for example a Bluetooth slider.
WARNING
The chip checks D10 (GPIO5) at power-up to decide how to boot. A servo signal wire there is normally fine, but if the board will not start or upload with the tilt servo attached, unplug that signal wire during upload and plug it back in after.
Example 2 — Brightness or Volume Dial on D5
The knob spins freely here. The code turns 0–360° into a PWM duty of 0–255 and also prints a percentage. Wire an LED with a 220Ω resistor, or any PWM input, to D5 (GPIO16).
Example 3 — Compass Needle on the Phone
Now data goes from the board to the phone. Every 500 ms the board reads a heading and turns the disc to match. A compass talks over I2C. On this board that bus lives on the SDA (GPIO21) and SCL (GPIO22) header pins, while A4/A5 are plain analog inputs.
Example 4 — Stepper Driver on D5 and D4
A STEP/DIR driver such as an A4988 can follow the knob. The code changes the angle into a step target for a 200-step motor, and stepper.run() moves it there. Wire STEP to D5 (GPIO16) and DIR to D4 (GPIO17).
Smarter Angle Handling
Snap to 15° Steps
The code rounds each angle to the closest multiple of 15° and sends it back, so the disc clicks into neat spots.
Four Zones, Four Colors
Split the circle into quarters and run a different action in each. Here each quarter gives an RGB LED a new color. Write a setColor() function that fits your LED.
Choosing BLE or Classic on the ESP32 Uno
The ESP32 Uno runs both sketches. Pick by phone type and power need.
| Point | BLE (Esp32BLE_Rotator) | Classic (Esp32Bluetooth_Rotator) |
|---|---|---|
| iPhone | Works | Not possible |
| Android | Works | Works |
| Current draw | Lower | Higher |
| Pairing in phone settings | Not needed | Needed once |
| Name in the scan list | ESP32BLE_Rotator | ESP32_Rotator |
| Good fit | Battery builds, mixed phones | Android-only builds |
Debug Helper
Call this function inside onRotatorAngle() while you test. It prints the angle, the mode and the window in one block.
Build Ideas
| Area | Ideas |
|---|---|
| Motion | Servo pointer, stepper angle picker, motor speed dial, robot arm joint |
| Display | Compass heading, clock hands, wind vane, dial gauge |
| Sound | Volume knob, tone pitch picker, equalizer band, radio tuner |
| Light | LED ring spot, hue color wheel, spotlight aim, stage light tilt |
Mix the Rotator with Other Bluetooth Apps
Rotator Plus Slider
The rotator gives the direction and a slider gives the speed. Sine and cosine of the angle, scaled by the speed, give the X and Y drive for a pair of motors.
Rotator Plus Table
Show the angle, its quarter and its value in radians as rows on the phone.
Try These Next
With the knob working, keep going with these ESP32 Uno pages:
- ESP32 Uno - Bluetooth Joystick — steer in two directions at once
- ESP32 Uno - Bluetooth Slider — set a value along a straight bar
- ESP32 Uno - Bluetooth Analog Gauge — show a reading on a needle dial
- ESP32 Uno - Multiple Bluetooth Apps — run the knob next to other screens
Where to Get Help
- The API reference that comes with the DIYables Bluetooth library
- More app guides at diyables.io/bluetooth-app
- The Arduino community forums
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears in Arduino IDE | CH340 driver missing or a charge-only cable | Install the CH340 driver and use a USB Type-C cable that carries data |
| Upload stops at "Failed to connect" or "Waiting for download" | The board did not enter download mode | Hold the BOOT button while the upload starts, then let go |
| Board does not boot or upload with the tilt servo on D10 | D10 (GPIO5) is a boot strapping pin pulled the wrong way | Unplug the module while uploading, or use another pin |
| Compiler says the sketch is too big | Default partition has no room for Bluetooth | Choose Tools > Partition Scheme > Huge APP (3MB No OTA/1MB SPIFFS) |
| Board name is missing in the app scan | Sketch not running, phone Bluetooth off, or Classic not paired | Check the Serial Monitor shows "Waiting for Bluetooth connection...", pair ESP32_Rotator first for Classic, and turn on Location on Android 11 or older |
| ESP32_Rotator never shows on an iPhone | iOS has no Classic Bluetooth | Upload the BLE sketch and pick ESP32BLE_Rotator |
| Compile error about Servo.h | The standard Servo library has no support for this chip | Install ESP32Servo and use the line #include |
| Servo shakes or the board resets when it moves | Servo draws too much current from the 5V pin | Power the servo from a separate 5V supply, join the grounds, and add a 100µF capacitor across its power wires |
| Angle stops at 180° | The knob is in window mode | Use ROTATOR_MODE_CONTINUOUS or raise the max with setRotatorMode() |
| Serial Monitor prints garbled symbols | Baud rate in the monitor does not match the sketch | Pick 115200 in the drop-down at the bottom of the monitor |
FAQ
BLE or Classic Bluetooth — which sketch fits my ESP32 Uno rotator build?
Load the BLE sketch if anyone uses an iPhone or if you want to skip pairing. Load the Classic sketch if all users have Android phones. The knob and the Serial Monitor output are the same in both.
Is the angle a whole number or a decimal?
It is a float, so you get decimals such as 63.25°. A servo only takes whole degrees, so the examples cast it with (int)angle. Keep the float when you need fine steps, for example for a stepper.
Can the board turn the knob on the phone by itself?
Yes. Call bluetoothRotator.send(angle) with any value, and the disc moves to it. The compass example uses this to show a live heading.
Why does the servo code use ESP32Servo and not Servo.h?
The standard Servo library has no timer code for the ESP32 Uno chip, so it does not compile. ESP32Servo by Kevin Harrington gives the same attach() and write() calls. Your servo logic stays the same.
Can a 5V servo run from the ESP32 Uno?
Yes. Feed the servo from the 5V pin or an outside 5V supply, and connect its signal to D9 (GPIO13). The 3.3V pulse is enough for most hobby servos. A big or loaded servo needs its own supply with a shared ground.
Do I need a driver to upload to the ESP32 Uno?
The board talks to the computer through a CH340 USB-to-serial chip. Some Windows and macOS computers need the CH340 driver before the COM port shows. Install it once, then plug the cable in again.
Can I keep my old UNO R4 rotator sketch?
Not as it is. The UNO R4 WiFi sketch includes DIYables_ArduinoBLE.h. On the ESP32 Uno, include DIYables_Esp32BLE.h (or DIYables_Esp32Bluetooth.h for Classic) and set the baud rate to 115200. The rotator calls themselves do not change.
Can I put a second servo on D10 for a pan-tilt head?
You can, and D10 maps to GPIO5. That pin is a boot strapping pin, so a strong pull on it at power-up can stop the boot. A servo signal is usually fine. If the board hangs, unplug the signal during reset or upload.
Will an Uno servo shield fit the ESP32 Uno?
The header shape is the same, so the shield fits. Check that the shield does not push 5V into a signal pin, and that it does not need A4/A5 for I2C, because on this board I2C is on the SDA (GPIO21) and SCL (GPIO22) pins.
My rotator build needs more pins than the Uno headers give. What can I use?
The ESP32 Uno has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they still read while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder a pin header into the hole and use its GPIO number in code. For an extra servo or a stepper DIR line, GPIO32 or GPIO33 is the best choice. Two warnings apply. First, GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Second, never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11), because they go to the flash chip and using them crashes the board.
Can I turn the same servo from a web page instead?
Yes. The ESP32 Uno also has WiFi. The ESP32 Uno - Web Rotator page draws the same kind of knob in a browser and moves a servo with it.