File Coverage

blib/lib/RF/Functions.pm
Criterion Covered Total %
statement 38 38 100.0
branch 6 6 100.0
condition n/a
subroutine 19 19 100.0
pod 13 13 100.0
total 76 76 100.0


line stmt bran cond sub pod time code
1             package RF::Functions;
2 1     1   74857 use strict;
  1         3  
  1         29  
3 1     1   12 use warnings;
  1         3  
  1         25  
4 1     1   579 use POSIX qw{log10};
  1         7014  
  1         6  
5 1     1   1498 use base qw{Exporter};
  1         3  
  1         163  
6 1     1   553 use Math::Round qw{};
  1         1227  
  1         537  
7              
8             our $VERSION = '0.04';
9             our @EXPORT_OK = qw(
10             db_ratio ratio2db
11             ratio_db db2ratio
12             fsl_hz_m fsl_mhz_km fsl_ghz_km fsl_mhz_mi
13             dbd_dbi dbi_dbd dbd2dbi dbi2dbd dipole_gain
14             );
15              
16             =head1 NAME
17              
18             RF::Functions - Perl Exporter for Radio Frequency (RF) Functions
19              
20             =head1 SYNOPSIS
21              
22             use RF::Functions qw{db_ratio ratio_db};
23             my $db = db_ratio(2); #~3dB
24              
25             =head1 DESCRIPTION
26              
27             RF::Functions is a lib for common RF function. I plan to add additional functions as I need them.
28              
29             =head1 FUNCTIONS
30              
31             =head2 db_ratio, ratio2db
32              
33             Returns dB given a numerical power ratio.
34              
35             my $db = db_ratio(2); #+3dB
36             my $db = db_ratio(1/2); #-3dB
37              
38             =cut
39              
40 2     2 1 99 sub db_ratio {10 * log10(shift())};
41              
42 2     2 1 16 sub ratio2db {10 * log10(shift())};
43              
44             =head2 ratio_db, db2ratio
45              
46             Returns power ratio given dB.
47              
48             my $power_ratio = ratio_db(3); #2
49              
50             =cut
51              
52 2     2 1 17 sub ratio_db {10 ** (shift()/10)};
53              
54 2     2 1 15 sub db2ratio {10 ** (shift()/10)};
55              
56             =head2 dbi_dbd, dbd2dbi
57              
58             Returns dBi given dBd. Converts the given antenna gain in dBd to dBi.
59              
60             my $eirp = dbi_dbd($erp);
61              
62             =cut
63              
64 1     1 1 19 sub dbi_dbd {shift() + dipole_gain()};
65              
66 1     1 1 3 sub dbd2dbi {shift() + dipole_gain()};
67              
68             =head2 dbd_dbi, dbi2dbd
69              
70             Returns dBd given dBi. Converts the given antenna gain in dBi to dBd.
71              
72             my $erp = dbd_dbi($eirp);
73              
74             =cut
75              
76 1     1 1 4 sub dbd_dbi {shift() - dipole_gain()};
77              
78 1     1 1 4 sub dbi2dbd {shift() - dipole_gain()};
79              
80             =head2 dipole_gain
81              
82             Returns the gain of a reference half-wave dipole in dBi.
83              
84             my $dipole_gain = dipole_gain(); #always 2.15 dBi
85              
86             =cut
87              
88 5     5 1 340 sub dipole_gain {2.15}; #FCC 10Log(1.64) ~ 2.15
89              
90             =head2 fsl_hz_m, fsl_mhz_km, fsl_ghz_km, fsl_mhz_mi
91              
92             Return power loss in dB given frequency and distance in the specified units of measure
93              
94             my $free_space_loss = fsl_mhz_km($mhz, $km); #returns dB
95              
96             =cut
97              
98             sub fsl_hz_m {
99 1     1 1 310 my ($f, $d) = @_;
100 1         4 return _fsl_constant($f, $d, -147.55);
101             }
102              
103             sub fsl_mhz_km {
104 3     3 1 896 my ($f, $d) = @_;
105 3         8 return _fsl_constant($f, $d, 32.45);
106             }
107              
108             sub fsl_ghz_km {
109 1     1 1 344 my ($f, $d) = @_;
110 1         3 return _fsl_constant($f, $d, 92.45);
111             }
112              
113             sub fsl_mhz_mi {
114 1     1 1 349 my ($f, $d) = @_;
115 1         3 return _fsl_constant($f, $d, 36.58); #const = 20*log10(4*pi/c) where c = 0.18628237 mi/μs (aka mile * MHz)
116             }
117              
118             sub _fsl_constant {
119 7 100   7   818 my $freq = shift; die("Error: Frequency must be positive number") unless $freq > 0;
  7         41  
120 6 100       10 my $dist = shift; die("Error: Distance must be non-negative number") unless $dist >= 0;
  6         21  
121 5 100       17 my $const = shift or die("Error: Constant required");
122             #Equvalent to 20log($freq) + 20log($dist) + $const for performance
123 4         33 return Math::Round::nearest(0.001, 20 * log10($freq * $dist) + $const);
124             }
125              
126             =head1 SEE ALSO
127              
128             L, L
129              
130             L
131              
132             L
133              
134             L
135              
136             =head1 AUTHOR
137              
138             Michael R. Davis, MRDVT
139              
140             =head1 COPYRIGHT AND LICENSE
141              
142             MIT LICENSE
143              
144             Copyright (C) 2022 by Michael R. Davis
145              
146             =cut
147              
148             1;