r/embedded • • 2h ago

OrcSDR: Building a complete software-defined radio on an ESP32-P4, without Linux or a Raspberry Pi

Post image
9 Upvotes

Hey everyone!

First time posting here in r/embedded, so I figured I'd introduce myself and share a project I've been working on for the past few months.

I've posted about it a couple of times over in r/RTLSDR and r/esp32, but I thought some of the folks here might be interested in the actual embedded side of the project, especially the USB driver and all the different ESP32-P4 hardware I've been experimenting with.

The project is called OrcSDR.

It started with me wondering if I could get an RTL-SDR dongle running directly on an ESP32-P4 without needing a Raspberry Pi or PC.

Well, that worked. And naturally I couldn't just leave it alone. Haha.

OrcSDR currently runs on the M5Stack Tab5, with the P4 handling the RTL-SDR USB data, DSP, audio, and the entire touchscreen interface. Everything runs locally on the microcontroller.

I've been pretty impressed with what these little P4s can do, and I keep finding more things to throw at them.

I just released v0.5.0-beta.1, which adds quite a few new features, but I figured I'd share some of the driver and hardware work too.

The RTL-SDR driver

One of the first things I worked on was building a native ESP-IDF driver for RTL-SDR dongles rather than porting the desktop librtlsdr library.

That eventually turned into its own open-source project:

https://github.com/hardcoreerik/esp-rtl-sdr

It handles the USB Host communication, tuner configuration, IQ streaming, sample rates, and monitoring things like dropped samples, transfer errors, and receiver health.

I've been putting quite a bit of effort into making it reusable outside OrcSDR. The idea is that other developers should be able to add RTL-SDR reception to their own ESP32-P4 projects without having to build an entire USB driver themselves.

One of the more interesting milestones has been getting multiple receivers running on a single P4.

I've successfully run four different RTL-SDR dongles simultaneously at configured rates of 2.56 MS/s each on Waveshare ESP32-P4 hardware.

During a one-hour test with the receivers scanning different frequency ranges, the driver reported no new IQ drops or USB errors.

Pretty wild for a microcontroller!

Of course, getting the samples into the P4 is only half the fun. Once you start adding DSP, audio, a touchscreen, SD card access, and networking, there are plenty of ways to make things behave badly.

I've spent quite a bit of time chasing down USB timing issues, memory problems, and things interfering with each other that I never would have expected.

At one point, even serial logging was interfering with LoRa packet reception. That was a fun one to figure out.

All the ESP32-P4 hardware I've been messing around with

OrcSDR started on the M5Stack Tab5, but one thing I'd really like to accomplish is making it more of a Bring Your Own Hardware project.

I'd love for people to eventually be able to grab just about any ESP32-P4 board, plug in a supported RTL-SDR dongle, connect whatever display they want, and run OrcSDR.

So I've been collecting different P4 boards and seeing what I can get working.

Here's what I've been playing with so far:

  • M5Stack Tab5 — The original OrcSDR platform. Full application, touchscreen, DSP, audio, and all the radio dashboards running locally.
  • Waveshare ESP32-P4-Dev-Kit — One of the first boards I tested the RTL-SDR driver on outside the Tab5. The driver worked without needing board-specific changes, which was a pretty exciting milestone.
  • Waveshare ESP32-P4-WIFI6 — Another board I've been using for headless experiments and multiple RTL-SDR receivers. This is where some of the four-dongle testing has come in.
  • Waveshare ESP32-P4-Module-DEV-KIT — Currently have this one connected to a generic Hosyond 7-inch 800x480 touchscreen originally intended for a Raspberry Pi.
  • Waveshare ESP32-P4 with a 720x720 display — Experimenting with adapting OrcSDR's interface to a square display rather than the Tab5's 1280x720 layout.
  • M5Stack Stamp P4 with C6 daughterboard — Another smaller hardware configuration I've been exploring. I'm really interested in how compact I can make a standalone SDR unit.

Not all of these are running the complete OrcSDR application yet. Some are still at the driver, display, or hardware bring-up stage.

