####################################################### #Copyright GPL v2.0 (but not v3.0) #Author David A. Bandel # #Instructions: #This file must be cut into two files, each file starting with the #shebang perl line (#!/usr/bin/perl -T). The first file should be called #rfcalcs.pl and the second results.pl #Put them in your cgi-bin directory and ensure your web server runs them. # #If your perl compiler is elsewhere, please edit the shebang line. # #This software also requires the following Perl modules: #CGI #Math::Cephes #Geo::Distance #Location::GeoTool #you can use `perl -MCPAN -e shell` and install the modules using #MCPAN's install command. # #-----begin rfcalcs.pl-------# #!/usr/bin/perl -T use strict; use CGI; my $q = new CGI; my %arr = $q->Vars; my $megahertz=$arr{megahertz}; my $miles=$arr{miles}; my $kilometers=$arr{kilometers}; my $rxsens=$arr{rxsens}; my $rxsens2=$arr{rxsens2}; my $txcblloss=$arr{txcblloss}; my $txantgain=$arr{txantgain}; my $rxantgain=$arr{rxantgain}; my $rxcblloss=$arr{rxcblloss}; my $watts=$arr{watts}; my $watts2=$arr{watts2}; my $milliwatts=$arr{milliwatts}; my $milliwatts2=$arr{milliwatts2}; my $dbm=$arr{dbm}; my $dbm2=$arr{dbm2}; my $fsl; my $rxsig; my $rxsig2; my $fresnel; my $snr; my $snr2; my $eirp; my $eirpw; my $eirp2; my $eirpw2; my $unit="mile"; my $lon1=$arr{lon1}; my $long1=$arr{long1}; my $lat1=$arr{lat1}; my $lati1=$arr{lati1}; my $lon2=$arr{lon2}; my $long2=$arr{long2}; my $lat2=$arr{lat2}; my $lati2=$arr{lati2}; my $north=$arr{north}; my $south=$arr{south}; my $west=$arr{west}; my $east=$arr{east}; my $locobj=$arr{locobj}; my $dirobj=$arr{dirobj}; my $dir=$arr{dir}; my $units=$arr{units}; my $dist=$arr{dist}; my $power1=$arr{power1}; my $power2=$arr{power2}; my $pwrunit1=$arr{pwrunit1}; my $pwrunit2=$arr{pwrunit2}; ## Some sensible defaults ## if (! $rxsens) { $rxsens = -86; } if (! $rxsens2) { $rxsens2 = -86; } if (! $units) { $units = "miles"; } if (! $pwrunit1) { $pwrunit1 = "decibels"; } if (! $pwrunit2) { $pwrunit2 = "decibels"; } if (! $megahertz) { $megahertz = "5800" ; } my $cgi=new CGI; print $cgi->header; print < RF Calculations Page

Radio Frequency Calculations Page for Internet Radios (DSSS, FHSS, OFDM)

