6
$\begingroup$

I'm very new to shortwave radio, as evidenced here:

Can an antenna be too powerful for certain receivers?

I want to build a longwire receive-only antenna for the HF frequencies.

I've been using the source:

SWL - Shortwave Listening

as a guide, but it isn't clear whether it's using 50 or 75 ohm coax cable.

The source says that if you use a coax you should also use a balun, but I don't know whether it should have a 9:1 ratio like the source says or whether I should calculate the impedance of the antenna.

Should the antenna be a specific length to receive the HF frequencies best?

I have a decent amount of space to work with so an antenna 75 feet long or less will be doable.

Do I need to worry about SWR?

I'm wondering whether I even need to consider all this as I'm just making a receiving longwire; I'm pretty sure I need a coax as I live nearby other houses (i.e. sources of noise), but do I need to have a transformer, antenna tuner, match impedance, etc. or am I just overthinking this?

The way the antenna system will be hooked up to a RTL-SDR dongle - this might be important to some answers.

$\endgroup$
4
  • 2
    $\begingroup$ IMHO, Yes you're overthinking things for just a receive antenna, and one that will be used over a range of frequencies at that. Just toss a wire into the top of a tree and listen with that. If you start transmitting or if you're looking to optimize your receiving station (to receive weak signals, etc.), then you can start being concerned about SWR and baluns and such. But for casual listening? Just do it. $\endgroup$
    – Duston
    Apr 9, 2018 at 14:26
  • $\begingroup$ @Duston, I agree. However, answers should not be posted in comments. $\endgroup$
    – Mike Waters
    Apr 9, 2018 at 14:51
  • $\begingroup$ My apologies. I didn't think my comments were worthy of answer-status. $\endgroup$
    – Duston
    Apr 9, 2018 at 15:09
  • $\begingroup$ It's hard to answer since it's unclear what "this" is. The kind of coax? The balun? The antenna type? $\endgroup$ Apr 9, 2018 at 18:20

5 Answers 5

5
$\begingroup$

The answers given so far provide good food for thought. I would like to add a slightly different perspective.

Today's home is loaded with sources of RFI (radio frequency interference). Routers, computers, wall warts, LED lamps, solar inverters, video cameras, etc. all are potential sources of RFI that interfere with the weak signals of short wave signals from distant countries. More and more, the need to keep the antenna system away from these local RFI sources is the reality of short wave listening. Not only must the antenna be distanced from the RFI but care must be taken that the feedline, typically coax, does not pickup these local RFI sources.

Antennas such as long wires and end fed "half waves" suffer from common mode currents on the feedline. These common mode currents cause the coax to pickup local RFI sources and couple them into the receiver. This problem can be mitigated by using a balanced antenna, such as a dipole, and connecting the coax to the dipole using a wide band, 1:1 current balun. This will minimize the local RFI pickup.

Is this over-thinking the issue? Some may say yes. But anything from a coat hanger to a log periodic antenna on the top of an 80 foot tower will receive signals. It is only a question of effectiveness for the effort and expense. You will need to make that determination.

$\endgroup$
3
$\begingroup$

The simple case would be a 75 foot wire whose far end is an open-end tied to a high support, and whose near end feeds directly to your SDR-dongle. It is assumed the dongle is a single-ended input whose other termination is RF-grounded through your PC.
It is likely that your SDR-dongle has a low-impedance antenna input, perhaps 50 ohms. At some frequencies, this will work well. At other frequencies a poor match delivers less power to your SDR-dongle. A 75 foot wire would favour the low end of the HF frequency space, where it mimics a quarter-wave vertical. As the frequency goes higher, a poorer match to a low-impedance SDR would be where your antenna mimics a half-wave end-fed wire.
Does this poor match make the antenna useless at certain frequencies? Certainly not, if your SDR receiver noise floor is decent....(a sensitive receiver). For transmitting, a good match would be more important for the health of a transmitting power amplifier but of less importance for a receiver where signal loss creates insignificant heat (nanowatts).

