This is a simple program that does a simple but often needed thing - prints the closest 1% (E96) or 5% (E24) resistor value from an entered desired value...
Although it's easy enough to consult a resistor value table from
the web, this is easier, especially handy when using trimpots to
dial in a circuit. For more information check out the Wikipedia
page for the E
series of preferred numbers.
Download the fcrval.zip
file for compiled binaries for Linux and Windows plus the
QBasic source code and docs.
Here's the QBasic source code...
REM a program for finding standard resistor values REM by WTN, last mods 20180117 20210412 20250514 PRINT "===== Find Closest Resistor Value =====" PRINT "Finds the closest stock 1% and 5% resistor values." PRINT "Entry can include K or M suffix, output is standard" PRINT "resistor notation. Enter an empty value to exit." DIM valueE96(97), valueE24(25) REM E96 values, extra decade value at the end to simplify code DATA 100,102,105,107,110,113,115,118,121,124,127,130,133,137 DATA 140,143,147,150,154,158,162,165,169,174,178,182,187,191 DATA 196,200,205,210,215,221,226,232,237,243,249,255,261,267 DATA 274,280,287,294,301,309,316,324,332,340,348,357,365,374 DATA 383,392,402,412,422,432,442,453,464,475,487,499,511,523 DATA 536,549,562,576,590,604,619,634,649,665,681,698,715,732 DATA 750,768,787,806,825,845,866,887,909,931,953,976,1000 FOR i = 1 TO 97: READ valueE96(i): NEXT i REM E24 values+decade DATA 10,11,12,13,15,16,18,20,22,24,27,30 DATA 33,36,39,43,47,51,56,62,68,75,82,91,100 FOR i = 1 TO 25: READ valueE24(i): NEXT i entervalue: LINE INPUT "Desired value: ", desired$ desired$ = LTRIM$(RTRIM$(UCASE$(desired$))) IF desired$ = "" THEN GOTO exitprogram IF LEFT$(desired$, 1) = CHR$(0) THEN GOTO exitprogram mult = 1: num$ = desired$ IF RIGHT$(desired$, 1) = "K" THEN mult = 1000: num$ = LEFT$(num$, LEN(num$) - 1) IF RIGHT$(desired$, 1) = "M" THEN mult = 1000000: num$ = LEFT$(num$, LEN(num$) - 1) REM num$ must contain only 0-9 and no more than one decimal point E = 0: E1 = 0: PC = 0 FOR i = 1 TO LEN(num$) a$ = MID$(num$, i, 1) IF ASC(a$) < ASC("0") OR ASC(a$) > ASC("9") THEN E1 = 1 IF a$ = "." THEN E1 = 0: PC = PC + 1 IF E1 = 1 THEN E = 1 NEXT i IF E = 0 AND PC < 2 THEN GOTO entryok PRINT "Don't understand that, try again" GOTO entervalue entryok: REM calculate desired value from string and multiplier desiredR = VAL(num$) * mult IF desiredR >= .1 AND desiredR <= 100000000 THEN GOTO valueok PRINT "Value must be from 0.1 to 100M" GOTO entervalue valueok: REM determine multiplier to convert stored values norm = .001 IF desiredR >= 1 THEN norm = .01 IF desiredR >= 10 THEN norm = .1 IF desiredR >= 100 THEN norm = 1 IF desiredR >= 1000 THEN norm = 10 IF desiredR >= 10000 THEN norm = 100 IF desiredR >= 100000 THEN norm = 1000 IF desiredR >= 1000000 THEN norm = 10000 IF desiredR >= 10000000 THEN norm = 100000 REM determine lower value match, upper match is one more REM compare to a slightly smaller value to avoid FP errors FOR i = 1 TO 96 IF desiredR > valueE96(i) * norm - .00001 THEN v1 = i: v2 = i + 1 NEXT i lowerE96 = valueE96(v1) * norm upperE96 = valueE96(v2) * norm REM do the same for E24 series, using norm*10 since E24 values are 2 digit FOR i = 1 TO 24 IF desiredR > valueE24(i) * norm * 10 - .00001 THEN v1 = i: v2 = i + 1 NEXT i lowerE24 = valueE24(v1) * norm * 10 upperE24 = valueE24(v2) * norm * 10 REM calculate error percentages for lower and upper values lowerE96error = (1 - lowerE96 / desiredR) * 100 upperE96error = -(1 - upperE96 / desiredR) * 100 lowerE24error = (1 - lowerE24 / desiredR) * 100 upperE24error = -(1 - upperE24 / desiredR) * 100 REM determine which value has less error REM in the event of a tie go with the higher value (user can pick) closestE96 = lowerE96: IF lowerE96error >= upperE96error THEN closestE96 = upperE96 closestE24 = lowerE24: IF lowerE24error >= upperE24error THEN closestE24 = upperE24 REM print the closest value and error percentages for lower/upper values PRINT "Closest E96 value = "; R = closestE96: GOSUB convertE96: PRINT R$; SPACE$(7 - LEN(R$)); "("; REM to detect exact matches compare to a range to avoid float errors M = 0: IF closestE96 > desiredR - .0001 AND closestE96 < desiredR + .0001 THEN M = 1 IF M = 1 THEN PRINT "exact match)": GOTO printE24values E$ = LEFT$(LTRIM$(STR$(lowerE96error + .0001)), 4) R = lowerE96: GOSUB convertE96: PRINT "-"; E$; "%="; R$; ","; E$ = LEFT$(LTRIM$(STR$(upperE96error + .0001)), 4) R = upperE96: GOSUB convertE96: PRINT "+"; E$; "%="; R$; ")" printE24values: PRINT "Closest E24 value = "; R = closestE24: GOSUB convertE24: PRINT R$; SPACE$(7 - LEN(R$)); "("; M = 0: IF closestE24 > desiredR - .0001 AND closestE24 < desiredR + .0001 THEN M = 1 IF M = 1 THEN PRINT "exact match)": GOTO doneprintingvalues E$ = LEFT$(LTRIM$(STR$(lowerE24error + .0001)), 4) R = lowerE24: GOSUB convertE24: PRINT "-"; E$; "%="; R$; ","; E$ = LEFT$(LTRIM$(STR$(upperE24error + .0001)), 4) R = upperE24: GOSUB convertE24: PRINT "+"; E$; "%="; R$; ")" doneprintingvalues: GOTO entervalue: REM loop back to enter another value exitprogram: SYSTEM REM subroutines to convert R value back to standard notation REM input R containing resistor value (with possible float errors) REM output R$ containing value in standard resistor notation convertE96: R$ = "error": R2$ = "": R1 = R + .00001: R2 = R IF R1 >= 1000 THEN R2 = R1 / 1000: R2$ = "K" IF R1 >= 1000000 THEN R2 = R1 / 1000000: R2$ = "M" IF R2 < 1 THEN R$ = LEFT$(LTRIM$(STR$(R2 + .00001)) + "000", 5) IF R2 >= 1 AND R2 < 100 THEN R$ = LEFT$(LTRIM$(STR$(R2 + .00001)) + "000", 4) + R2$ IF R2 >= 100 AND R2 < 1000 THEN R$ = LEFT$(LTRIM$(STR$(R2)), 3) + R2$ RETURN convertE24: R$ = "error": R2$ = "": R1 = R + .00001: R2 = R IF R1 >= 1000 THEN R2 = R1 / 1000: R2$ = "K" IF R1 >= 1000000 THEN R2 = R1 / 1000000: R2$ = "M" IF R2 < 1 THEN R$ = LEFT$(LTRIM$(STR$(R2 + .00001)) + "00", 4) IF R2 >= 1 AND R2 < 10 THEN R$ = LEFT$(LTRIM$(STR$(R2 + .00001)) + "00", 3) + R2$ IF R2 >= 10 AND R2 < 100 THEN R$ = LEFT$(LTRIM$(STR$(R2)), 2) + R2$ IF R2 >= 100 AND R2 < 1000 THEN R$ = LEFT$(LTRIM$(STR$(R2)), 3) + R2$ RETURN
Terry Newton (wtn90125@yahoo.com)