Most RF calculation pages only give you half the story unless your two endpoints happen to be identical (most aren't). Since we are usually interested in two-way behavior, we have to perform the calculations twice (once for each direction). This page will allow you to fill in all the information on each site and will provide you, at a glance, a good indication of what you should expect to see excepting environmental conditions (including but not limited to interference and second and fourth fresnel zone signal cancellation effects).

NOTE: Form is based on accepted calculations for 1000MHz (1GHz) to 6000MHz (6GHz). Use for other frequencies not recommended and may yield inaccurate results.

Distance calculations (if you have the Geos but not the distance)

Site A TX: N S W E
Site B TX: N S W E

Geo coords must be in the form of Degrees:Minutes:Seconds or Degrees:Minutes.decimals or Degrees.decimals.

Distance Site A to Site B:
Frequency: MHz (not GHz)
TX Power Site A*:
TX Power Site B*:
TX Antenna gain Site A: db
TX Antenna gain Site B: db.
Optional values:
RX Sensitivity Site A: db
RX Sensitivity Site B: db
Cable Loss Site A**: db
Cable Loss Site B**: db

*Transmitter output power. If you are using an amplifier or frequency converter, this is the output power of that amp or frequency converter.
**Cable loss should be the combined loss of cables, connectors, splitters, etc., between the transmitter output (radio card, amp, or frequency converter) and the antenna.

Form created by David A. Bandel, AI4FG, HP1DAB
Released under the GPL. Code available here.

EOF #------end rfcalcs.pl-----------# #------begin results.pl---------# #!/usr/bin/perl -T use strict; use CGI; use Math::Cephes qw(:all); use Geo::Distance; use Location::GeoTool; my $q = new CGI; my %arr = $q->Vars; my $megahertz=$arr{megahertz}; my $miles=$arr{miles}; my $kilometers=$arr{kilometers}; my $rxsens=$arr{rxsens}; my $rxsens2=$arr{rxsens2}; my $txcblloss=$arr{txcblloss}; my $txantgain=$arr{txantgain}; my $rxantgain=$arr{rxantgain}; my $rxcblloss=$arr{rxcblloss}; my $watts=$arr{watts}; my $watts2=$arr{watts2}; my $milliwatts=$arr{milliwatts}; my $milliwatts2=$arr{milliwatts2}; my $dbm=$arr{dbm}; my $dbm2=$arr{dbm2}; my $fsl; my $rxsig; my $rxsig2; my $fresnel; my $fresm; my $snr; my $snr2; my $eirp; my $eirpw; my $eirp2; my $eirpw2; my $unit="mile"; my $lon1=$arr{lon1}; my $long1=$arr{long1}; my $lat1=$arr{lat1}; my $lati1=$arr{lati1}; my $lon2=$arr{lon2}; my $long2=$arr{long2}; my $lat2=$arr{lat2}; my $lati2=$arr{lati2}; my $north=$arr{north}; my $south=$arr{south}; my $west=$arr{west}; my $east=$arr{east}; my $locobj=$arr{locobj}; my $dirobj=$arr{dirobj}; my $dir=$arr{dir}; my $units=$arr{units}; my $dist=$arr{dist}; my $power1=$arr{power1}; my $power2=$arr{power2}; my $pwrunit1=$arr{pwrunit1}; my $pwrunit2=$arr{pwrunit2}; ## Some sensible defaults ## #if (! $rxsens) { $rxsens = -86; } #if (! $rxsens2) { $rxsens2 = -86; } #if (! $units) { $units = "miles"; } #if (! $pwrunit1) { $pwrunit1 = "decibels"; } #if (! $pwrunit2) { $pwrunit2 = "decibels"; } #if (! $megahertz) { $megahertz = "5800" ; } my $geo = new Geo::Distance; my $cgi=new CGI; print $cgi->header; print < RF Calculations Results Page EOF $lon1=$long1; $lat1=$lati1; $lon2=$long2; $lat2=$lati2; if ($lon1 && $lat1 && $lon2 && $lat2) { my @decimal=split(/:/,$lon1); $lon1=$decimal[0] + ($decimal[1]/60) + ($decimal[2]/3600); @decimal=split(/:/,$lat1); $lat1=$decimal[0] + ($decimal[1]/60) + ($decimal[2]/3600); @decimal=split(/:/,$lon2); $lon2=$decimal[0] + ($decimal[1]/60) + ($decimal[2]/3600); @decimal=split(/:/,$lat2); $lat2=$decimal[0] + ($decimal[1]/60) + ($decimal[2]/3600); if ($north eq "S") { $lat1=(-1*$lat1); } if ($east eq "E") { $lon1=(-1*$lon1); } if ($south eq "S") { $lat2=(-1*$lat2); } if ($west eq "E") { $lon2=(-1*$lon2); } $miles=sprintf("%.2f",$geo->distance($unit,$lon1,$lat1 => $lon2,$lat2)); $locobj = Location::GeoTool->create_coord($lat1,$lon1,'wgs84','degree'); $dirobj = $locobj->direction_point($lat2,$lon2,'wgs84','degree'); $dir = sprintf("%.2f",$dirobj->direction); } if ($dist) { if ($units eq "miles") { $miles=$dist; $kilometers=sprintf("%.3f",$miles / 0.62137119); } else { $kilometers=$dist; $miles=sprintf("%.3f",$kilometers * 0.62137119); } } if ($power1) { if ($pwrunit1 eq "decibels") { $dbm=$power1; $milliwatts=sprintf("%.3f",(10**($dbm/10))); $watts=sprintf("%.3f",$milliwatts/1000); } elsif ($pwrunit1 eq "watts") { $watts=$power1; $milliwatts=$watts * 1000; $dbm=sprintf("%.3f",10 * log10($milliwatts)); } else { $milliwatts=$power1; $dbm=sprintf("%.3f",10 * log10($milliwatts)); $watts=$milliwatts/1000; } } if ($power2) { if ($pwrunit2 eq "decibels") { $dbm2=$power2; $milliwatts2=sprintf("%.3f",(10**($dbm2/10))); $watts2=sprintf("%.3f",$milliwatts2/1000); } elsif ($pwrunit2 eq "watts") { $watts2=$power2; $milliwatts2=$watts2 * 1000; $dbm2=sprintf("%.3f",10 * log10($milliwatts2)); } else { $milliwatts2=$power2; $dbm2=sprintf("%.3f",10 * log10($milliwatts2)); $watts2=$milliwatts2/1000; } } if ($miles && $megahertz) { $fresnel=sprintf("%.1f",72.05 * sqrt($miles/($megahertz / 1000))); $fresm=sprintf("%.1f",72.05 / 3.2808399 * sqrt($miles/($megahertz /1000))); $fsl=sprintf("%.0f",20*log10($megahertz)+20*log10($miles)+36.6); } if (!$txcblloss) { $txcblloss="0"; } if (!$rxcblloss) { $rxcblloss="0"; } if ($dbm && $txantgain && $rxantgain) { $rxsig=sprintf("%.f",$dbm - $txcblloss + $txantgain - $fsl - $rxcblloss + $rxantgain); } if ($dbm2 && $txantgain && $rxantgain) { $rxsig2=sprintf("%.f",$dbm2 - $rxcblloss + $rxantgain - $fsl - $txcblloss + $txantgain); } if ($rxsig) { $snr = sprintf("%.f",$rxsig - $rxsens2); } if ($rxsig2) { $snr2 = sprintf("%.f",$rxsig2 - $rxsens); } if ($dbm && $txantgain && $rxantgain) { $eirp=sprintf("%.f",$dbm - $txcblloss + $txantgain); } if ($eirp) { $eirpw=sprintf("%.3f",((10**($eirp/10))/1000)); } if ($dbm2 && $txantgain && $rxantgain) { $eirp2=sprintf("%.f",$dbm2 - $rxcblloss + $rxantgain); } if ($eirp2) { $eirpw2=sprintf("%.3f",((10**($eirp2/10))/1000)); } print < Fresh calculations page

Calculation Results:

Distance $miles miles or $kilometers kilometers.

(First) Fresnel zone radius: $fresnel ft / $fresm meters.
Free Space loss: $fsl db.

TX Power site A: $dbm decibels, $milliwatts mW, or $watts W.
TX Power site B: $dbm2 decibels, $milliwatts2 mW, or $watts2 W.

Signal seen by receiver A is $rxsig2 db.
Signal seen by receiver B is $rxsig db.

SNR at Site A is $snr2 db.
SNR at Site B is $snr db.

EIRP Site A $eirp db or $eirpw watts. (Note: Are we legal? If over 4 watts, better check.)
EIRP Site B $eirp2 db or $eirpw2 watts. (See note above, some frequencies may be restricted to even less power.)

If the SNR value >=10, and you have little or no fresnel zone encroachment, expect a usable signal if the antennas are properly aligned and you have no adjacent channel interference. While I've had usable links as low as 3db, I don't recommend it.

Home
Form created by David A. Bandel, AI4FG, HP1DAB
Released under the GPL. Code available here.

EOF #------end results.pl-----------# # #Please e-mail all comments, criticisms, witicisms, patches, etc. to: #david dot bandel at gmail dot com # #If anyone actually knows how to calculate degrees from site A to site B #please let me know. # #Thanx, # #David A. Bandel #