Adding some coax between antenna-end and SDR might change the impedance that your SDR sees, and also change the frequency spans where the antenna is decently matched (and poorly matched). Coax will likely add some small signal loss too.
For casual listening, throw up a good long wire, whose end comes conveniently-close to your SDR, and a short length of coax to make up the difference. If a band-segment becomes particularly interesting to you, a simple L-section tuner could improve signals, if that band-segment is poorly matched. But many receivers have enough sensitivity that perceived improvements may be minor. Fussing over a "proper" receiving antenna, especially over a wide frequency range like the whole HF spectrum is not worth the trouble if "casual" listening is a goal.

$\endgroup$
1
$\begingroup$

Yes, do experiment, and "toss a length of wire in a tree" is definitely how most SWL's are starting.

However if you have a choice, the you should avoid 1/2 wave lengths, or multiples thereof.

A good source of information is here http://udel.edu/~mm/ham/randomWire/

And if you scroll down to the little table, you are probably interested in row d or row e. In the next table you will find what lengths to avoid.

So for 80-40-30-20-17-15-12-10 meter bands, you can get away with a length of 72 feet.

For 160-80-40-30-20-17-15-12-10 meter bands, you can get away with a length of 143 feet.

$\endgroup$
1
$\begingroup$

I have an MFJ 9200 CW rig that only transmits in CW on ham freqs, but I can listen on SW broadcast freqs.

I always carry it on bikepacking and backpacking trips. I spend over 6 months a year in the outdoors. I rarely actively operate, but I use it every night to listen on SW broadcast bands and just monitoring the convos on the ham bands. I use a 21 foot piece of # 24 wire with a piece of 550 cord tied on the end. Then I throw it over a tree limb and string it in a vertical fashion. Sometimes (rarely) I’ll ground my rig case with a short non-resonant wire and tent stake if there’s any need.

21 feet does great for listening on all freqs!!!! My point is that 21 feet of wire should do just fine if you want to cover all bands... I’d put it vertical for listening. No worries about SWR unless you’re going to transmit. I use a small Z match when transmitting.

You can get as complicated or as simple as you’d like when it comes to antenna’s!! I like simple...

With the RTL-SDR, you could run a piece of RG-175 that isn’t resonant on any freqs you monitor to a bnc/banana plug at ground level with the 21 foot wire going straight up (vertical) and you could just connect the “ground” side of the banana/bnc to a copper rod directly in the ground with a few inches of wire. That’ll do pretty darn good I’d bet!!!!! I also use a 71 foot wire on occasion. Adding the coax will cause more RFI pick up as said before but if it’s total length isn’t resonant on any freqs you monitor then it’ll help.

$\endgroup$
1
$\begingroup$

I decided to add another answer. This because I was curious about some of the calculators which would calculate the ideal length of wire. These calculators can be found by simple searches.

Some of those simply take the mid of the band, and calculates lengths to avoid.

I decided to create a simple calculator in python3 as that is my preferred scripting language. See code below.

Usage parameters:

-b:a,b,c
-b:a

This runs the calculation just on bands a, b, c specified, comma-separated, no spaces

-b:a-b

This runs the calculation on all bands a to b (including a, including b), ensure a is lower in frequency than b, and no spaces. Example -b:80-20 which will run for 80,60,40,30,20 m bands.

-b:all

This runs the calculation on all defined bands. This is the default and can be omitted

-margin:x

This defines the x% margin to add to the edge of the bands, to ensure that the calculation stays away from half wave on band edges. Example: if x is given as 10, and band is the 40m band, and this band is defined as 7000-7200 kHz, then the band edges are + and - the 10% of the bandwidth: e.g. 6980-7220 kHz. If this x is given as -50, then it calculates only the exact middle of the band, e.g. 7100 kHz. if this is given as 50, then it will be 6900-7300 kHz. By default this is 10%, and can be omitted.

-min:y

This is the minimum wire length to be calculated, based on factor y of the lowest frequency wavelength. By default this is 0.25 which is a quarter-wave on the lowest frequency as a minimum for wire length. Default is 0.25 and can be omitted.

-max:z

This is the maximum wire length to be calculated based on factor z of the lowest frequency wavelength. By default this is 2 and can be omitted.

-res:2

