//Purpose: Produce closest standard resistor value based on IEC 60063 preferred value system (E series) and colour code per IEC 60062:2016
//Input: Your resistor value and E series (tolerance)
//Output: Standard resistor value, colour coding, and percent error from entered value
//Author: Konstantin Borissov
//Date: 21 September 2018
EXPORT SRV() //Uncomment for interactive input. Chose this, or the one below.
//EXPORT SRV(myResistance, eSeries) //Uncomment for function-style input. Note: You'll have to know which E series you want.
//If using function-style input, also comment out INPUT line(14), eSeries line(13) and line(16), and UNcomment line(17).
BEGIN
LOCAL myResistance, eSeries, numberInSeries, stdValue, roundValue, pctError; //For calculations
LOCAL homeFormat, homeDigits, xPON; //To store user-defined environment later on
LOCAL eSeriesListCode := 2; //Sets default eSeries according to list below. e.g., 2 is E12.
INPUT ({myResistance, {eSeriesListCode,{"E6 (20%)","E12 (10%)","E24 (5%)","E48 (2%)","E96 (1%)","E192 (0.5%)"}}},"Standard Resistor Calc v1.2", {"Resistance ", "E
series "}); //Comment if using fuction-style input.
eSeries := 6*2^(eSeriesListCode - 1); //Convert value from dropdown list to a more useful value for calculations.
//eSeriesListCode := CEILING(logb(eSeries/6,2) + 1); //UNcomment if using fuction-style input, converts eSeries to eSeriesListCode
CASE //Number of sig figs to display based on E series
IF ((eSeries == 6) OR (eSeries == 12) OR (eSeries == 24)) THEN
roundValue := -2;
END;
IF ((eSeries == 48) OR (eSeries == 96) OR (eSeries == 192)) THEN
roundValue := -3;
END;
END;
//Calculations
IF (myResistance == 0) THEN //Zero-resistance case
stdValue := 0;
ELSE
numberInSeries := ROUND(eSeries*LOG( myResistance ), 0); //
stdValue := ROUND(10^(numberInSeries / eSeries), roundValue);
END;
//Check for values that don't fit into the standard calculation model (27,33,39,47,82)
IF ((eSeries == 6) OR (eSeries == 12) OR (eSeries == 24)) THEN
CASE
IF ( (stdValue*10^(-XPON(stdValue)))/2.6 == 1) THEN //Magic
xPON := XPON(stdValue);
stdValue := 2.7*10^(xPON);
END;
IF ( (stdValue*10^(-XPON(stdValue)))/3.2 == 1) THEN
xPON := XPON(stdValue);
stdValue := 3.3*10^(xPON);
END;
IF ( (stdValue*10^(-XPON(stdValue)))/3.8 == 1) THEN
xPON := XPON(stdValue);
stdValue := 3.9*10^(xPON);
END;
IF ( (stdValue*10^(-XPON(stdValue)))/4.6 == 1) THEN
xPON := XPON(stdValue);
stdValue := 4.7*10^(xPON);
END;
IF ( (stdValue*10^(-XPON(stdValue)))/8.3 == 1) THEN
xPON := XPON(stdValue);
stdValue := 8.2*10^(xPON);
END;
END;
END;
//Percent error, for zero value and all others
IF (stdValue == 0) THEN
pctError :=0;
ELSE
pctError := ROUND(%CHANGE(myResistance, stdValue), -2); //Caculate signed percent error b/en desired and std value
END;
//Colour Coding
LOCAL bandColours := {" PK "," SR "," GD "," BK "," BN "," RD "," OG "," YE "," GN "," BU "," VT "," GY "," WH ", " DNE "};
LOCAL toleranceColours := {" none ", " SR ", " GD ", " RD ", " BN ", " GN "};
LOCAL resColourCode := toleranceColours(eSeriesListCode); //Initialize with tolerance colour band
CASE //Determine if 4 or 5 band depending on E series
IF (stdValue == 0) THEN //Zero resistance case
resColourCode := bandColours(0+4);
END;
IF ((eSeries == 6) OR (eSeries == 12) OR (eSeries == 24)) THEN //4-band
IF (XPON(stdValue) > 10) OR (XPON(stdValue) < -2) THEN //Check for out of bounds multipliers
resColourCode := prepend(resColourCode, bandColours(14)); //Assign DNE multiplier
ELSE
resColourCode := prepend(resColourCode, bandColours(XPON(stdValue)+3)); //Assign multiplier
END; //Next, colour bands are assigned from least to most significant
resColourCode := prepend(resColourCode, bandColours(CEILING((stdValue*10^(-XPON(stdValue)))*10 MOD 10 + 4))); //1's,
resColourCode := prepend(resColourCode, bandColours(IP((stdValue*10^(-XPON(stdValue))) MOD 10 + 4))); //10's
END;
IF ((eSeries == 48) OR (eSeries == 96) OR (eSeries == 192)) THEN //5-band
IF (XPON(stdValue) > 11) OR (XPON(stdValue) < -1) THEN //Check for out of bounds multipliers, 5-bands have a different range
resColourCode := prepend(resColourCode, bandColours(14)); //Assign DNE multiplier
ELSE
resColourCode := prepend(resColourCode, bandColours(XPON(stdValue)+2)); //Assign multiplier
END;
resColourCode := prepend(resColourCode, bandColours(CEILING((stdValue*10^(-XPON(stdValue)))*100 MOD 10 + 4))); //1's IP function rounds down here instead
of giving integer part
resColourCode := prepend(resColourCode, bandColours(IP((stdValue*10^(-XPON(stdValue)))*10 MOD 10 + 4))); //10's, colour bands are assigned from least to
most significant
resColourCode := prepend(resColourCode, bandColours(IP((stdValue*10^(-XPON(stdValue))) MOD 10 + 4))); //100's
END;
END;
//Aesthetics
homeDigits := HDigits; //Store user-defined number of digits to display
HDigits := 2; // Too many digits looks messy
//Outputs
PRINT ("Closest Standard Resistor Value: ");
PRINT (stdValue + " Ω");
PRINT (" ");
PRINT ("Entered value: ");
PRINT (myResistance + " Ω");
PRINT (" ");
homeFormat := HFormat; //Store home number format display.
HFormat := 0; //Temporarily changes output format to standard from here on for a better display look.
PRINT ("Error is: ");
PRINT (pctError + "%");
PRINT (" ");
PRINT ("Resistor E series: ");
PRINT ("E" + eSeries + " (±" + ROUND(20*0.5^(eSeriesListCode-1)-0.125, -1) + "%)" ); //Incl. function to convert eSeriesListCode to tolerance.
PRINT (" ");
PRINT("Colour Code: " + resColourCode); //Print colour coding
HDigits := homeDigits; //Back to original, user-defined, format.
HFormat := homeFormat;
RETURN (stdValue);
END; //Hasta la vista