16bit variable and degrees conversion


Closed Thread
Results 1 to 8 of 8
  1. #1

    Default 16bit variable and degrees conversion

    Hi all

    I need some help on a 16bit variable

    I receive serial at 9600 bd N8,1 a string with 2 positions each 16bit

    example:
    21 AD 34 01 22 EF 23 02

    where:
    21 is indicating the 1st position request
    AD 34 16bit position 1
    01 not used

    22 is indicating the 2nd position request
    EF 23 16bit position 2

    Now I need to display both positions on a LCD in degrees

    So AD 34 is 44340 decimal

    65536 / 360 = 182.04444444 Per degree

    So 44340 / 182.0444444 = 243,56689453125 degrees

    I need to display 243 and 566 on a LCD

    Same for the 2nd position

    How can I handle those variables in PBP ?


    Thanks Walter

  2. #2
    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    237


    Did you find this post helpful? Yes | No

    Post

    Hi,

    IntPartOfPos1 = 16bitPosition1 ** 360
    FracPartOfPos1 = 16bitPosition1 * 360
    FracPartOfPos1 = FracPartOfPos1 ** 1000
    LCDOUT DEC3 IntPartOfPos1, ".", DEC3 FracPartOfPos1

    The code above starts with two multiplications by 360, one of them isn't really necessary. However i'm a bit unsure of wich internal register contains what after a multiplication. I think the code below will work, but i'm not 100% sure it's the right register. Try it and see.

    FracPartOfPos1 = 16bitPosition1 * 360
    IntPartOfPos1 = R0
    FracPartOfPos1 = FracPartOfPos1 ** 1000
    LCDOUT DEC3 IntPartOfPos1, ".", DEC3 FracPartOfPos1

    /Ingvar

  3. #3
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Hi!

    What precision do you need?
    Describe your project.

    The three conversions below (44340, 13107 and 13)
    are performed using the solution of the user Ingvar.
    (See his previous post).

    From the PicBasic Pro manual:

    PicBasic Pro multiply (*) function
    operates as a 16-bit x 16-bit multiply
    yielding a 32-bit internal result.

    4.17.1. Multiplication
    PBP performs unsigned 16-bit x 16-bit multiplication.

    The '*' operator returns the lower 16 bits of
    the 32-bit internal result. This is the typical
    multiplication found in most programming languages.

    The '**' operator returns the upper 16 bits of
    the 32-bit internal result. These two operators
    can be used in conjunction to perform 16-bit x 16-bit
    multiplication that produces 32-bit results.

    ========================================
    (See original post of the user Walter/RFsolution)
    With the Windows calculator:
    65535/360 = 182.04166666666666666666666666667

    ========================================
    44340 conversion

    44340 * 360 = 15962400

    15962400 = 00000000111100111001000100100000 (32-bit internal result)
    -----------0000000011110011-1001000100100000
    -------------(upper 16 bits )-----(lower 16 bits )

    Upper 16 bits of the 32-bit internal result = 0000000011110011 = 243 decimal
    Lower 16 bits of the 32-bit internal result = 1001000100100000 = 37152 decimal

    37152 * 1000 = 37152000

    37152000 = 00000010001101101110010100000000 (32-bit internal result)
    -----------0000001000110110-1110010100000000
    -------------(upper 16 bits )-----(lower 16 bits )

    Upper 16 bits of the 32-bit internal result = 0000001000110110 = 566 decimal
    Lower 16 bits of the 32-bit internal result = 1110010100000000 = 58624 decimal

    Display = 243.566

    With the Windows calculator:
    44340 / 182.04166666666666666666666666667
    = 243.57061112382696269169146257725

    ========================================
    13107 conversion (65535/5 = 13107 ---- 360 / 5 = 72 degrees)

    44340 * 360 = 4718520

    4718520 = 10001111111111110111000
    1000111-1111111110111000
    (up.part)---(lo. part)

    Upper part 1000111 = 71 decimal
    Lower part 1111111110111000 = 65464 decimal

    65464 * 1000 = 65464000

    65464000 = 11111001101110011011000000
    1111100110-1110011011000000
    (up.part)---(lo. part)

    Upper part = 1111100110 = 998 decimal
    Lower part = 1110011011000000 = 59072 decimal

    Display = 71.998

    With the Windows calculator:
    13107 / 182.04166666666666666666666666667
    = 72

    ========================================
    13 conversion

    13 * 360 = 4680

    4680 = 0-0001001001001000
    -------(up.part)---(lo. part)

    Upper part 0 = 0 decimal
    Lower part 1001001001000 = 4680 decimal

    4680 * 1000 = 4680000

    4680000 = 10001110110100101000000
    1000111-0110100101000000
    (up.part)---(lo. part)

    Upper part = 1000111 = 71 decimal
    Lower part = 1110011011000000 = 59072 decimal

    Display = 0.071

    With the Windows calculator:
    13 / 182.04166666666666666666666666667
    = 0.071412222476539253833829251544976

    ========================================

    * * * * * * * *

    About precision

    Example with earth's longitude:

    A degree of longitude at the equator is 111.2 kilometers
    a minute is 1853 meters and a second is 30.9 meters.

    * * * *
    Convert degrees to decimal degrees:

    Example 09°59'58" (9 degrees, 59 minutes, 58 seconds).
    = Decimal degrees 9.9994


    Example 09°59'57" (9 degrees, 59 minutes, 57 seconds).
    = Decimal degrees 9.9991


    Example 09°59'56" (9 degrees, 59 minutes, 56 seconds).
    = Decimal degrees 9.9988

    * * * *

    Convert decimal degrees to degrees:

    9.999 > 09°59'56"
    9.998 > 09°59'52"
    9.997 > 09°59'49"

    * * * *

    Above conversions done with:

    http://www.beg.utexas.edu/GIS/tools/DMS_DD.htm
    http://www.beg.utexas.edu/GIS/tools/dd_dms.htm


    Best regards,

    Luciano
    Last edited by Luciano; - 19th April 2005 at 18:03.

  4. #4


    Did you find this post helpful? Yes | No

    Default Thanks

    Thank you All ,

    I will have a look and give it a try this weekend, but both Ingvar and Luciano
    pointed me in the direction

    I only need to check the SERIN2 command to see how to handle the incomming string in my previous msg

    Precision is 2 decimals

    The project is to read out 2 position absolute encoders
    which are polled by a controller over a RS485 line at 9600bd

    Thanks again to everyone who helped me

    Walter

  5. #5
    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    237


    Did you find this post helpful? Yes | No

    Post

    Ok, since you only need 2 decimals and my code gives 3 you can use the extra precision to round the result .......

    IntPartOfPos1 = 16bitPosition1 ** 360
    FracPartOfPos1 = 16bitPosition1 * 360
    FracPartOfPos1 = FracPartOfPos1 ** 1000
    FracPartOfPos1 = (FracPartOfPos1 + 5) / 10
    LCDOUT DEC3 IntPartOfPos1, ".", DEC2 FracPartOfPos1

    ..... should give you a correctly rounded result with 2 decimals.

    /Ingvar

  6. #6


    Did you find this post helpful? Yes | No

    Default Serin2 help

    Hmm looks that I'm doing something wrong


    I receive serial at 9600 bd N8,1 the following in hex

    example:
    21 AD 34 01 22 EF 23 02

    loop:
    AZ var word
    EL var Word

    Serin2 portb.2,84,[wait ("!"),AZ] => "!" is the ascii represenataion of 21 hex
    would like to store AD 34 in variable AZ, 01 dont care
    then the same for EF 23 in EL

    Use an SP485 RS485 driver in front

  7. #7
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Hi,

    Your example data:
    21 AD 34 01 22 EF 23 02

    ===============================================
    ' The code (Not tested)

    my_array VAR BYTE[7] ' Define array variable with 7 locations

    SERIN2 IN_PIN, BAUD,[WAIT("!") STR my_array\7]

    ' Waits for the string "!", then collects the next 7 characters.
    ' (21 HEX = ASCII !)


    ===============================================

    This could be valid data:
    21 21 21 01 22 21 21 02

    Make sure you verify that "01" "22" "02" are in the
    right position in the array.

    * * * * * *

    From PicBasic manual:

    An optional Timeout and Label may be included to allow the program
    to continue if a character is not received within a certain amount of time.
    Timeout is specified in 1 millisecond units. If the serial input pin stays in
    the idle state during the Timeout time, the program will exit the SERIN2
    command and jump to Label.

    * * * * * *

    PicBasic Pro Code that demonstrates the use of modifiers
    with the Serin2 and Serout2 commands.

    http://www.microengineeringlabs.com/...bp/ser2mod.bas


    Luciano
    Last edited by Luciano; - 22nd April 2005 at 11:54.

  8. #8


    Did you find this post helpful? Yes | No

    Default Thanks

    Everything is working

    I would like to thank those who post some replys

    If someone is in the Belgian Area, I will certainly offer a Beer

    Walter

Similar Threads

  1. Conversion problem
    By eva in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 15th March 2007, 18:21

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts