Posted on 11 Comments

RTL-SDR Server as a service on Raspberry Pi

Updated 25th Aug 2021 Clarified RTL-SDR build requirements

NB: This post assumes that you have already built the RTL-SDR server from source using the following instructions. 

Install RTL-SDR server 

These instructions will not work if you install RTL-SDR via the repository, i.e. sudo apt install…

Now that Raspbian has changed to Systemd for managing auto-starting programs and daemons, I thought it was about time I moved away from using rc.local to start the rtl-sdr server.

If you ‘re currently using the rc.local file to start the server, begin by removing the server commands from that file.

The next job is to create a unit file to provide Systemd with the essential information for the management of the service. To create the unit file, use nano as follows.

Enter: sudo nano /etc/systemd/system/rtlsdr.service

Once nano opens, populate it with the following lines:

[Unit]
Description=RTL-SDR Server

Wants=network-online.target
After=network-online.target

[Service]

ExecStartPre=/bin/sleep 15
ExecStart=/bin/sh -c ‘/usr/local/bin/rtl_tcp -a $(hostname -I)’
WorkingDirectory=/home/pi
StandardOutput=inherit
StandardError=inherit
Restart=always

[Install]
WantedBy=multi-user.target

When you’ve entered the lines above, press ctl x then y and Enter to save the file.

To test the service, make sure the RTL dongle and network are connected and enter: sudo systemctl start rtlsdr.service. If that proceeds without error, you can check the status of the service with sudo systemctl status rtlsdr.service. If all is well, you should see a message showing that the RTL-SDR dongle has been found. You can stop the service with sudo systemctl stop rtlsdr.service. If you’re happy that all is working ok, you can enable the service so it automatically starts at boot time. Enter the following: sudo systemctl enable rtlsdr. To disable the auto-start service it’s sudo systemctl disable rtlsdr.service

Time Saving Tip: When entering systemctl commands, you can omit the .service suffix.

You can find out more about Systemd at: https://fedoramagazine.org/what-is-an-init-system/

ExecStart Explanation

ExecStartPre=/bin/sleep 15

This line adds a 15 second delay between completion of the network setup and starting the Spy Server. This is included as a precaution to allow time for a slow router to allocate an IP address for the Pi. If the start-up delay is a problem for you try reducing the sleep time or eliminating this line completely.

ExecStart=/bin/sh -c ‘/usr/local/bin/rtl_tcp -a $(hostname -I)’

This line starts the server but warrants some explanation. One of the problems with starting the rtl-sdr server as a service is the lack of a system variable to provide the Pi IP address. We need this because we have to pass the IP address to the server when it’s started. In this solution, I’ve called sh first and used the -c option. This tells sh to get the command line instruction from the quoted string that follows. That way we can use our standard call to rtl_tcp and combine it with the command line $(hostname -I) instruction to retrieve the IP address.

Mike – G4WNC

11 thoughts on “RTL-SDR Server as a service on Raspberry Pi

  1. Does not work for me, bloody computers!

    If I do

    rtl_tcp -a 192.168.1.49

    it works, can access it from SDR# or an iPhone RTL_TCP app
    Do not have it set to auto start either from rc.local or as service.

    After a reboot i get

    pi@raspberrypi:~ $ sudo systemctl status rtlsdr.service
    ? rtlsdr.service – RTL-SDR Server
    Loaded: loaded (/etc/systemd/system/rtlsdr.service; disabled; vendor preset:
    Active: inactive (dead)
    pi@raspberrypi:~ $ sudo systemctl start rtlsdr.service
    pi@raspberrypi:~ $ sudo systemctl status rtlsdr.service
    ? rtlsdr.service – RTL-SDR Server
    Loaded: loaded (/etc/systemd/system/rtlsdr.service; disabled; vendor preset: enabled)
    Active: failed (Result: exit-code) since Thu 2018-07-26 15:39:46 BST; 55s ago
    Process: 1622 ExecStart=/bin/sh -c ‘/usr/local/bin/rtl_tcp -a $(hostname -I)’ (code=exited, status=127)
    Main PID: 1622 (code=exited, status=127)

    Jul 26 15:39:46 raspberrypi systemd[1]: rtlsdr.service: Failed with result ‘exit-code’.
    Jul 26 15:39:46 raspberrypi systemd[1]: rtlsdr.service: Service hold-off time over, scheduling restart.
    Jul 26 15:39:46 raspberrypi systemd[1]: Stopped RTL-SDR Server.
    Jul 26 15:39:46 raspberrypi systemd[1]: rtlsdr.service: Start request repeated too quickly.
    Jul 26 15:39:46 raspberrypi systemd[1]: Failed to start RTL-SDR Server.
    Jul 26 15:39:46 raspberrypi systemd[1]: rtlsdr.service: Unit entered failed state.
    Jul 26 15:39:46 raspberrypi systemd[1]: rtlsdr.service: Failed with result ‘exit-code’.
    pi@raspberrypi:~ $ ^C

  2. Ok, fresh install of rasp stretch lite and now working …to a degree. Works with rtl_tcp command but not as start service

    Also You have error in the text to stop the service

    you have
    sudo systemd stop rtlsdr.service which does not work

    Think it should be
    sudo systemctl stop rtlsdr.service

    The service shows started, it does not actually work at the ‘far end’

    In order to get it to work, still must use the command
    rtl_tcp -a 192.168.1.49

    The remote end reports a ‘network error’ when started as service with:
    sudo systemctl start rtlsdr.service

    but works fine with:
    rtl_tcp -a 192.168.1.49

    pi@rtltcp:~ $ sudo systemctl start rtlsdr.service
    pi@rtltcp:~ $ sudo systemctl status rtlsdr.service
    ? rtlsdr.service – RTL-SDR Server
    Loaded: loaded (/etc/systemd/system/rtlsdr.service; disabled; vendor preset: enabled)
    Active: active (running) since Fri 2018-07-27 07:13:21 GMT; 4s ago
    Main PID: 847 (sh)
    CGroup: /system.slice/rtlsdr.service
    ??847 /bin/sh -c /usr/local/bin/rtl_tcp -a -I)
    ??848 /usr/local/bin/rtl_tcp

    Jul 27 07:13:21 rtltcp systemd[1]: Started RTL-SDR Server.
    Jul 27 07:13:21 rtltcp sh[847]: Found 1 device(s):
    Jul 27 07:13:21 rtltcp sh[847]: 0: Realtek, RTL2838UHIDIR, SN: 00000001
    Jul 27 07:13:21 rtltcp sh[847]: Using device 0: Generic RTL2832U OEM
    Jul 27 07:13:21 rtltcp sh[847]: Found Rafael Micro R820T tuner
    Jul 27 07:13:21 rtltcp sh[847]: [R82XX] PLL not locked!
    Jul 27 07:13:21 rtltcp sh[847]: Tuned to 100000000 Hz.
    pi@rtltcp:~ $ sudo systemd stop rtlsdr.service
    Excess arguments.
    pi@rtltcp:~ $ sudo systemctl stop rtlsdr.service
    pi@rtltcp:~ $ sudo systemctl status rtlsdr.service
    ? rtlsdr.service – RTL-SDR Server
    Loaded: loaded (/etc/systemd/system/rtlsdr.service; disabled; vendor preset: enabled)
    Active: inactive (dead)

    Jul 27 07:13:21 rtltcp sh[847]: [R82XX] PLL not locked!
    Jul 27 07:13:21 rtltcp sh[847]: Tuned to 100000000 Hz.
    Jul 27 07:13:49 rtltcp sh[847]: Signal caught, exiting!
    Jul 27 07:13:49 rtltcp systemd[1]: Stopping RTL-SDR Server…
    Jul 27 07:13:49 rtltcp sh[847]: Signal caught, exiting!
    Jul 27 07:13:49 rtltcp sh[847]: listening…
    Jul 27 07:13:49 rtltcp sh[847]: Use the device argument ‘rtl_tcp=127.0.0.1:1234’ in OsmoSDR (gr-osmosdr) source
    Jul 27 07:13:49 rtltcp sh[847]: to receive samples in GRC and control rtl_tcp parameters (frequency, gain, …).
    Jul 27 07:13:49 rtltcp sh[847]: bye!
    Jul 27 07:13:49 rtltcp systemd[1]: Stopped RTL-SDR Server.
    pi@rtltcp:~ $

  3. Server does not start @reboot ( see previous posts )
    Only works with rtl_tcp -a IP_adddress

    pi@raspberrypi:~ $ sudo systemctl status rtlsdr
    ? rtlsdr.service – RTL-SDR Server
    Loaded: loaded (/etc/systemd/system/rtlsdr.service; enabled; vendor preset: enabled)
    Active: activating (start-pre) since Thu 2018-08-23 16:34:37 CEST; 6s ago
    Process: 736 ExecStart=/bin/sh -c ‘/usr/local/bin/rtl_tcp -a $(hostname -I)’ (code=exited, status=127)
    Main PID: 736 (code=exited, status=127); Control PID: 745 (sleep)
    CGroup: /system.slice/rtlsdr.service
    ??control
    ??745 /bin/sleep 15

    aug 23 16:34:37 raspberrypi systemd[1]: Starting RTL-SDR Server…

    1. Hi Kim,

      This may be because your Pi doesn’t have an IP address when the rtlsdr service starts. Try updating the unit file to include the following line in the [Service] section:
      ExecStartPre=/bin/sleep 15

      This adds a 15 second delay to allow the IP address to be allocated after the network is up.

      See the latest instructions for full details.

      Regards,

      Mike – G4WNC

      1. Hi Mike,

        That line is included and I have tried different timings.

        Regards,

        Kim

        1. Ok. With the Pi running make sure the service is stopped by entering:
          sudo systemctl stop rtlsdr
          Enter: hostname -I to make sure the Pi has an IP address
          Enter: sudo systemctl start rtlsdr
          That should start the service
          Now enter sudo systemctl status rtlsdr and let me know what you get. If it all appears to be running test access from your SDR software.

          Mike – G4WNC

          1. Hi Mike,

            IP is correct.
            sudo systemctl status rtlsdr throws an error.
            Access not possible.

            Thx for looking at it.

            Kim

            pi@raspberrypi:~ $ sudo systemctl stop rtlsdr
            pi@raspberrypi:~ $ hostname -I
            10.10.176.18
            2a02:a03f:54ec:5000:a7c8:cdb:5f88:945f
            pi@raspberrypi:~ $ sudo systemctl start rtlsdr
            pi@raspberrypi:~ $ sudo systemctl status rtlsdr
            ? rtlsdr.service – RTL-SDR Server
            Loaded: loaded (/etc/systemd/system/rtlsdr.service; disabled; vendor preset:
            Active: activating (start-pre) since Fri 2018-08-24 17:50:25 CEST; 6s ago
            Process: 1127 ExecStart=/bin/sh -c ‘/usr/local/bin/rtl_tcp -a $(hostname -I)’
            Main PID: 1127 (code=exited, status=127); Control PID: 1130 (sleep)
            CGroup: /system.slice/rtlsdr.service
            ??control
            ??1130 /bin/sleep 15

            aug 24 17:50:25 raspberrypi systemd[1]: Starting RTL-SDR Server…
            lines 1-10/10 (END)

  4. In case anyone is stuck getting this to work, I copied and pasted the code shown but the single quotes came over as ` instead of ‘ in the rtl_tcp command. Retyping those with the correct single quote character made it work.

    1. Hi Scott, Very useful observation. Thanks Mike – G4WNC

  5. It took me ages to figure out why this doesn’t work.

    Firstly, when you install the package rather than build from source it is not installed in /usr/local/bin but /usr/bin – in that case the script needs altering.

    Secondly, with the package, the udev rules are not installed in /etc but in /lib AND they have mode set to 0660 rather than 0666. This mode setting seems to prevent the UDEV rules working unless you modify it to 0666. Devil in the detail literally.

    Thirdly – if you are on the internet then chances are you not running the default user “pi” and you need to modify the script accordingly.

    1. Hi Mike,

      Thanks for the feedback. I’m sure that will be very helpful to anyone installing from the repository. However, I prefer to build from source as radio related applications in the Pi repository are often out of date. Building from source is very quick and easy to follow. I’ve modified the original post to make the requirement clearer.

      Thanks,

      Mike – G4WNC

Leave a Reply

Your email address will not be published. Required fields are marked *

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