This is the (metric) resolution of the results, indicating decimal places after the decimal point for all calculations. 2 will indicate a resolution of centimeters, 1 will indicate a resolution of 10-cm, 0 will indicate a resolution of 1 meter. Default is 2 and can be omitted.

Example usage:

To calculate 160,80,40 meter bands, with default resolution, default minimum and default maximum, and a default margin:

longwire.py -b:160,80,40

Result:

-------------------------------------------------------------------
Random Longwire Antenna Calculation
Input parameters:
-------------------------------------------------------------------
Bands         : ['160', '80', '40']
Minimum factor: 0.25    (of lowest frequency)
Maximum factor: 2       (of lowest frequency)
Margin        : 10    % (band edge adjustment)
-------------------------------------------------------------------

Avoidance for band: 160 [[74.26, 84.27], [148.52, 168.54], [222.78, 252.81], [297.04, 337.08], [371.3, 421.35]]
Avoidance for band: 80 [[39.16, 43.23], [78.32, 86.46], [117.48, 129.69], [156.64, 172.92], [195.8, 216.15], [234.96, 259.38], [274.12, 302.61], [313.28, 345.84], [352.44, 389.07]]
Avoidance for band: 40 [[20.78, 21.49], [41.56, 42.98], [62.34, 64.47], [83.12, 85.96], [103.9, 107.45], [124.68, 128.94], [145.46, 150.43], [166.24, 171.92], [187.02, 193.41], [207.8, 214.9], [228.58, 236.39], [249.36, 257.88], [270.14, 279.37], [290.92, 300.86], [311.7, 322.35], [332.48, 343.84], [353.26, 365.33]]

Start Lengths [[42.13, 337.08]]
Take away avoids [[74.26, 84.27], [148.52, 168.54], [222.78, 252.81], [297.04, 337.08], [371.3, 421.35]]
New Lengths [[42.13, 74.25], [84.28, 148.51], [168.55, 222.77], [252.82, 297.03]]
Take away avoids [[39.16, 43.23], [78.32, 86.46], [117.48, 129.69], [156.64, 172.92], [195.8, 216.15], [234.96, 259.38], [274.12, 302.61], [313.28, 345.84], [352.44, 389.07]]
New Lengths [[43.24, 74.25], [86.47, 117.47], [129.7, 148.51], [172.93, 195.79], [216.16, 222.77], [259.39, 274.11]]
Take away avoids [[20.78, 21.49], [41.56, 42.98], [62.34, 64.47], [83.12, 85.96], [103.9, 107.45], [124.68, 128.94], [145.46, 150.43], [166.24, 171.92], [187.02, 193.41], [207.8, 214.9], [228.58, 236.39], [249.36, 257.88], [270.14, 279.37], [290.92, 300.86], [311.7, 322.35], [332.48, 343.84], [353.26, 365.33]]
New Lengths [[43.24, 62.33], [64.48, 74.25], [86.47, 103.89], [107.46, 117.47], [129.7, 145.45], [172.93, 187.01], [193.42, 195.79], [216.16, 222.77], [259.39, 270.13]]

-------------------------------------------------------------------
 Results:
-------------------------------------------------------------------
 from 43.24  to 62.33  meters (mid 52.78  m)
 from 64.48  to 74.25  meters (mid 69.37  m)
 from 86.47  to 103.89 meters (mid 95.18  m)
 from 107.46 to 117.47 meters (mid 112.47 m)
 from 129.7  to 145.45 meters (mid 137.57 m)
 from 172.93 to 187.01 meters (mid 179.97 m)
 from 193.42 to 195.79 meters (mid 194.6  m)
 from 216.16 to 222.77 meters (mid 219.47 m)
 from 259.39 to 270.13 meters (mid 264.76 m)

EXTRA:

You may specify a frequency range in kHz instead of bands. Example, 15 MHz to 20 MHz, minimum 1/8 wave on lowest frequency, maximum 1 wave on lowest frequency, with a 10cm resolution, and a 20% margin for the band edges:

longwire.py -range:15000-20000 -margin:20 -min:0.125 -max:1 -res:1

Result:

