$50 ESP32-S3 Knob Roon Controller

I fixed the flash instructions and uploaded my local build of the ESP32 firmware.

I still haven’t merged the wifi debugging instructions, just need to test them some more locally and I’ll roll them into 1.3.1

I’m still not entirely following but I flashed what looks like the new artifact (it’s a different size than the previous) and there’s no change in behavior. On the dial, the version still reads v1.2.12.

I’m using this little scriplet to monitor:

while ! ls /dev/tty.usbmodem* >/dev/null 2>&1; do
  sleep 0.1
done
python3 -m serial.tools.miniterm "$(ls /dev/tty.usbmodem* | head -n 1)" 115200

With this, I can have the device powered off, run it, power the device on. When I do this, and I go through the captive flow, I can see from the output that even though I’ve provided an ssid and password, no attempt to actually connect to my network appears to be made.

I see you just updated the release notes with flashing instructions. I’m still confused by the “flip the usb-c cable” thing. Is that actually how usb-c works? But I also don’t understand where esp32_bt.bin is supposed to come from. Your workflow isn’t propping it. Even if you do prop it, if it’s a bluetooth specific thing, it seems unlikely to be the source of my issue.

I’m just curious - with the current bin, can you start with a completely reset dial, go through captive the captive portal flow, and have the dial connect to your WiFi? To me, it looks like the values I set in the captive flow aren’t being persisted and used.

It’s persisting for me to NV storage. I need to document how to wipe that so I can test fully.

Got it. Well… you now know that I know how to flash, and I know how to monitor whatever is output to serial. If you put a build together with additional instrumentation, I’m happy to try it and to send you what I see.

On the off chance that this is relevant - I have the version of the device with a battery. Hard to imagine that it’s causing this issue but, just in case, now you know :slight_smile:

I know, that tripped me up too. From the wiki:

Question: Why can’t the program be flashed?
Answer:

  • Plug the Type-C into the port in a different direction and try
  • Switch between ESP32 or ESP32S3 through Type-C access in different directions

As for the other firmware, it’s from the source code in the esp32_bt/ folder. The ESP32-S3 Only implemented BLE and I wanted BT for AVRCP, so added it.

And you’re right, it’s not related to your Wifi connectivity issue, that chip isn’t involved at all in that. I’ve added better wifi debugging + logs so we can see if that helps. Testing that shortly.

1 Like

Much appreciated! I am glad you were the first user.

1 Like

Thanks for all the detailed debugging, gTunes! Your serial logs were great -

I (151433) captive_portal: Credentials saved, switching to STA mode in 2 seconds…

But the current code says:
Credentials saved, rebooting in 2 seconds…

The firmware tried to switch WiFi modes (from AP to a client) on-the-fly instead of rebooting. That was failing. Now: after saving credentials, the firmware reboots which should apply the new WiFi config.

v1.3.2 has:

  • The reboot-after-config fix
  • Detailed WiFi status messages (wrong password, network not found, auth timeout)
  • Version displayed correctly (it was hardcoded to 1.2.12, doh!)

To test:

  1. Download roon_knob.bin and flash
  2. Run your serial monitor
  3. Display should show v1.3.2 and “Connect to WiFi: roon-knob-setup”
  4. After captive portal, you should see “Rebooting…” (not “switching to STA mode”)
  5. After reboot, watch for WiFi connection attempts with detailed status

WiFi should work now, :crossed_fingers: but if not hopefully the messages tell us what’s happening.

On the bridge pairing, another great find. It wasn’t persisting! PR #8 (just merged) fixes that - it now saves to /data/config.json. Thank you!

1 Like

Excellent!
I’m out for the evening, but I’ll give this a try tomorrow. Thanks for looking at this!

Unfortunately, still not working. PM sent with a log.

An update for folks on the forum.

@Muness was kind enough to work with me until we’d solved the initial configuration issues. I now have this controller up and running and the fixes he did along the way should make getting it set up pretty straightforward for everyone else.

This is a really, really promising controller - great display, works great for volume, allows choosing the zone to control, supports play/pause, previous, and next.

This is a great addition to the community. Thanks, @Muness!

2 Likes

Hi @Muness,

This controller option looks great! I gave it a shot and got one. Flashed the latest firmwares (v1.3.10), roon_knob.bin and esp32_bt.bin but the knob doesn’t seem to start.
I’m new to ESP boards but I have good technical knowledge. I must be doing something wrong.
I’m using Windows to flash the firmwares and will probably try through a Linux distro tomorrow.

Below is my command prompt with output following flashing of roon_knob.bin:

C:\Downloads\ESP_KNOB>esptool --chip esp32s3 -p COM5 write-flash 0x0 roon_knob.bin
esptool v5.1.0
Connected to ESP32-S3 on COM5:
Chip type:          ESP32-S3 (QFN56) (revision v0.2)
Features:           Wi-Fi, BT 5 (LE), Dual Core + LP Core, 240MHz, Embedded PSRAM 8MB (AP_3v3)
Crystal frequency:  40MHz
USB mode:           USB-Serial/JTAG
MAC:                d0:##:##:##:##:##

Stub flasher running.

Configuring flash size...
Flash will be erased from 0x00000000 to 0x001e0fff...
Wrote 1966304 bytes (1031315 compressed) at 0x00000000 in 19.1 seconds (821.9 kbit/s).
Hash of data verified.

Hard resetting via RTS pin...

Any thoughts?
Thanks in advance for the help!

Hi Guy - I haven’t tried Windows to flash. If you have access to Linux, please let me know how that goes.

I’ve been meaning to get Windows on one of my Mele Quieter mini PCs (I got a batch on ebay for streamers but haven’t needed them): will try to get it done over the holidays so I can try it there too.

1 Like

Hi, @Guy_Maurier.

Did the device start before you flashed it? @Muness bought a used device that didn’t have the original firmware. Mine came from the manufacturer with the default firmware and did start before I flashed Muness’.

On Windows, you might try using the Windows Subsystem for Linux if that’s easier than trying a Linux distro.

I flashed using a Mac. I never had an issue flashing, but we did run into issues that benefitted from monitoring the device’s serial output during startup. This is a bash script I wrote (well, ChatGPT wrote) that you can run before turning the device on. It waits for the device and then monitors. It may work as is in WSL or you may have to figure out and set the right port (uses a wildcard currently). Personally, I’d give this a shot before doing anything else.

I have it in a file called “monitor.sh” so it’s easy to run.

Hope you figure this out.

#!/usr/bin/env bash

BAUD=115200

echo "🔎 Waiting for ESP32-S3 serial port..."

while true; do
  PORT=$(ls /dev/tty.usbmodem* 2>/dev/null | head -n 1)
  if [[ -n "$PORT" ]]; then
    echo "📟 Connecting to $PORT @ $BAUD baud"
    exec python3 -m serial.tools.miniterm "$PORT" "$BAUD" --raw
  fi
  sleep 0.2
done
2 Likes

Hey Guy - if @gTunes 's suggestion of using WSL doesn’t work, can you try out the new getting started doc to see if it’s any help? roon-knob/docs/GETTING_STARTED.md at master · muness/roon-knob · GitHub

2 Likes

Hey @Muness, @gTunes,

Thank you both for your replies, much appreciated!
The Knob came with Wareshare’s demo application and is working fine. I reflashed it back (https://www.waveshare.com/wiki/ESP32-S3-Knob-Touch-LCD-1.8) using the same process on Windows and the knob starts with the demo once the firmware has been successfully transferred. Transferring roon_knob.bin again, nothing happens on the knob.

@Muness, I checked the new getting started doc. The one difference that I noted is the parameter 0x0 versus 0x10000 . Seems to be a memory allocation but I’m not sure about its impact. It didn’t make any difference.

Hey @Muness, @gTunes,

I’ve found the issue. I’ve completed the setup on Linux but going through Windows should not be an issue. When I first attempted the flash, I used the command with address 0x0 (from old documentation) instead of 0x10000, which had the effect of overwriting the bootloader (0x0) and partition table (0x8000) with the roon_knob.bin firmware, which includes only the application. Address 0x10000 is meant for the application only.

Running the below command gave me insight into what was happening when the device was booting:

python3 -m serial.tools.miniterm /dev/ttyACM0 115200 --raw

With the error:

Invalid image block, can’t boot.

I re-flashed with the stock Waveshare firmware (which restored the bootloader and partition table), then flashed roon_knob.bin again at address 0x10000, which solved the problem (I noticed you’ve updated the info on the main page).

Suggestion: It would help if the release included the bootloader and partition table files, or provided a merged firmware image that can be flashed at 0x0. This would eliminate the dependency on having Waveshare’s stock firmware installed first.

I’ll start playing with the device now :slight_smile:

2 Likes

Well done figuring this out!

2 Likes

Hi @Muness, @gTunes,

Now that the firmware is running, as well as the docker Bridge, the Knob is not getting connected to the Bridge. I’m gettingNo bridge URL message in the settings when clicking Test Bridge.
The Bridge connected to my Roon server; in the logs I see it updated with all available zones and their status.
I see this line in the logs:
[2025-12-19T02:34:07.173Z][Sidecar][INFO] Listening on 8088 {"roon_service_port":9330,"base":"http://muness-roon-extension-knob1:8088"}

What does the reference to the two different ports mean?
In the Getting Started documentation, under the Troubleshooting section, it mentions the ability to enter the bridge URL manually (long-press the zone name on the knob to access Settings) but I can’t find this option.

Thanks for the help!

1 Like

Awesome progress @Guy_Maurier !

You should be able to set the bridge by connecting to the knob at http://knob_ip

in DM @gTunes has shared feedback this isn’t discoverable, will see what I can do to improve it. it’s a shame mdns discovery is unreliable ,

1 Like

Roon uses the service port, you probably don’t have to worry about it . The 8088 is the one we use to connect to the bridge from the knob or users from a browser .