-
Notifications
You must be signed in to change notification settings - Fork 0
/
electronics-voltage-divider
executable file
·129 lines (115 loc) · 3.5 KB
/
electronics-voltage-divider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/perl
use v5.36;
use Getopt::Lucid qw(:all);
use bansi; # Custom coloring library for terminal output
use utf8;
use FindBin;
use lib $ourdir;
my $aval=$bcya;
my $asym=$gra;
my $amath=$yel;
my $symv = "${asym}V";
my $symohm = "${asym}Ω";
binmode *STDOUT, "encoding(utf-8)";
# Define command-line specifications
my $argslen = @ARGV;
my @specs = (
Param("r1|r")->default(undef)
->valid(qr/^\d+(\.\d+)?[kKmM]?[ohmOHM]{0,3}$/)
->doc("Specify R1 resistance in Ohms, kilohms (e.g., 10k or 10kohm), or megaohms (e.g., 1M or 1Mohm)"),
Param("r2")->default(undef)
->valid(qr/^\d+(\.\d+)?[kKmM]?[ohmOHM]{0,3}$/)
->doc("Specify R2 resistance"),
Param("vin|v")->default(undef)
->valid(qr/^\d+(\.\d+)?[vV]$/)
->doc("Specify the input voltage (Vin) in volts (e.g., 5V)"),
Switch("quiet|q")
->doc("Quiet normal output (only output calculated value(s))"),
Switch("ratio")
->doc("Calculate and return the resistance ratio R2/(R1+R2) only"),
Switch("help|h")
->anycase()
->doc("Display this help message and exit"),
);
# Create the option parser and parse command line
my $opt = Getopt::Lucid->getopt(\@specs)->validate;
sub print_eqns {
say <<~"EOT";
$bgblu$yel---- ${whi}Voltage Divider Equations: $yel----${rst}
${bcya}Basic Voltage Divider Formula:${rst}
Vout = Vin × (R2 / (R1 + R2))\n
${bgre}Where:${rst}
${bblu}Vout${rst} - Output voltage across R2
${bblu}Vin${rst} - Input voltage to the circuit
${bblu}R1${rst} - Resistance of the first resistor connected to Vin
${bblu}R2${rst} - Resistance of the second resistor connected to ground\n
${bgre}Usage Examples:${rst}
Calculate Vout given R1, R2, and Vin:
$0 --r1 10k --r2 5k --vin 12V
Calculate the ratio R2/(R1 + R2):
$0 --r1 10k --r2 5k --ratio
EOT
}
# Display help if requested
if ($opt->get_help || $argslen < 1) {
say '';
print_eqns();
print $opt->usage();
say '';
exit;
}
# Function to parse resistance values
sub parse_resistance {
my $res = shift;
if ($res =~ /^(\d+(\.\d+)?)([kmKM]?)(ohm)?$/i) {
my $value = $1;
my $unit = lc $3;
$value *= 1000 if $unit eq 'k';
$value *= 1000000 if $unit eq 'm';
return $value;
}
die "${bgred}Error:${rst} Invalid resistance value '$res'\n";
}
# Function to calculate output voltage
sub calculate_vout {
my ($r1, $r2, $vin) = @_;
$r1 = parse_resistance($r1);
$r2 = parse_resistance($r2);
$vin =~ s/[vV]$//; # Remove the 'V' from voltage input
say "$aval${vin}$symv $amath* ($aval${r2}$symohm$amath / ($amath$aval${r1}$symohm $amath+ $aval${r2}$symohm$amath))" if ! $opt->get_quiet;
return $vin * ($r2 / ($r1 + $r2));
}
sub parse_shorthand_args {
if (@ARGV < 3) {
say STDERR "${bred}Shorthand use requires r1 r2 Vin. See -h for help.";
exit 1;
} else {
my ($r1, $r2, $vin) = @ARGV;
$opt->set_r1($r1);
$opt->set_r2($r2);
$opt->set_vin($vin);
}
}
if (@ARGV) {
parse_shorthand_args();
}
# Execute calculations based on provided options
if ($opt->get_vin && $opt->get_r1 && $opt->get_r2 && !$opt->get_ratio) {
my $vout = calculate_vout($opt->get_r1, $opt->get_r2, $opt->get_vin);
if (! $opt->get_quiet) {
printf "Output Voltage (Vout): ${bgre}%.2f$symv$rst\n", $vout;
} else {
printf "%.2fV\n", $vout;
}
} elsif ($opt->get_ratio) {
my $r1 = parse_resistance($opt->get_r1);
my $r2 = parse_resistance($opt->get_r2);
my $ratio = $r2 / ($r1 + $r2);
if (! $opt->get_quiet) {
printf "Resistance Ratio (R2/(R1+R2)): ${bcya}%.4f${rst}\n", $ratio;
} else {
printf "%.4f\n", $ratio;
}
} else {
print $opt->usage();
}