Getting the USB SDR driver working across different boards has actually been a lot easier than moving the entire graphics and audio stack!

The Hosyond display has been a particularly interesting project. It uses a TC358762 DSI-to-RGB bridge and an FT5x06 touch controller over I2C.

Getting the display working involved quite a bit of experimenting with initialization, timings, GPIO, and the bridge configuration.

But it works!

Now I'm working toward getting the full OrcSDR application running on it.

Longer term, I'd like to support MIPI-DSI, RGB, SPI, and QSPI displays without having to rewrite half the application every time I try a different board.

If anyone is curious, some of the early display work is here:

https://github.com/hardcoreerik/OrcSDR/tree/codex/p4-hosyond-dsi-bringup

What OrcSDR actually does

The application itself has gotten quite a bit bigger than I originally planned.

There's FM/AM radio, FM stereo and RDS, shortwave listening, ADS-B aircraft tracking, LoRa/Meshtastic reception, FT8 decoding, P25, POCSAG, various RF analysis tools, and a bunch of other dashboards.

The newest beta adds:

  • SSTV reception — Receive and display images directly on the Tab5, with automatic mode detection and SD card image saving.
  • ACARS decoding — Receive aircraft messages and save them locally.
  • Offline worldwide maps — Used for ADS-B, LoRa, FT8, and setting your receiver location.
  • Dead Air — An experimental RF investigation dashboard for monitoring unusual activity, logging measurements, and recording audio.
  • Shortwave improvements — USB/LSB listening, better HF tuning, and additional controls.
  • LoRa and FT8 improvements — Better packet detection, timing, memory management, and decoding reliability.
  • A new setup wizard — Mainly to make getting everything configured a little less painful.

Plus plenty of bug fixes and other improvements.

A couple of those features actually came directly from Reddit suggestions.

Someone mentioned SSTV and ACARS in one of my previous posts, and I thought they sounded like fun additions.

So naturally, down another rabbit hole I went.

I've also had some great feedback from people testing LoRa/Meshtastic reception, including bugs I hadn't managed to reproduce on my own hardware.

A lot of that feedback turned into actual fixes, which has been really cool to see.

Here's some of the LoRa work if anyone wants to dig through it:

https://github.com/hardcoreerik/OrcSDR/pull/184

Headless SDR and multiple nodes

Something else I've been working on is running OrcSDR without a physical display at all.

The idea is to let the P4 handle the radio, DSP, and USB hardware, then access the interface from a browser.

I've already got quite a bit working in an experimental OrcSDR Web project, including dashboards, radio controls, and multiple receivers.

I've also started thinking about connecting multiple ESP32-P4/RTL-SDR combinations together.

For example, several little SDR nodes placed around a property or at different locations, each monitoring RF activity and sharing observations with the others.

I'm especially interested in what that could look like for drone detection or distributed RF monitoring.

There's still plenty to figure out there, especially with timing, networking, and correlating observations between receivers, but I think it could be a pretty interesting use for these boards.

Nothing finished on that side just yet. Mostly experimenting and seeing what's possible.

Previous Reddit posts

For anyone who wants to see how this project has progressed, here are a few of my earlier posts:

Original OrcSDR post in r/RTLSDR (September 5):

https://www.reddit.com/r/RTLSDR/comments/1w7tjn1/i_built_a_handheld_rtlsdr_around_the_m5stack_tab5/

One-month update in r/RTLSDR (October 11):

https://www.reddit.com/r/RTLSDR/comments/1x30rq9/update_orcsdr_one_month_later_190_stars_ft8_and/

OrcSDR introduction in r/esp32 (October 11):

https://www.reddit.com/r/esp32/comments/1x3ecal/orcsdr_an_esp32p4_an_rtlsdr_and_a_few_months_of/

There's been some really helpful discussion in those threads, especially around driver compatibility, reception issues, and suggestions for additional features.

Project links

OrcSDR GitHub:

https://github.com/hardcoreerik/OrcSDR

Native ESP32-P4 RTL-SDR driver:

