multiplying with decimals??
Matthew
Posts: 200
Hey.
I have a program that reads an analog input (0-5v). It converts it to a number between 0-255. Now I'm trying to convert that new number to inches (it's from an ultrasonic sensor). In order to do it correctly, I need to multiply the 0-255 number with 1.875.
I've tried to multiply it by 1875, then divide it by 1000, but the number can't go any larger than 35 because 35*1875=65625, which is larger than a 'word' of space.
So far I've only been able to multiply the number by 187, then divide it by 100. That gets a new number that's about·1-4·off from what it's supposed to be.
Here's my code:
'
[noparse][[/noparse] Title ]
' Basic Analog and Digital - ADC with Inches
' {$STAMP BS2}
' {$PBASIC 2.5}
'
[noparse][[/noparse] Declarations ]
adcBits VAR Byte
v······ VAR Byte
r······ VAR Byte
v2····· VAR Byte
v3····· VAR Byte
Inches· VAR Word
'
[noparse][[/noparse] Initialization ]
CS···················· PIN· 0
CLK··················· PIN· 1
DataOutput············ PIN· 2
DEBUG CLS
'
[noparse][[/noparse] Main Routine ]
DO
· GOSUB ADC_Data
· GOSUB Calc_Volts
· GOSUB Calc_Inches
· GOSUB Display
LOOP
'
[noparse][[/noparse] Subroutines ]
ADC_Data:
· LOW CS
· LOW CLK
· PULSOUT CLK, 210
· SHIFTIN DataOutput,CLK,MSBPOST, [noparse][[/noparse]adcBits\8]
· HIGH CS
RETURN
Calc_Volts:
v = 5 * adcBits / 255
r = 5 * adcBits // 255
v2 = 100 * R / 255
v3 = 100 * r // 255
v3 = 10 * v3 / 255
IF (v3 >= 5) THEN v2 = v2 + 1
IF (v2 >= 100) THEN
· v = v + 1
· v2 = 0
ENDIF
RETURN
Calc_Inches:
Inches = adcBits * 187 / 100
RETURN
Display:
· DEBUG HOME
· DEBUG "8-pit binary value:····· ", BIN8 adcBits
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcBits
· DEBUG CR, CR, "DVM Reading:· "
· DEBUG DEC1 v, ".", DEC2 v2, " Volts"
· DEBUG CR, CR, "Inches value:··· ", DEC3 inches
RETURN
Thanks,
Matthew
I have a program that reads an analog input (0-5v). It converts it to a number between 0-255. Now I'm trying to convert that new number to inches (it's from an ultrasonic sensor). In order to do it correctly, I need to multiply the 0-255 number with 1.875.
I've tried to multiply it by 1875, then divide it by 1000, but the number can't go any larger than 35 because 35*1875=65625, which is larger than a 'word' of space.
So far I've only been able to multiply the number by 187, then divide it by 100. That gets a new number that's about·1-4·off from what it's supposed to be.
Here's my code:
'
[noparse][[/noparse] Title ]
' Basic Analog and Digital - ADC with Inches
' {$STAMP BS2}
' {$PBASIC 2.5}
'
[noparse][[/noparse] Declarations ]
adcBits VAR Byte
v······ VAR Byte
r······ VAR Byte
v2····· VAR Byte
v3····· VAR Byte
Inches· VAR Word
'
[noparse][[/noparse] Initialization ]
CS···················· PIN· 0
CLK··················· PIN· 1
DataOutput············ PIN· 2
DEBUG CLS
'
[noparse][[/noparse] Main Routine ]
DO
· GOSUB ADC_Data
· GOSUB Calc_Volts
· GOSUB Calc_Inches
· GOSUB Display
LOOP
'
[noparse][[/noparse] Subroutines ]
ADC_Data:
· LOW CS
· LOW CLK
· PULSOUT CLK, 210
· SHIFTIN DataOutput,CLK,MSBPOST, [noparse][[/noparse]adcBits\8]
· HIGH CS
RETURN
Calc_Volts:
v = 5 * adcBits / 255
r = 5 * adcBits // 255
v2 = 100 * R / 255
v3 = 100 * r // 255
v3 = 10 * v3 / 255
IF (v3 >= 5) THEN v2 = v2 + 1
IF (v2 >= 100) THEN
· v = v + 1
· v2 = 0
ENDIF
RETURN
Calc_Inches:
Inches = adcBits * 187 / 100
RETURN
Display:
· DEBUG HOME
· DEBUG "8-pit binary value:····· ", BIN8 adcBits
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcBits
· DEBUG CR, CR, "DVM Reading:· "
· DEBUG DEC1 v, ".", DEC2 v2, " Volts"
· DEBUG CR, CR, "Inches value:··· ", DEC3 inches
RETURN
Thanks,
Matthew
Comments
n = n*/$01E0
To get the "E0" of the above operator, .185 x 256 = 224
224 converted to HEX = E0, and your operator becomes $01E0.· If you wanted to multiply by 2.185 then it would be $02E0, and so on.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sid Weaver
Do you have a Stamp Tester?
http://hometown.aol.com/newzed/index.html
·
n * 1.875 =
n = n*/$01E0
The E0 comes from .875 * 256 = 224 = HEX E0.
If you wanted to multiply by 2.875 your operator would be $02E0.
Sorry for the confusion.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sid Weaver
Do you have a Stamp Tester?
http://hometown.aol.com/newzed/index.html
·
Where did you get :
.875 * 256 = 224 = HEX E0?
I see what the $01 or $02 means, but now the E0.
Thanks,
Matthew
Have I cleared that up now[noparse]:)[/noparse])
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sid Weaver
Do you have a Stamp Tester?
http://hometown.aol.com/newzed/index.html
·
1.875 * 256 = 480
Now use this value with star-slash:
x = y */ 480
Many of us convert the */ parameter to hex as the way things work out, the whole portion is in the upper byte, the fractional portion in the lower byte. So I woud do this:
x = y */ $01E0
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
x = (y * 3) + (y ** 9279)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Thanks again.
You can play with the numbers a bit to get more decimal places if
you need them. There's still a bit of range left so that you won't
overflow 16-bits.
If you want to round to the nearest inch, take your reading, multiply
by 15 and then add 4 before dividing by 8. This will round the answer
to the nearest inch for you.
If your voltage reading is 255 then your distance should be 255*1.875
= 478.125-inches. What I'm suggesting is do this calculation:
(255 * 15 + 4) / 8 = 3829 / 8 = 478
I'm sure the suggestions with the */ operator are correct but my mind,
especially on weekends (Sunday night, no less) handles this method a
little easier once the 1.875 is recognized as 1 7/8.
For your amusement,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Rusty-
--
Rusty Haddock = KD4WLZ = rusty@fe2o3.lonestar.org
**Out yonder in the Van Alstyne (TX) Metropolitan Area**
Microsoft is to software what McDonalds is to gourmet cooking
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Now I know, thanks!