Floating point exception

I trying to employ my RTL-SDR to listen to the radio and got an AI program produced to find and play stations with a strong signal.

Here is what it came up with:-
sh:
#!/bin/sh

# ====================== CONFIGURATION ======================
MIN_FREQ=88.0
MAX_FREQ=108.0
STEP=0.1
GAIN=40
SQUELCH=-25
LISTEN_TIME=12
# ===========================================================

echo "FM Strong Station Player (FreeBSD)"
echo "Squelch: $SQUELCH dB | Gain: $GAIN"
echo "Press Ctrl+C to stop"
echo

freq=$MIN_FREQ

while [ "$(echo "$freq <= $MAX_FREQ" | bc -l)" -eq 1 ]; do
    # Measure signal power
    power=$(rtl_power -f ${freq}M:${freq}M:10k -g $GAIN -i 0.3 -e 1s 2>/dev/null | \
            awk -F',' '{s+=$6; n++} END {if(n>0) printf "%.1f", s/n; else print -99}')

    printf "\r→ %6.1f MHz   Power: %6.1f dB" "$freq" "$power"

    # Squelch check
    if [ "$(echo "$power > $SQUELCH" | bc -l)" -eq 1 ]; then
        echo
        echo
        echo ">>> Strong station found: ${freq} MHz ($power dB)"
        echo "Playing for $LISTEN_TIME seconds..."

        # Play station
        rtl_fm -f ${freq}M -M wbfm -s 200k -r 32k -g $GAIN -l 15 2>/dev/null | \
        play -r 32k -t raw -e signed-integer -b 16 -c 1 - 2>/dev/null &
        play_pid=$!

        sleep "$LISTEN_TIME"
        kill $play_pid 2>/dev/null
        wait $play_pid 2>/dev/null

        echo "----------------------------------------"
    fi

    # Increase frequency
    freq=$(echo "$freq + $STEP" | bc -l)
done

echo
echo "Scan finished."

Unfortunately the line

if [ "$(echo "$power > $SQUELCH" | bc -l)" -eq 1 ]; then
dumps with a floating point exception.

Is this line correctly created?

How would I run it from a command prompt using values of 99 and 25 for $power an $SQUELCH ?
 
Two further suggestion by GROK to eliminate the problem have failed.

The requirement was to create a program to find and play stations with a strong signal from an RTL-SDR dongle using rtl_power.
 
I was able to run it after changing "→" to "->" on line 24.

Code:
FM Strong Station Player (FreeBSD)
Squelch: -25 dB | Gain: 40
Press Ctrl+C to stop

 ->  108.0 MHz   Power:  -99.0 dB
Scan finished.
I simply ran it, so it might not have any particular significance.
 
The error seems to occur as a result of this line:-

while [ "$(echo "$freq <= $MAX_FREQ" | bc -l)" -eq 1 ]; do

Can anyone tell me what this means?

If $freq is 88.0 and $MAX_FREQ is 90.0 what does this expression evaluate to?

I can't figure out what bc -l does.
 
Is there a particular reason for using the shell here? Because there are plenty of languages that are much better suited for this—and more powerful, too.
man bc(1)

