]> git.gag.com Git - hw/altusmetrum/commitdiff
bin: Add resistor divider calculator
authorKeith Packard <keithp@keithp.com>
Mon, 10 Feb 2025 22:42:41 +0000 (14:42 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 10 Feb 2025 22:42:41 +0000 (14:42 -0800)
Signed-off-by: Keith Packard <keithp@keithp.com>
bin/divider [new file with mode: 0755]

diff --git a/bin/divider b/bin/divider
new file mode 100755 (executable)
index 0000000..62844ba
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/nickle
+#
+# Compute resistor dividers
+#
+#
+
+if (dim(argv) != 3) {
+       File::fprintf(stderr, "usage: %s <input voltage> <output voltage>\n", argv[0]);
+       exit(1);
+}
+
+real input = atof(argv[1]);
+real output = atof(argv[2]);
+
+real[...] resistors = {
+       10.0,   10.2,   10.5,   10.7,   11.0,   11.3,   11.5,   11.8,   12.1,   12.4,   12.7,   13.0,
+       13.3,   13.7,   14.0,   14.3,   14.7,   15.0,   15.4,   15.8,   16.2,   16.5,   16.9,   17.4,
+       17.8,   18.2,   18.7,   19.1,   19.6,   20.0,   20.5,   21.0,   21.5,   22.1,   22.6,   23.2,
+       23.7,   24.3,   24.9,   25.5,   26.1,   26.7,   27.4,   28.0,   28.7,   29.4,   30.1,   30.9,
+       31.6,   32.4,   33.2,   34.0,   34.8,   35.7,   36.5,   37.4,   38.3,   39.2,   40.2,   41.2,
+       42.2,   43.2,   44.2,   45.3,   46.4,   47.5,   48.7,   49.9,   51.1,   52.3,   53.6,   54.9,
+       56.2,   57.6,   59.0,   60.4,   61.9,   63.4,   64.9,   66.5,   68.1,   69.8,   71.5,   73.2,
+       75.0,   76.8,   78.7,   80.6,   82.5,   84.5,   86.6,   88.7,   90.9,   93.1,   95.3,   97.6,
+       100.0,
+};
+
+real divider(real input, real ra, real rb)
+{
+       return input * rb / (ra + rb);
+}
+
+real find_ra(real input, real output, real rb)
+{
+       real ra;
+       /* output = input * rb / (ra + rb)
+        * output / (input * rb) = 1 / (ra + rb)
+        * (input * rb) / output = ra + rb
+        * (input * rb) / output - rb = ra
+        */
+
+       return (input * rb) / output - rb;
+}
+
+real error(real input, real output, real ra, real rb)
+{
+       real actual = divider(input, ra, rb);
+
+       real e = abs(actual - output);
+       return e;
+}
+
+real closest_standard(real ohms)
+{
+       real exp = floor(log10(ohms));
+       real mul = pow(10,exp + 1);
+       real search = ohms * mul;
+
+       for (int i = 0; i < dim(resistors)-1; i++) {
+               if (resistors[i] <= search && search <= resistors[i+1])
+                       if (abs(resistors[i] - search) < abs(resistors[i]+1 - search)) {
+                               return resistors[i] / mul;
+                       } else {
+                               return resistors[i+1] / mul;
+                       }
+       }
+       return 0;
+}
+
+void find_divider(real input, real output)
+{
+       real    best_a, best_b;
+       real    best_error = -1;
+
+       for (int i = 0; i < dim(resistors); i++) {
+               real rb = resistors[i];
+               real ra_ideal = find_ra(input, output, rb);
+               real ra_actual = closest_standard(ra_ideal);
+               real e = error(input, output, ra_actual, rb);
+               if (best_error < 0 || e < best_error) {
+                       best_a = ra_actual;
+                       best_b = rb;
+                       best_error = e;
+               }
+       }
+       printf("input: %g ra: %g rb: %g output %g\n", input, best_a, best_b, divider(input, best_a, best_b));
+}
+
+find_divider(input, output);