BASIC & Visual Basic DISCUSSION

How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

Started by bosbos PICAXE BASICBASIC Stamp PBASIC16-bit integer mathsADC scalingleft-to-right evaluation
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

bosbos BASIC & Visual Basic Forum
#1

My PICAXE reads a sensor with readadc10, giving 0 to 1023 for 0 to 5 V, and I want the result in millivolts. The obvious w1 = w0 * 5000 / 1023 gives nonsense for most readings, and dividing first, w1 = w0 / 1023 * 5000, returns 0 for everything except full scale. I also noticed that w2 = 100 + w0 * 2 gives a different result from what I get on a calculator.

How are expressions evaluated in these small BASIC dialects, and how do I do this kind of scaling without floating point?

Community replies 5

Re: How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

#2

Two properties of these dialects cause what you see. Variables are unsigned 16-bit words at most, holding 0 to 65535, and arithmetic that goes beyond that wraps around silently. w0 * 5000 exceeds 65535 for any reading above 13 (14 × 5000 = 70,000), so the intermediate product is wrong before the division happens. Dividing first avoids the overflow but throws the information away: integer division discards the remainder, so w0 / 1023 is 0 for every reading below 1023.

The general principle: multiply first, but only by as much as still fits in 16 bits.

Re: How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

#3

The calculator mismatch is evaluation order. PICAXE BASIC, and PBASIC on the BASIC Stamp 2, evaluate expressions strictly from left to right with no operator precedence. 100 + w0 * 2 with w0 = 10 is (100 + 10) × 2 = 220, not 120. Write the multiplication first, w0 * 2 + 100, or split the calculation across two lines.

The BASIC Stamp accepts parentheses to force an order. Check the manual of your dialect before relying on them, and do not assume that the rules of desktop BASIC apply.

Re: How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

#4

For the scaling itself, replace 5000/1023, which is about 4.888, by a small fraction whose numerator keeps the product in range. w1 = w0 * 49 / 10 works over the whole input range: the largest product is 1023 × 49 = 50,127, which fits, and full scale comes out as 5012 mV, an error of about 0.25 percent. Evaluated left to right, that is exactly the multiply-then-divide order you need.

A closer fraction costs nothing extra: 44/9 is 4.889. With w0 * 44 / 9 the largest product is 45,012 and full scale gives 5001 mV.

Re: How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

#5

Both PICAXE and the BASIC Stamp 2 also have the ** operator, which multiplies two words and returns the upper 16 bits of the 32-bit product, in effect multiplying by a fraction of 65536. Split the factor into 4 plus 0.88759: the fractional part times 65536 is about 58,169. Then w1 = w0 ** 58169 gives the fractional share, and w1 = w0 * 4 + w1 adds the whole part.

For a reading of 1023 that is 908 + 4092 = 5000 mV, and for 512 it is 454 + 2048 = 2502 mV, with no overflow anywhere. This high-word multiply is the standard trick for precise scaling on integer-only systems.

Re: How do I scale a 10-bit ADC reading to millivolts in PICAXE or BASIC Stamp with 16-bit integer maths?

#6

Two further options. If the dialect or compiler offers wider types, use them: compiled BASICs such as BASCOM-AVR have a 32-bit Long and a floating-point Single, at the cost of more code space and slower maths. And consider whether you need millivolts inside the program at all. Comparing against a threshold is cheaper and exact if you convert the threshold to counts once by hand (2.5 V is about 512 counts) and compare raw readings, converting to millivolts only for display.

Whatever you choose, test both ends and the middle of the range, here 0, 512 and 1023, against a calculator. Overflow errors in integer scaling show up immediately at full scale.

TEP COMMUNITY