So what is the best way to test various gain levels on the pro-stick without having to wait 24 hours for stats on the dashboard to populate? Is the best way to just look at your local dump1090 web interface and eyeball it?
I really hope someone with the knowledge does a comprehensive write up on this matter. I guess we are quite few out there with the same issue regarding the gain adjustments.
What i really would like to see is a guide how to interpret the charts from dump1090 mutability, and what levels one should try to reach.
It is not easy. Each setup is different.
Someone could write a program to run for a few hours to work it out.
I have had good results running at 30/35 and max. I get a much lower noise floor at the 30/35 settings.
I am still experimenting. One change at a time.
No - the gain adjustment is not changing the amplification of the extra LNA installed on the ProStick - same as with the standard dongles, it’s changing the gain of the amp that’s part of the tuner.
The additional LNA featured in the pro-stick has a fixed gain value.
The core concept behind the ProStick is the inclusion of the fixed-gain, higher quality, lower noise LNA should allow you to use a lower tuner gain setting - since the amp in the tuner introduces far more noise.
I wrote a script to sort of do this. I only ran for 15 second intervals because the amount of traffic can change a lot throughout the day. But you can try different durations.
Here’s the code. It’s pretty dumb (like it just waits 2 seconds after starting dump1090 rather than checking to see if dump1090 is actually ready). You probably want to change the measure_duration, ntests, and gains variables at the top.
Stop any existing dump1090 process before running the script. sudo /etc/init.d/fadump1090.sh stop or **sudo service dump1090-mutability stop
**
#!/usr/bin/python2
import time, socket, subprocess
measure_duration = 15 #seconds
ntests = 10 #Number of tests
mutability = False #set to True if you use dump1090-mutability
#gains = "20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6".split()
gains = "36.4 38.6 40.2 42.1 44.5 48.0 49.6".split()
#gains = "22.9 25.4 28.0 29.7 32.8 33.8 36.4".split()
gains.reverse()
results = {}
for i in range(ntests):
print "test", i+1, "of", ntests
for g in gains:
if g not in results:
results[g] = [0,0,{}] #msgs, positions, aircraft
if mutability:
p = subprocess.Popen(('/usr/bin/dump1090-mutability --net --gain '+g+' --oversample --fix --phase-enhance --quiet').split(),shell=False,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
p = subprocess.Popen(('/usr/bin/dump1090 --net --gain '+g+' --quiet').split(),shell=False,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(2)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost',30003))
t = time.time()
d = ''
while 1:
d += s.recv(32)
if time.time() - t > measure_duration:
break
s.close()
p.terminate()
messages = 0
positions = 0
planes = {}
for l in d.split('
'):
a = l.split(',')
messages += 1
if len(a) > 4:
if a[1] == '3':
positions += 1
planes[a[4]] = 1
print "gain=",g, "messages=", messages, "positions=", positions, "planes=", len(planes.keys())
results[g][0] += messages
results[g][1] += positions
for hex in planes.keys():
results[g][2][hex] = 1
print "
===Totals==="
print "Gain, Messages, Positions, Aircraft"
for g in gains:
(messages,positions,planes) = results[g]
print g, messages, positions, len(planes.keys())
So, really, the object is to run the gain as low as possible as long as you can still get traffic at your “maximum” range…? Is the advice to run “max gain” if you’re using a filter necessarily accurate then?
That’s a very interesting idea, thanks for providing the Python script. Just ran it against a ProStick with a full range of allowed gain values and the same 15 second interval. Just as you found, the results are highly inconclusive!
FWIW, I normalize the raw values into ADSB messages per ADSB aircraft (excluding MLAT). There’s too much variability IMO to look at time slices of message and aircraft quantities. I also run for at least 24 hours to collect enough data points and compare the percent change delta to the previous day, then choose a neighboring site to see how much that site changed and whether I’m +/-. I only tune in real time for gross gain adjustments.
That’s how I do it anyway…with a SQL database to store the values over a longer period than available on the FA stats page.
I also have had mixed results trying to dial in gain, I think the issue is the variation of traffic during the sample times.
Just had an idea. What if you set this up so that you ran two dongles, both fed from the same antenna via a splitter? Use one dongle as the reference and the other as the variable to test gain?
You would lose sensitivity with the splitter, but it would only be used for calibration.
The splitter idea is good but you could also use the data from a second system as a reference. The data rate changes from traffic changes would be evident on a second nearby system. Perhaps even a friends system in the same general area.
My setup is Cantenna → Inline Amp → DC Power → Splitter →
Raspberry Pi B+, Regular tuner / Gain 42
Raspberry Pi 3, Pro Tuner, FA Filter / Gain 16.6
(Note: My cantenna is on my second story roof and followed by about 40 feet of coax)
I came to these gain numbers mostly by trial and error with my baseline receiver being the B+. I then compared results between the two to get the gain to where it is on the Pi 3. The Pi 3 does slightly better, most likely due to the filter.
I have graphs setup on the Pi 3 as it is a fresh install using Dump1090-Muta/PiAware add-on and the B+ is a vanilla PiAware image.
I would be interested in some more in depth tuning information as most of my results are pure speculation…
Realized I was being dumb when running the above Python script. I hadn’t killed my usual dump1090 instance so all I was doing was reading the same values again and again!
I modified the script to allow simultaneous testing with normal dump1090 operation and got somewhat more likely results where the figures drop off at lower gain values once you get below a threshold. I’m going to run it again over a 24 hour period (about 250 iterations rather than 10) and see how that looks.
This illustrates an interesting phenomenon. The maxima for messages and the maxima for aircraft do not necessarily occur at the same gain. I’ve personally noticed that I can increase a/c count with more gain but at the expense of message count.
Happy to do so, but be warned, this will mess up your local collectd stats. Depending on the timing between when collectd samples and the gain levels switching you’ll likely see some strange results. However, the overall average won’t change much and you’ll keep feeding data to FA. The constant rebooting of dump1090 will also break MLAT for the duration of the test. It’s a fairly crude hack of BartJr’s code that rewrites the dump1090-mutability config file with a different gain and then restarts dump1090. Please don’t use this unless you are prepared to deal with all that. No warranty is implied or should be inferred, if it breaks you get to keep both pieces!
PS - If someone knows a cleaner way of restarting dump1090 with a different gain, then please post it.
#!/usr/bin/python2
import time, socket, subprocess, fileinput, os
measure_duration = 62 #seconds
ntests = 10
gains = "20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6".split()
#gains = "36.4 38.6 40.2 42.1 44.5 48.0 49.6".split()
#gains = "22.9 25.4 28.0 29.7 32.8 33.8 36.4".split()
gains.reverse()
results = {}
for i in range(ntests):
print "test", i+1, "of", ntests
for g in gains:
if g not in results:
results[g] = [0,0,{}] #msgs, positions, aircraft
for line in fileinput.input('/etc/default/dump1090-mutability', inplace=1):
if line.startswith('GAIN'):
print 'GAIN='+g
else:
print line,
os.system("sudo /etc/init.d/dump1090-mutability restart")
time.sleep(2)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost',30003))
t = time.time()
d = ''
while 1:
d += s.recv(32)
if time.time() - t > measure_duration:
break
s.close()
messages = 0
positions = 0
planes = {}
for l in d.split('
'):
a = l.split(',')
messages += 1
if len(a) > 4:
if a[1] == '3':
positions += 1
planes[a[4]] = 1
print "gain=",g, "messages=", messages, "positions=", positions, "planes=", len(planes.keys())
results[g][0] += messages
results[g][1] += positions
for hex in planes.keys():
results[g][2][hex] = 1
print "
===Totals==="
print "Gain, Messages, Positions, Aircraft"
for g in gains:
(messages,positions,planes) = results[g]
print g, messages, positions, len(planes.keys())