-------------------------------------------------------------------
Random Longwire Antenna Calculation
Input parameters:
-------------------------------------------------------------------
Bands         : ['custom']
Range         : 15000-20000 kHz
Minimum factor: 0.125   (of lowest frequency)
Maximum factor: 1.0     (of lowest frequency)
Margin        : 20.0  % (band edge adjustment)
-------------------------------------------------------------------

Avoidance for band: custom [[7.1, 10.7], [14.2, 21.4], [21.3, 32.1], [28.4, 42.8]]

Start Lengths [[2.7, 21.4]]
Take away avoids [[7.1, 10.7], [14.2, 21.4], [21.3, 32.1], [28.4, 42.8]]
New Lengths [[2.7, 7.0], [10.8, 14.1]]

-------------------------------------------------------------------
 Results:
-------------------------------------------------------------------
 from 2.7    to 7.0    meters (mid 4.8    m)
 from 10.8   to 14.1   meters (mid 12.4   m)

Comments and improvements of the code are very welcome !

Here is the code:

#!python3
# -*- coding: utf-8 -*-

# Author: Edwin van Mierlo
# Call sign: EI2HEB

# No claims of functionality are being made, no warrantees either

# You may re-use this code anyway you see fit
# Just give me some credit

###############################################################################
## IMPORTS                                                                   ##
###############################################################################
import sys

###############################################################################
## GLOBAL DEFAULTS                                                           ##
###############################################################################
# Band definitions
# low is the lower band edge in kHz
# high is the upper band edge in kHz
# the key is the 'band name'
BANDS_D = {
         "160":{"low":1800,  "high":2000},
         "80" :{"low":3500,  "high":3800},   ## upto 4000 in USA
         "60" :{"low":5250,  "high":5450},   ## varies by region
         "40" :{"low":7000,  "high":7200},   ## upto 7300 in USA
         "30" :{"low":10100, "high":10150},
         "20" :{"low":14000, "high":14350},
         "17" :{"low":18068, "high":18168},
         "15" :{"low":21000, "high":21450},
         "12" :{"low":24890, "high":24990},
         "10" :{"low":28000, "high":29700},
         "6"  :{"low":50000, "high":54000}
        }

# for calculation purposes, you still want
# to stay away from half wave of band edges
# this margin can be expressed in a percentage 
# of the span of the band. Example:
# If 10% is used as margin for the 40m band
# and 40m band is defined as "low":7000,  "high":7200
# then the calculation will take a lower edge of 6980
# and will take an upper edge of 7220
MARGIN = 10

# the minimum length is at least 
# MINIMUM * (lowest frequency wave length)
# By default this is set to 0.25 to ensure 
# that the calculated lengths are at least
# a quarter wavelength on the lowest frequency.
MINIMUM = 0.25

# by setting the maximum to a meaningful value
# if forces the calculation to stop at a value of 
# MAXIMUM * (lowest frequency wave length)
# this ensures the calculation actually stops
# default is set to two times the wavelength of 
# the lowest frequency
MAXIMUM = 2

# you can set the resolution of the calculation
# which by default is set to 2 digits after
# the decimal point. Which is centimeters
# by setting this to 3 it will be millimeters 
METRIC_RESOLUTION = 2

###############################################################################
## INTERNAL FUNCTIONS                                                        ##
###############################################################################
def _get_band_edges(bands_d, index, margin):
    start_freq = int(bands_d[index]['low'])
    stop_freq = int(bands_d[index]['high'])
    lower_bandedge = start_freq - ((stop_freq - start_freq) * (margin/100))
    upper_bandedge = stop_freq + ((stop_freq - start_freq) * (margin/100))
    return lower_bandedge, upper_bandedge

def _get_wirelength_limits(frequency, minimum, maximum, metric_res):
    wavelength = 300/(frequency/1000)
    return (round(wavelength * minimum, metric_res), 
            round(wavelength * maximum, metric_res))