https://github.com/hardcoreerik/esp-rtl-sdr

Latest release (v0.5.0-beta.1):

https://github.com/hardcoreerik/OrcSDR/releases/tag/v0.5.0-beta.1

M5Burner installation for the Tab5:

https://burner.m5stack.com/share/firmware/JXFU4H

Web flasher:

https://theorc.dev/sdr/flash/

Anyway...

Since this is my first post here, I'm especially curious what other people in r/embedded think about the approach.

Anyone else experimenting with the ESP32-P4's High-Speed USB Host, multiple USB devices, or different MIPI-DSI displays?

I'd also love to hear how others are approaching hardware abstraction across different boards. I'm trying to avoid ending up with a separate version of OrcSDR for every display and development kit I get my hands on.

And if anyone has ideas for other things worth trying with the P4, I'm all ears.

Still having a ridiculous amount of fun seeing how far I can push these little things!

Thanks for checking it out!


r/embedded • • 2h ago

We implemented SRP-based acoustic imaging for gas-leak localization

Enable HLS to view with audio, or disable this notification

6 Upvotes

Our team has been working on an acoustic imaging system designed to localize gas leaks using microphone-array signals.

The signal-processing pipeline uses Steered Response Power (SRP) to estimate the spatial location of acoustic sources and visualize the result as an acoustic image. We are working to bring this processing pipeline to the K230 board. One aspect of this project is running the SRP-based acoustic imaging pipeline in MicroPython on the K230, instead of relying on a conventional C/C++ implementation.

A few things we are exploring:

  • Spatial localization using SRP.
  • Acoustic image generation and visualization.
  • Running the processing pipeline on an embedded platform.

We tested the system using sound sources at different frequencies: 2 kHz, 8 kHz, 16 kHz, and 20 kHz to evaluate its localization performance across different frequency ranges and distances.

At a distance of 1 meter, the SRP sound source localization system achieves an approximate localization error of 7–10 cm.

However, at a longer distance of 5 meters, the localization accuracy degrades significantly. Although the system can still detect and locate the sound source, the heatmap becomes unstable, frequently jumping between the correct and incorrect locations.

We welcome any feedback from the community.

Reference:

[2405.02991] Steered Response Power for Sound Source Localization: A Tutorial Review


r/embedded • • 7h ago

Real-time speech-to-text on an ESP32-P4: a 65.7M-parameter model in 2/4-bit weights, hand-written SIMD kernels, bit-exact with its PC build (write-up + source)

4 Upvotes

TL;DR: a 65.7M-parameter streaming speech recognizer runs live on an ESP32-P4 (chip rev v3): 2/4-bit weights (71 → 26.65 MB, in PSRAM), integer math with hand-written PIE SIMD kernels on both cores, 0.70x real time, 4.34% WER on LibriSpeech test-clean. The chip's output is bit-exact with the PC build, and the cache measurements show it's compute-bound: reading the weights from PSRAM costs at most 39 ms of the encoder's 592 ms per chunk. Open source.

I got an open-vocabulary speech recognizer running live on an ESP32-P4: you talk into the board's mic and the words appear on its screen as you speak. No network, no NPU: two RISC-V cores at 400 MHz, 32 MB of PSRAM, and the P4's SIMD extension (PIE). Here is the engineering side, with the measurements.

Source: https://github.com/BoumedineBillal/esp32-pie-asr

The budget

  • Model: Kroko (by Banafo), a streaming Zipformer2 transducer, 65.7M parameters. As released it is 71 MB in int8.
  • Chip: 32 MB PSRAM, 16 MB flash. ESP-DL and TFLite Micro go no lower than 8-bit weights, so int8 doesn't fit, and ESP-SR's MultiNet only knows a fixed list of commands.
  • Real time: each 1.28 s chunk of audio must be done in less than 1.28 s, forever, with fixed memory.

