From: Keith Packard Date: Mon, 10 Feb 2025 22:42:41 +0000 (-0800) Subject: bin: Add resistor divider calculator X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=7155ca3d0d0e124c107e061b4524d9c4271da011;p=hw%2Faltusmetrum bin: Add resistor divider calculator Signed-off-by: Keith Packard --- diff --git a/bin/divider b/bin/divider new file mode 100755 index 0000000..62844ba --- /dev/null +++ b/bin/divider @@ -0,0 +1,88 @@ +#!/usr/bin/nickle +# +# Compute resistor dividers +# +# + +if (dim(argv) != 3) { + File::fprintf(stderr, "usage: %s \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);