def _get_band_avoidance(lower_bandedge, 
                        upper_band_edge, 
                        min_wire_length, 
                        max_wire_length, 
                        metric_res):
    avoid = []
    half_wave_low = round(300/(lower_bandedge/1000)/2, metric_res)
    half_wave_high = round(300/(upper_band_edge/1000)/2, metric_res)
    avoid.append([half_wave_high, half_wave_low])
    factor = 2
    current_high = half_wave_high
    while current_high < max_wire_length:
        current_low = round(half_wave_low * factor, metric_res)
        current_high = round(half_wave_high * factor, metric_res)
        if current_low >= min_wire_length:  
            avoid.append([current_high, current_low])
        factor += 1
    return avoid

    
def _get_good_lenghts(lengths, avoid, metric_res):
    my_lengths = []
    step = 1/(10**metric_res)
    for length_range in lengths:
        my_lengths += _recursive_check(length_range, avoid, step, metric_res)
    return my_lengths

def _recursive_check(good, bad, step, metric_res):
    # end of good is smaller than start of bad
    if good[1] < bad[0][0]:
        if good[0] < good[1]:
            return [good]
        else:
            return []
    l = []
    if (bad[0][0] > good[0]) and (bad[0][0] < good[1]):
        l.append([good[0], round(bad[0][0] - step, metric_res)])
        if bad[0][1] < good[1]:
            l += _recursive_check([round(bad[0][1] + step, metric_res), good[1]], 
                                  bad[1:], 
                                  step,
                                  metric_res)
    elif ((bad[0][0] < good[0]) 
          and (bad[0][1] < good[1]) 
          and (bad[0][1] > good[0])):
        l += _recursive_check([round(bad[0][1] + step, metric_res), good[1]],
                               bad[1:],
                               step,
                               metric_res)
    elif (bad[0][0] < good[0]) and (bad[0][1] > good[1]):
        return l
    elif (bad[0][0] > good[0]) and (bad[0][1] > good[1]):
        l.append([good[0], round(bad[0][0] - step, metric_res)])
    else:
        l += _recursive_check(good,
                              bad[1:],
                              step,
                              metric_res)
    return l

def _get_multi_band(bands_d, bands_l, minimum, maximum, margin, metric_res):
    lower_bandedge, upper_bandedge = _get_band_edges(bands_d, 
                                                     bands_l[0], 
                                                     margin)
    min_wire_length, max_wire_length = _get_wirelength_limits(lower_bandedge, 
                                                              minimum, 
                                                              maximum, 
                                                              metric_res)
    my_lengths = [[min_wire_length, max_wire_length]]

    my_avoids = []
    for band in bands_l:
        lower_bandedge, upper_bandedge = _get_band_edges(bands_d, 
                                                         band, 
                                                         margin)
        avoid = _get_band_avoidance(lower_bandedge, 
                                    upper_bandedge, 
                                    min_wire_length, 
                                    max_wire_length, 
                                    metric_res)
        my_avoids.append(avoid)
        print('Avoidance for band:', band, avoid)
    print()
    print('Start Lengths', my_lengths)
    for avoid in my_avoids:
        print('Take away avoids', avoid)
        my_lengths = _get_good_lenghts(my_lengths, avoid, metric_res)
        print('New Lengths', my_lengths)
    return my_lengths

###############################################################################
## EXTERNAL FUNCTIONS                                                        ##
###############################################################################
def main(bands_d, bands_l, minimum, maximum, margin, metric_res):
    """
    bands_d = dictionary of bands, example:
    
    BANDS_D = {
         "160":{"low":1800,  "high":2000},
         "80" :{"low":3500,  "high":3800},   
         "60" :{"low":5250,  "high":5450},   
         "40" :{"low":7000,  "high":7200},   
         "30" :{"low":10100, "high":10150},
         "20" :{"low":14000, "high":14350},
         "17" :{"low":18068, "high":18168},
         "15" :{"low":21000, "high":21450},
         "12" :{"low":24890, "high":24990},
         "10" :{"low":28000, "high":29700},
         "6"  :{"low":50000, "high":54000}
        }
        
    bands_l = list of the keys of the dictionary of bands to run the 
              calculation on. This is either 1 of the keys, all of the keys
              or a subset of keys
              
    minimum = minimum wire length expressed as a minimum factor of the lowest
              frequency wavelength
              
    maximum = maximum wire length expressed as a maximum factor of the lowest
              frequency wavelength
              
    margin  = band edge correction expressed as a percentage of band width
    
    metric_res = digit precision expressed in number of digits 
                 after decimal point
    """
    my_lengths = []
    my_lengths = _get_multi_band(bands_d, 
                                 bands_l, 
                                 minimum, 
                                 maximum, 
                                 margin, 
                                 metric_res)
    return my_lengths

