The Pi Pico, An SDR Receiver Front End

Making a software defined radio (SDR) receiver is a relatively straightforward process, given the right radio front end electronics and analogue-to-digital converters. Two separate data streams are generated using clocks at a 90 degree phase shift, and these are passed to the software signal processing for demodulation. But what happens if you lack a pair of radio front ends and a suitable clock generator? Along comes [Mordae] with an SDR using only the hardware on a Raspberry Pi Pico. The result is a fascinating piece of lateral thinking, extracting something from the hardware that it was never designed to do.

The onboard RP2040 ADC is of course far too slow for the task, so instead an input is used, with a negative feedback arrangement from another GPIO to form a crude 1-bit ADC. A PIO peripheral is then used to perform the quadrature mixing, resulting in the requisite pair of data streams. At this point these are sent over USB to GNU Radio for demodulating, mainly for convenience rather than necessarily because the microcontroller lacks the power.

The result is a working SDR front end, demonstrated pulling in an FM broadcast station. The Pico has to be overclocked to reach that frequency and it’s more than a little noisy, but we’re extremely impressed with how much has been done with so little. Oddly it isn’t the first Pico SDR we’ve seen, but the previous one was a much more conventional and lower-frequency affair for the European Long Wave band.

22 thoughts on “The Pi Pico, An SDR Receiver Front End

      1. If you read the article correctly, the author specifies that this is feasible with the RP2040 CPU. And I believe it, having done similar things for a long time with it. It wasn’t his goal, it’s written. Please think a little before commenting (unnecessarily) on other people’s work. Thank you.

        1. By bothering to comment, the person who offended you definitely implies that it matters that it wasn’t done, but they still do not necessarily imply that it couldn’t be done. I read their comment as meaning that in their opinion it’d be worth eliminating the desktop to do this on-board.

          I disagree with that and actually agree with the blogger that it’s a neat concept and fun, but it wouldn’t be a fun use of time to implement all the remainder. They specifically say it’d be better to try for a Tayloe detector or something else better and easier than this one, and I think that sounds right.

        2. The problem is presentation.

          “Just an RP2040” when it wasn’t.
          It doesn’t matter if it is possible or feasible.
          That isn’t what happened, so don’t present it to us as if it was.

          If I spend $15 on cables to build a computer using other parts I already own, I sure as heck didn’t “build a computer for $15”.
          Yet, that would be a perfectly normal headline here on HaD and elsewhere.

          This project is really neat.
          However, some of us are sick and tired of the rampant misrepresentation, so we bitch about it in the comments.

    1. Way back in the 2000s we did this without the microcontroller.

      We attached a Direct-Conversion receiver (DC rx) to the soundcard’s line-in connector.

      The IF range was about 7 KHz, I think.
      The software then was doing the demodulation.

      Sample schematic with EF95 tube and crystal 6 MHz:
      https://www.elexs.de/ef956.htm

      Dream and SDRadio were being popular back then.

      https://www.softpedia.com/get/Science-CAD/SDRadio.shtml

      http://www.mynetcologne.de/~nc-keilje/drm/dream/index.htm
      Pictures: https://www.qsl.net/hb9tlk/drm/dream.htm

      Also known was SAQrx software.
      It didn’t require any receiver, just a long wire antenna and soundcard with high enough sampling rate to cover the frequency (your 8-bit 22 KHz Sound Blaster Pro compatible wasn’t good enough, hi).

      https://sites.google.com/site/sm6lkm/saqrx-vlf-receiver

    2. Reminds me of using a whisker on a germanium crystal and a hand wrapped tuning coil. Used to sit in my room at night as a kid listening to the world. Am I showing my age?

  1. The mixing is actually performed by DMA, making use of use XOR register alias, exploiting the fact that some of the PIO control registers are unused (those that control pin configurations of state machines that perform the summing / decimation). PIO is connected to AHB-lite and thus the register can deal with the high data rate.

    It was fun building this and I will eventually tackle the demodulation as well, just not now.

    1. This is the kind of work that keeps me reading HaD.
      Thanks for sharing it with us, you didn’t even have to. I have no immediate use for it, but knowing it’s possible is just amazing.
      Few people are able to provide so much explanation so cleanly and in such a structured way.

      Thank you so much for such high-quality content!

  2. Congratualtions Mordae, an extremely innovative approach. I wonder what could be possible with f. I. an ESP module, dual core 240 MHz, and maybe a way to mis-use thevradio hardware. I enjoyed the explanation and the links provided.

  3. Very interesting project. I could compile the source following the explanation:
    https://code.porucha.net/mordae/pico-sdr

    But it is unclear which gnu radio version is to be used and probably there is an error in the sequence of how to start gnu-radio (start gnu radio first, then the python bridge).

    In my gnu radio version (3.8.1.0) the tcp-source is obsolete:
    https://github.com/gnuradio/gnuradio/issues/4033
    ( I post this here because it seems not to be possible to post issues in the git repo)

    1. I am using gnuradio-3.10.9.2 on Fedora 40. The proper sequence is to start the bridge, then to launch the GNU Radio Companion sheet. Bridge will exit after the client disconnects.

      You can also try out rtl_tcp branch where the firmware & bridge talk rtl_tcp protocol (including frequency changes, but not much else yet). The WBFM sheet in that branch has been updated to use it as well and gqrx seems to mostly work fine with it too. The filtering in this branch has been stripped away a bit, so the neighboring channel suppression is not as good. I will probably re-add it later on when I figure out the origin of those ~72.5 kHz spurs you can see. It’s a work in progress.

      Anyway, 3rd party logins with Github and Gitlab accounts are now enabled so feel free to add issues at your leisure.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.