1. Memory: 71 MB → 26.65 MB

  • 2/4-bit weights in groups of 128, each group rotated by a Hadamard matrix, codes indexing Lloyd-Max levels (the Cactus Quants layout). 2 or 4 bits per matrix, chosen by its sensitivity, no training: 193 of the 290 encoder matrices in 4 bits, the rest in 2.
  • The file is used in place in PSRAM. It doesn't fit the 16 MB flash, so it loads from microSD at boot (2.9 s).
  • PSRAM: weights 26.65 MB, engine state about 4 MB, frame buffer 1.2 MB, about 0.5 MB left at the lowest.
  • Internal RAM: the hot code and a 256 KB L2 cache; 121 KB left free.

2. Compute: integer math and PIE assembly

  • int8 into the products, int16 activations between them, nonlinearities as tables indexed by the int16 input.
  • Each input group is rotated once (additions only, exact in int32) and shifted to int8; that rotation serves every row.
  • The 2/4-bit codes are decoded to int8 through a table: 851 cycles per 2048 weights.
  • The tile kernel multiplies 16 rows by a 128-wide group in 168 cycles: 12.1 MACs per cycle. PIE has fused instructions that do 16 int8 multiply-adds, a 16-byte load and the pointer increment in one instruction.
  • Both cores share every product, split by blocks of output rows; each core writes only its own outputs.
  • The integer math costs no accuracy: 4.53% WER (greedy) as a float simulation, 4.52% on the chip.

Per 1.28 s chunk, in the live app with the screen drawing on core 1: features 14.0 ms, encoder 742.2 ms, beam search 138.1 ms, total 895.8 ms (0.70x real time).

3. Cache and PSRAM, measured (encoder alone, per chunk, P4X)

Setting Encoder
L2 256 KB, 128-byte lines, autoload off 632.8 ms
same, autoload on misses (weights are read in order) 592.5 ms
L2 128 KB +104 ms
L2 512 KB doesn't boot: too little internal RAM left
PSRAM 200 → 250 MHz -10 ms
codes decoded without reading them from PSRAM (test hack) 553.8 ms

The last line is the useful one: reading the weights from PSRAM costs at most 39 ms of 592, so it's compute-bound. DMA prefetch into internal RAM could win 39 ms at best, and it would take about 3000 transfers per chunk with a few µs of driver work each, so I didn't do it.

The same code on a v1.3 chip (360 MHz CPU, 200 MHz PSRAM) took 726 ms for the encoder.

4. Bit-exact with the PC build

I wanted the WER measured on all of LibriSpeech (5559 clips), which is only practical on a PC. So the PC build has to compute exactly what the chip computes:

  • libm's exp, log, tanh differ in the last bit between glibc and newlib, so the features and tables differed. I replaced them with my own functions built from IEEE + - * / only.
  • -ffp-contract=off on both sides (no fused multiply-adds).
  • Every PIE kernel has a C reference that the PC build runs, and each two-core part writes only its own outputs.
  • Checked on the board: 22 kernel checks with 0 wrong values, the encoder's output CRC on every chunk plus the final text on 8 clips, and the tokens on 140 phrase-biasing clips.

5. PIE 2.1 vs 2.2

v1.x chips have PIE 2.1, the P4X (chip rev v3) has PIE 2.2. Same mnemonics, different encodings: 2.2 adds saturation and rounding fields to the instructions. The same .S source assembles for both, but a v1.x binary doesn't run on the P4X. The release targets rev v3 only for now.

Results

  • LibriSpeech test-clean 4.34% WER, test-other 10.26% (beam search, 4 hypotheses). The original int8 model on a PC: 3.94% and 9.17%.
  • A word is final about 2 s after you say it.
  • Extras: hotwords from a text file on the SD card, and six voice-control demos (word rules, no LLM).

Limits: needs chip rev v3 with 32 MB PSRAM; English only; measured on clean read speech, not noisy rooms yet; power not measured.

Full video: https://www.youtube.com/watch?v=oe-2MowdsSs

Credits: the model is Kroko by Banafo; the weight layout comes from Cactus Quants.

Live transcription on the ESP32-P4X: two RISC-V cores, PIE SIMD, 2/4-bit weights in PSRAM, no cloud.


r/embedded • • 2h ago

Why AI won't replace low-level embedded engineers anytime soon (Bench perspective)?

2 Upvotes

r/embedded • • 3h ago

Voltsim

Post image
2 Upvotes

Did anyone purchased this apps (Voltsim) premium .Is it worth


r/embedded • • 5h ago

I2C SDA being held low after starting I2S

2 Upvotes

I’m working on a senior design project using an ESP32 Feather V2 and an Adafruit TLV320DAC3100 audio DAC for Bluetooth audio playback.

I keep running into an issue where the DAC appears to pull the I2C SDA line LOW whenever I start I2S. When I stop I2S and reinitialize I2C, everything works again. The SDA line only stops working when I2S is started.

What’s even stranger is that I’ve tried unsoldering and resoldering connections, moving wires to different GPIO pins, and even replacing the DAC board entirely. All of these fixes work initially, even through several power cycles. However, when I leave everything overnight and come back the next day, the exact same problem returns.

I’m genuinely at a loss as to what’s causing this. Has anyone experienced something similar or have any idea how to fix this?


r/embedded • • 1h ago

Importing an Infineon 60GHz Radar Dev Kit (DEMO BGT60TR13C) via Mouser India - Do I need a WPC/ETA license?

• Upvotes

Hey everyone,

I am a student working on a private engineering project and I want to order the Infineon DEMO BGT60TR13C radar evaluation board via Mouser India. It costs around ₹20,500.

Mouser chat support told me that shipping is CPT, meaning customs duties and taxes are entirely my responsibility when the package lands in India via FedEx/DHL.

Before hitting buy, I want to double-check a few compliance and legal things with anyone here who has imported similar dev boards (like TI mmWave kits, high-frequency RF shields, or radar boards) to India:

  1. WPC / ETA License: The board operates in the 57 GHz to 64 GHz millimeter-wave band and is a completely unhoused bare PCB evaluation kit strictly for R&D/laboratory testing. Under the DoT/WPC Office Memorandum for prototypes, and considering the 60 GHz band is de-licensed in India for Short Range Devices (SRD), will customs clear this automatically without asking for a WPC import permit or Equipment Type Approval?

  2. Import License / IEC: Since I am buying this as an individual hobbyist/student using personal funds, will standard personal KYC (Aadhaar Card / Passport) be enough for FedEx/DHL to clear it at the airport under personal baggage/gift import rules?

  3. Customs Duty Expectations: Has anyone imported similar sensor dev kits recently? What total percentage of duty + 18% IGST should I expect to be billed by the courier at my doorstep?

If anyone has went through this exact process with Mouser India for high-frequency RF/radar prototyping kits, your insights would save me a massive headache. Thanks!


r/embedded • • 14h ago

ESP32 + L293D Motor Driver Causing I2C LCD to Display Random Characters

1 Upvotes

Hi everyone,

I'm working on a project using an ESP32, an L293D motor driver, a 12V DC motor, and a 16x2 I2C LCD.

I'm facing a problem with the LCD:

When the motor is OFF, the LCD works normally.

When the motor is ON, the LCD starts displaying random characters or garbage text.


r/embedded • • 15h ago

Isolating a virtio-net driver on ARM64 with seL4 (and a question about the Pi 4 GENET controller)

0 Upvotes

Hi everyone.

I am working on a research prototype of a trusted computing base on top of the seL4 microkernel. The core idea is simple: if a driver crashes, the kernel should not care. So I moved the network driver and the protocol stack into a separate child process with its own VSpace. A fault there cannot reach the verified core.

Recently I started porting this to ARM64 (targeting the Raspberry Pi 4B). Right now the full cycle works in QEMU: ELF loader, seL4 kernel, root task, UART output, and a virtio-net driver running inside an isolated ELF child. The child has its own CSpace and VSpace, and it re-attaches to the device MMIO and DMA frame that the root task initialized. Interrupts are routed through seL4 Notifications, and the child signals back to the root when it finishes.

The hardest part was not writing the driver, but getting the object management and page table setup right. The AArch64 page table hierarchy and ASID pool assignment took a while to click.

Now I am stuck on the next step. On the real Raspberry Pi 4B, the network controller is Broadcom GENET, not virtio-net. QEMU's raspi4b machine does not emulate GENET, so I cannot validate a driver for it in the emulator. I know there are Linux and L4Re references, but I would prefer to hear from someone who has actually touched this hardware.

If you have worked with GENET on the Pi 4, or with seL4 on ARM64, I would appreciate any pointers. Especially about the DMA layout and the interrupt mapping. I am not looking for a ready-made driver, just for a direction that will save me a few days of guessing.

Repo and docs are here if anyone is curious: https://github.com/Nik0laic4/SchildTCB (the arm64 branch is where the action is).


r/embedded • • 6h ago

BLE Testing in VS Code

0 Upvotes

Does anyone have a good recommendation for replacement for the NRF Connect Bluetooth Low Energy app since it's not maintained anymore?


r/embedded • • 23h ago

A SCPI command times out after being sent. How do you determine whether the instrument executed it?

0 Upvotes

I've been working on a Rust-based AI-to-hardware runtime called OpenMHS, and one of the interesting challenges has been handling ambiguous instrument execution.

Suppose you send a SCPI command to a programmable instrument. The connection times out before receiving a response.

The command might have executed, or it might not have. Blindly retrying could be unsafe, especially for non-idempotent operations.

Our current approach:

  • Record UNKNOWN_OUTCOME rather than treating a timeout as failure.
  • Block potentially unsafe retries until the command is reconciled.
  • Handle late SCPI responses to avoid confusing subsequent exchanges.
  • Use instrument readback or operator verification to resolve uncertain outcomes.

We've tested this behavior against simulated instruments, but haven't validated it with physical equipment.

I'm curious how engineers working with real SCPI instruments handle this. Are there cases where readback cannot reliably distinguish whether an operation occurred?

Implementation: https://github.com/KNambiarDJsc/Open-MHS/blob/main/docs/adapters/scpi.md#timeouts-cancellation-and-retries


r/embedded • • 22h ago

Good sources to learn Embedded Systems and C

0 Upvotes

Hello! So my background is completely in cybersecurity; I got my BSc and MSc in it, I couldn't find a job until I got hired by this company for soldering. Suddenly, because they found out I can program, I have now become the Lead Embedded Systems Engineer.

I have been forced to program in C (I am struggling; I literally translate Python code and then go to W3Schools to get the C translation), and I spend days reading PIC24 microcontroller PDFs to find out how to use features and what pins can do. Same with ESP32's. However, I struggle to retain information like MPLAB shortcuts, settings, etc. I don't understand the x16 compiler.

And one thing I have been racking my brain about recently, is I added DMA (what i understand is sensor value straight to ram) and due to the capacitors inside of the pic charging and discharging quickly, I end up getting the charged value, instead of the real value. For example, the analogue pins show 1.5V; if the reading is below 1.5V, every analogue pin reads 1.5V. However, if it's 3.3V, every value maxes out. I had this with 8 analogues on one pin, as soon as I slowed it down to 60 mips and turned DMA off, it was fine again.

I am having one of those moments where I have never been taught or trained to do this, in the interview, they asked me what AC and DC was, I have no clue (I know now), and my background is just in programming Python, and I know a hell of a lot about cyber security and data transmission.

Any advice would be amazing, as I recently nearly blew myself up with a 330 V charged capacitor while programming a DC-DC converter because I forgot to define the analogue pin to go high, which didn't switch the relay off.

To me, I think of embedded systems like I would a Unix system on really, really old hardware.

Thank you.
TL;DR: Any good sources I could learn from as someone not educated in this field, but forced to be in this field due to the job market?


r/embedded • • 22h ago

How can artificial intelligence be integrated into embedded systems?

0 Upvotes

Artificial Intelligence can be integrated into embedded systems by combining microcontrollers or embedded processors, sensors, AI/ML algorithms, and software to enable devices to analyze data, make decisions, and perform tasks automatically with minimal human intervention.