Shop OBEX P1 Docs P2 Docs Learn Events
How do you use Decimals — Parallax Forums

How do you use Decimals

computer guycomputer guy Posts: 1,113
edited 2007-04-05 23:15 in BASIC Stamp
How do i set a VAR (variable) as a decimal. say 0.003 for example. On the BS2.

I tried VAR Word but it just comes up as 0

Thank you smile.gif

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-04-04 16:26
    The Stamp only does integers. You have to mulitiply all of your numbers by a scale factor and think in smaller units. Instead of 0.003, you have 3 one-thousandths. Then a word variable can hold from 0 up to 65535 one thousandths, representing 0 to 65.535.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-04 23:46
    This is my code and it is important that i get a result as a decimal. Is there a way to maybe display an integer as a number like 0_003 or 0-003 or 0,003

    ' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------
    Ping PIN 15
    
    ' -----[noparse][[/noparse] Constants ]-------------------------------------------------------
    #SELECT $STAMP
    #CASE BS2, BS2E
    Trigger CON 5 ' trigger pulse = 10 uS
    Scale CON $200 ' raw x 2.00 = uS
    #CASE BS2SX, BS2P, BS2PX
    Trigger CON 13
    Scale CON $0CD ' raw x 0.80 = uS
    #CASE BS2PE
    Trigger CON 5
    Scale CON $1E1 ' raw x 1.88 = uS
    #ENDSELECT
    RawToIn CON 889 ' 1 / 73.746 (with **)
    RawToCm CON 2257 ' 1 / 29.034 (with **)
    IsHigh CON 1 ' for PULSOUT
    IsLow CON 0
    
    ' -----[noparse][[/noparse] Variables ]-------------------------------------------------------
    rawDist VAR Word ' raw measurement
    time VAR      'time for speed of sound
    speed VAR Word   'speed of sound
    cm VAR Word
    
    ' -----[noparse][[/noparse] Initialization ]--------------------------------------------------
    Reset:
    DEBUG CLS,
    "Parallax PING))) Sonar", CR, ' setup report screen
    "======================", CR,
    CR,
    "Time (uS)..... ", CR,
    "Time (sec).... ", CR,
    "Speed (m/sec). ", CR,
    "Centimeters... "
    
    ' -----[noparse][[/noparse] Program Code ]----------------------------------------------------
    Main:
    DO
    GOSUB Get_Sonar ' get sensor value
    cm = rawDist ** RawToCm ' convert to centimeters
    DEBUG CRSRXY, 15, 3, ' update report screen
    DEC rawDist, CLREOL,
    CRSRXY, 15, 4,
    DEC time, CLREOL,
    CRSRXY, 15, 5,
    DEC speed, CLREOL,
    CRSRXY, 15, 6,
    DEC cm, CLREOL
    PAUSE 100
    LOOP
    END
    
    ' -----[noparse][[/noparse] Subroutines ]-----------------------------------------------------
    ' This subroutine triggers the PING))) sonar sensor and measures
    ' the echo pulse. The raw value from the sensor is converted to
    ' microseconds based on the Stamp module in use. This value is
    ' divided by two to remove the return trip -- the result value is
    ' the distance from the sensor to the target in microseconds.
    Get_Sonar:
    Ping = IsLow ' make trigger 0-1-0
    PULSOUT Ping, Trigger ' activate sensor
    PULSIN Ping, IsHigh, rawDist ' measure echo pulse
    rawDist = rawDist */ Scale ' convert to uS
    rawDist = rawDist / 2 ' remove return trip
    time = rawDist / 1000 'convert to ms
    time = time / 1000    'convert to sec
    speed = 1 / time      'work out the speed in m/s
    RETURN
    
    



    This is the code that needs decimals.
    time = rawDist / 1000 'convert to ms
    time = time / 1000    'convert to sec
    speed = 1 / time      'work out the speed in m/s
    
    



    I am doing this for a science fair project and need my results as a decimal. (I cant aford to get them wrong.)

    Thank you smile.gif

    Post Edited (computer guy) : 4/4/2007 11:53:37 PM GMT
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 01:07
    If the BS2 can't do it then i will have to do the maths with a program then.

    so can someone make a windows application for me to

    1. read a number from the serial port. (this will be the speed in us).
    2. get 10 copies of this number and average them.
    3. divide the number by 1000
    4. divide it by 1000 again. (to get the number into seconds).
    5. divide 1 by the number. (to get the speed in m/s).

    Thank you smile.gif
  • ZootZoot Posts: 2,227
    edited 2007-04-05 01:39
    You can do this on the Stamp. Use this one line as an example:

    time = rawDist / 1000 'convert to ms


    Instead of thinking of it as ms, think of it as 1000ths of a second. Then your only trick is displaying it with the decimal point in the right place, e.g.

    434 ms = .434 seconds
    1356 ms = 1.356 seconds (although you won't get ms that high from sonar, but hopefully you get the idea).

    The same can be done with the raw distance, etc.

    Really what you are looking to do is something like:

    x = rawTimeinMs
    DEBUG DEC1 x/1000, ".", DEC3 x//1000

    Which would give you 1 place to the left of the decimal and 3 places to the right of the decimal.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 01:43
    Can you store a decimal in a Word though.

    Thank you smile.gif
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 02:19
    Can you give me an example using my code.

    Thank you smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-05 02:25
    Again, the Stamps do 16-bit integer arithmetic. That's all.

    You can do fixed point arithmetic using integers as described by representing perhaps 2 to 4 decimal places with an integer value, essentially by changing units. For example, instead of talking about fractional seconds, you keep your time information in milliseconds as an integer. As Zoot illustrated, you can format the information to display as seconds with 2 or 3 decimal places, but, in the Stamp, it's stored in a 16-bit word as an integer millisecond value.
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 02:27
    Would it be possible to round a decimal to the nearest whole number then.

    The numbers i am working with are in the range of 334.333'

    Thank you smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-05 02:42
    Well, you wouldn't be able to represent 334.333 in 16 bits. You could do 334.33 if it was positive only by using 33,433. To round to two decimal places and convert to integer in one statement you'd do something like:
    value = 33433
    rounded = value + 50 / 100
    
    


    Do have a look at Tracy Allen's website (www.emesystems.com) for lots of information on doing math with Stamps including multiple precision and fixed point.
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 03:09
    I almost have it it's just when i do 1/time i get a decimal and therefore the BS2 ignores it.

    Thank you smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-05 03:19
    When you do fixed point arithmetic, you have to know the range of your numbers. If you want to compute 1/time, you need to know the range of time values and, therefore, the range of 1/time values you want so you can do the division properly. Do have a look at the description of the "**" and "*/" operators in PBasic. You'll need one or the other to do the 1/time calculation.
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 04:14
    I managed to get it i don't get one of the lines though.
    I usually divide 1m by how long it takes to travel.
    now i have to use 2 */ time to get the correct result.

    Could someone explain this please.

    Thank you smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-05 13:57
    The only factor of 2 in the setup is the double path that the sound pulse takes (there and back). In your original Get_Sonar routine, there's a division by two to get rawDist. If you're calculating the speed of sound over that path, you'd need to put the factor of 2 back in.
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 17:16
    This is a bit of my new code as you can see i have kept the division of the rawdist by 2 in there although down the bottom for some reason
    i need to put 2 */ time in order to get the right number range.

    ' -----[noparse][[/noparse] Program Code ]----------------------------------------------------
    Main:
    DO
    GOSUB Get_Sonar ' get sensor value
    cm = rawDist ** RawToCm ' convert to centimeters
    DEBUG CRSRXY, 15, 3, ' update report screen
    DEC rawDist, CLREOL,
    CRSRXY, 15, 4,
    DEC3 time/100,".",DEC2 time, CLREOL,
    CRSRXY, 15, 5,
    DEC3 speed, CLREOL,
    CRSRXY, 15, 6,
    DEC cm, CLREOL
    PAUSE 500
    LOOP
    END
    
    ' -----[noparse][[/noparse] Subroutines ]-----------------------------------------------------
    ' This subroutine triggers the PING))) sonar sensor and measures
    ' the echo pulse. The raw value from the sensor is converted to
    ' microseconds based on the Stamp module in use. This value is
    ' divided by two to remove the return trip -- the result value is
    ' the distance from the sensor to the target in microseconds.
    Get_Sonar:
    Ping = IsLow ' make trigger 0-1-0
    PULSOUT Ping, Trigger ' activate sensor
    PULSIN Ping, IsHigh, rawDist ' measure echo pulse
    rawDist = rawDist */ Scale ' convert to uS
    rawDist = rawDist / 2 ' remove return trip
    time = rawDist  */ 1000  'convert to ms
    time = time  */ 1000    'convert to sec
    speed = 2 */ time       'work out the speed in m/s
    RETURN
    
    



    In the debug window i get.
    Parallax PING))) Sonar
    ======================
    
    Time (uS)..... 2956
    Time (sec).... 451.01
    Speed (m/sec). 352
    Centimeters... 101
    
    


    Thank you smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-05 17:24
    The question is "what's your path length?". The PING just reports the time to echo reception. rawDist with the division by 2 is the time in us for the sound to go one-way (for computing actual distance to the reflecting surface). If you're computing speed based on a total path length of 1 meter, you have to put the factor of 2 back in with the "2 */".
  • computer guycomputer guy Posts: 1,113
    edited 2007-04-05 23:15
    I am measuring how long it takes to travel 1 meter.
    So

    Parallax PING))) Sonar
    ======================
    
    Time (uS)..... 2956   <--------Time to travel 1 meter
    Time (sec).... 451.01   <------Time to travel 1 meter in seconds (should be 0.002956)
    Speed (m/sec). 352   <-------Speed of sound based on 1 meter / time sec (should be 338.2949)
    Centimeters... 101
    
    



    My maths in the code i posted Today 10:16 AM (GMT -7) is obviously incorrect then.

    Thank You smile.gif
Sign In or Register to comment.