(Don't rely too heavily on AI to generate fully functional programs.)
 
Perhaps reading
Bash:
man bc
could shed some light into the last part of your question
-l, --mathlib
Sets scale (see the SYNTAX section) to 20 and loads the included
math library and the extended math library before running any code,
including any expressions or files specified on the command line.


That is clear as mud.
 
Is there a particular reason for using the shell here? Because there are plenty of languages that are much better suited for this—and more powerful, too.
man bc(1)

(Don't rely too heavily on AI to generate fully functional programs.)
Unfortunately that is all I have to go on.

I usually come here where there is HI to get mistakes corrected.

I'm getting the idea that AI created additional work rather than saving work.
 
I'm having trouble following along since I'm not at all familiar with RTL-SDR and shell, but I asked ChatGPT to analyze the script, and it found both major and minor errors.

Don't hesitate to let me know if you want more information.
PriorityIssueConsequence
1$6 used as signal powerThe detector does not work correctly
2freq:freq scan rangeMeasurement is questionable / poorly defined
3rtl_power launched 201 timesExtremely slow scanning
4No peak detectionThe same station may be detected multiple times
5No trap handlingCtrl+C shutdown is not clean
6Fixed 40 dB gainRisk of tuner saturation
7Floating-point values handled with bcWorks, but is unnecessarily cumbersome
 
I'm having trouble following along since I'm not at all familiar with RTL-SDR and shell, but I asked ChatGPT to analyze the script, and it found both major and minor errors.

Don't hesitate to let me know if you want more information.



I think a knowledge of RTL_SDR and shell is a prequisite to find a solution to this and probably need to be done from first principles and seems to revolve around the commands rtl_power and rtl_fm.

I don't have much knowledge of these commands but will try to investigate.
 
Start by reading the bc man page. It is actually intelligible. Then think about what the -l switch does. It would help to actually read the man page, which explicitly sends you to the discussion of scale in the syntax section.

What does floating point error mean? That should be a quick web search.

And then look at the command line that's used for bc here. Why don't you start by echoing the parameters that are really being sent to bc. I would duplicate the line with the bc, and replace bc with "echo" and see what is really happening. Be super careful with quoting, as the expression being sent into bc contains common shell meta characters (such as < and >), which is they are not quoted will make the shell do something other than is intended.

After that, think about what that line does: it calls bc, seemingly to compare two numbers. It then compares the result of bc with a constant. Do you really need bc here? If yes, why?
 
This is the command which generates a floating point exception.

Code:
    power=$(rtl_power -f ${freq}M:${freq}M:10k -g $GAIN -i 0.3 -e 1s 2>/dev/null | \
            awk -F',' '{s+=$6; n++} END {if(n>0) printf "%.1f", s/n; else print -99}')

Not knowing much about awk I can't figure what this is trying to do.

This line is AI generated so may well be wrongly formatted.


Explanation:

In plain English:​


  1. Read the output of rtl_power (which is comma-separated).
  2. Take the 6th column from each line (this is the power/dB value).
  3. Add all those power values together.
  4. Divide by the number of lines → calculate the average power.
  5. Print the average with one decimal place.
  6. If there’s no data, print -99 as a fallback.
 
Post the output of
rtl_power -f ${freq}M:${freq}M:10k -g $GAIN -i 0.3 -e 1s

I ran:-

rtl_power -f 80M:90M:10k -g 40 -i 0.3 -e 1s /tmp/fm.scan

fm.scan:-

Code:
2026-08-16, 17:37:32, 80000000, 82500000, 9765.62, 128, -23.05, -22.63, -22.68, -22.49, -21.90, -22.84, -21.82, -20.68, -20.54, -20.76, -20.20, -20.44, -20.26, -19.70, -19.22, -18.77, -19.20, -18.74, -18.25, -18.29, -17.63, -17.67, -18.30, -17.71, -17.36, -16.80, -
2026-08-16, 17:37:32, 82500000, 85000000, 9765.62, 128, -26.76, -26.53, -25.79, -26.84, -26.20, -25.31, -24.96, -25.72, -25.21, -24.58, -24.79, -25.15, -24.33, -24.00, -23.62, -23.86, -23.41, -22.83, -22.63, -22.69, -22.07, -22.95, -22.47, -21.68, -21.60, -22.04, -
2026-08-16, 17:37:32, 85000000, 87500000, 9765.62, 128, -19.09, -19.72, -19.34, -19.94, -18.89, -19.97, -19.18, -18.62, -18.91, -18.99, -17.98, -18.34, -17.59, -17.96, -17.79, -17.25, -16.99, -17.21, -16.19, -16.32, -16.26, -16.15, -16.26, -15.99, -15.45, -16.11, -
2026-08-16, 17:37:32, 87500000, 90000000, 9765.62, 128, -19.23, -21.11, -21.04, -21.38, -20.97, -21.35, -21.43, -20.36, -20.97, -19.72, -19.67, -19.39, -19.47, -18.65, -18.66, -17.48, -18.81, -18.76, -18.18, -18.37, -17.70, -18.27, -17.47, -18.05, -17.41, -16.60, -
 
It is likely that the version of rtl_power used by the AI is different.
What happens if you change to awk -F',' '{s+=$7; n++}

Do you mean changing the original code to this?

Code:
#!/bin/sh

# ====================== CONFIGURATION ======================
MIN_FREQ=88.0
MAX_FREQ=108.0
STEP=0.1
GAIN=40
SQUELCH=-25
LISTEN_TIME=12
# ===========================================================

echo "FM Strong Station Player (FreeBSD)"
echo "Squelch: $SQUELCH dB | Gain: $GAIN"
echo "Press Ctrl+C to stop"
echo

freq=$MIN_FREQ

while [ "$(echo "$freq <= $MAX_FREQ" | bc -l)" -eq 1 ]; do
    # Measure signal power
    power=$(rtl_power -f ${freq}M:${freq}M:10k -g $GAIN -i 0.3 -e 1s 2>/dev/null | \
            awk -F',' '{s+=$7; n++} END {if(n>0) printf "%.1f", s/n; else print -99}')

    printf "\r→ %6.1f MHz   Power: %6.1f dB" "$freq" "$power"

    # Squelch check
    if [ "$(echo "$power > $SQUELCH" | bc -l)" -eq 1 ]; then
        echo
        echo
        echo ">>> Strong station found: ${freq} MHz ($power dB)"
        echo "Playing for $LISTEN_TIME seconds..."

        # Play station
        rtl_fm -f ${freq}M -M wbfm -s 200k -r 32k -g $GAIN -l 15 2>/dev/null | \
        play -r 32k -t raw -e signed-integer -b 16 -c 1 - 2>/dev/null &
        play_pid=$!

        sleep "$LISTEN_TIME"
        kill $play_pid 2>/dev/null
        wait $play_pid 2>/dev/null

        echo "----------------------------------------"
    fi

    # Increase frequency
    freq=$(echo "$freq + $STEP" | bc -l)
done

echo
echo "Scan finished."
 
Yes.
However, the floating point exception might not be resolved.
Actually it isn't.

What was the point of the change?

This command does not create a floating point exception:-

rtl_power -f 88.0M:108.0M:10k -g 40 -i 0.3 -e 1s


I'd like to split up this command into it's constituent components and run them individually and see if I can spot where the problem lies

power=$(rtl_power -f ${freq}M:${freq}M:10k -g $GAIN -i 0.3 -e 1s 2>/dev/null | \
awk -F',' '{s+=$7; n++} END {if(n>0) printf "%.1f", s/n; else print -99}')
 
$6 represents the number of samples; calculating it is meaningless.
What happens if you change to ${freq}M:${freq}M:512 ... | awk ...?
Not really sure what command line I should run.

Something like this?

rtl_power -f 88.0M:108.0:10k -g 40 -i 0.3 -e 1s 2>/dev/null | awk -F',' '{s+=$7; n++}
 
OK, that is a long command line, which makes it hard to debug. Try this temporarily:
Code:
echo Before rtl_power
rtl_power ... > /tmp/foo.$$ 2> /tmp/foo_error.$$
rtl_power_status=$?
echo After rtl_power status is $rtl_power_status
echo Output from rtl_power has `cat /tmp/foo.$$ | wc -l` lines
echo Error from rtl_power has `cat /tmp/foo_error.$$ | wc -l` lines, should be zero

cat /tmp/foo.$$ | awk -F ... > /tmp/bar.$$ 2> /tmp/bar_error.$$
awk_status=$?
echo After awk status is $awk_status
echo Output from awk has `cat /tmp/bar.$$ | wc -l` lines
echo Error from awl has `cat /tmp/bar_error.$$ | wc -l` lines, should be zero

echo Output from awk was:
cat /tmp/bar.$$

The important part is: DO NOT TYPE THE ABOVE LINES IN. First read then AND UNDERSTAND THEM. Do not run them until you understand what they do.
 
Back
Top