###############################################################################
## INTERACTIVE CODE                                                          ##
###############################################################################
if __name__ == '__main__':
    minimum = MINIMUM
    maximum = MAXIMUM
    margin = MARGIN
    bands_d = BANDS_D
    metric_res = METRIC_RESOLUTION
    bands_l = [key for key in bands_d]
    if len(sys.argv) > 1:
        # command line parameters are set
        for arg in sys.argv[1:]:
            # looping through the command line parameters
            if '-b:' in arg:
                # bands set in commandline
                my_bands = arg.split('-b:')[1]
                if my_bands.lower() == 'all':
                    # bands_l variable already defined
                    pass
                elif '-' in my_bands:
                    # range of bands in commandline
                    bands = [str(b) for b in my_bands.split('-') if str(b) in bands_l]
                    if len(bands) == 2:
                        start = bands_l.index(bands[0])
                        stop = bands_l.index(bands[1]) + 1
                        bands_l = bands_l[start:stop]
                elif ',' in my_bands:
                    # individual bands in commandline
                    if ',' in my_bands:
                        # multiple bands specified
                        bands = [ str(b) for b in my_bands.split(',') if str(b) in bands_l]
                        bands_l = bands
                else:
                    # single band specified
                    bands_l = [my_bands]
            if '-min:' in arg:
                # minimum length set in commandline
                minimum = float(arg.split('-min:')[1])
            if '-max:' in arg:
                # maximum length set in commandline
                maximum = float(arg.split('-max:')[1])
            if '-margin:' in arg:
                # margin set in commandline
                margin = float(arg.split('-margin:')[1])
            if '-res:' in arg:
                metric_res = int(arg.split('-res:')[1])
            if '-range:' in arg:
                # customer frequency range specified
                low = int(arg.split('-range:')[1].split('-')[0])
                high = int(arg.split('-range:')[1].split('-')[1])
                bands_d = {"custom":{"low":low, "high":high}}
                bands_l = ["custom"]
    print()
    print()
    print('-------------------------------------------------------------------')
    print('Random Longwire Antenna Calculation')
    print('Input parameters:')
    print('-------------------------------------------------------------------')
    print('Bands         : {}'.format(str(bands_l)))
    if bands_l == ['custom']:
        print('Range         : {}-{} kHz'.format(str(bands_d['custom']['low']), 
                                                 str(bands_d['custom']['high'])))
    print('Minimum factor: {}   (of lowest frequency)'.format(str(minimum).ljust(5)))
    print('Maximum factor: {}   (of lowest frequency)'.format(str(maximum).ljust(5)))
    print('Margin        : {} % (band edge adjustment)'.format(str(margin).ljust(5)))
    print('-------------------------------------------------------------------')
    print()
    my_lengths = main(bands_d, bands_l, minimum, maximum, margin, metric_res)
    print()
    print('-------------------------------------------------------------------')
    print(' Results:')
    print('-------------------------------------------------------------------')
    if len(my_lengths) == 0:
        print('No wirelengths found with current parameters')
        print('-------------------------------------------------------------------')
    else:
        for lengths in my_lengths:
            if lengths != []:
                print(' from {} to {} meters (mid {} m)'.format(str(lengths[0]).ljust(6),
                                                                str(lengths[1]).ljust(6),
                                                                str(round((lengths[0] + lengths[1])/2, metric_res)).ljust(6)))
        
###############################################################################
## END                                                                       ##
###############################################################################
$\endgroup$
1
  • $\begingroup$ (Tangentially, code you put in if __name__ == '__main__’: should be trivial; the purpose of this boilerplate is to allow you to import the code, which you will not want to do anyway if the logic you need is not available via import. See also stackoverflow.com/a/69778466/874188) $\endgroup$
    – tripleee
    Nov 14, 2022 at 7:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .