Shop OBEX P1 Docs P2 Docs Learn Events
Converting IEEE 32 bit floating point to scaled integer — Parallax Forums

Converting IEEE 32 bit floating point to scaled integer

ArchiverArchiver Posts: 46,084
edited 2004-06-10 15:11 in General Discussion
I was given this bit of code from a coworker who used it in a C++ program. I have tried to
get it to work on the BasicStamp to no avail. Any help is appreciated!

Julian

'{$Stamp BS2p} 'Stamp Directive (specifies BS2P)

'*********************************************************************
' OEM Example Program for the Basic Stamp 2p uProcessor to
' interface with a PNI Corporation V2Xe 2 Axis Compass Module.
' This program shows how to get the Heading from the V2Xe.
' Copyright 20Dec2003, PNI Corporation
' Written by Julian Benton, Applications Engineer
' Contact: jbenton@p... , 707-566-2260 x356
'*********************************************************************

'Declare Lines
SYNC CON 5 'SYNC is pin 5
SSNOT CON 7 'SSNOT is pin 7
MOSI CON 8 'MOSI is pin 8
MISO CON 9 'MISO is pin 9
SCLK CON 10 'SCLK is pin 10

'Declare Global Constants for Command Datagrams
Flag CON $AA 'Defines Sync Flag which is the first byte of any command
GetModInfo CON $1 'Defines the frame type that queries the V2Xe for
module information
ModInfoResp CON $2 'Defines the response frame type to command
GetModInfo
SetDataComponents CON $3 'Defines the frame type for the data components to
be sent back
XRaw CON $1 'Defines the Component ID for X sensor RAW Data
YRaw CON $2 'Defines the Component ID for Y sensor RAW Data
Heading CON $5 'Defines the Component ID for Heading
Mag CON $6 'Defines the Component ID for Magnetude
Dist CON $8 'Defines the Component ID for the distortion flag
CalStatus CON $9 'Defines the Component ID for calibration status

SaveConfig CON $9 'Defines the SaveConfig frame type
GetData CON $4 'Defines the frame type which queries the V2Xe for data
components
DataResp CON $5 'Defines the response to command GetData frame type

Term CON $00 'Defines Terminator which is the last byte of any
command



'Declare Variables for Response Datagrams
FlagIn VAR BYTE 'Defines Sync Flag in the response Datagram
FrameIn VAR BYTE 'Defines the Frame Type in the response Datagram
CountIn VAR BYTE 'Defines the number of components in the response
Datagram
XRawIn VAR BYTE 'Defines the XRaw ID in the response Datagram
XRawVal VAR WORD(2) 'Defines the XRaw value array in the response Datagram
YRawIn VAR BYTE 'Defines the YRaw ID in the response Datagram
YRawVal VAR WORD(2) 'Defines the YRaw value array in the response Datagram
HeadingIn VAR BYTE 'Defines the Heading ID in the response
Datagram
HeadingVAL VAR BYTE(4) 'Defines the Heading value array
CompHeading VAR WORD 'Defines the Heading
Exponent VAR BYTE 'Defines value for Heading calculation
TermIn VAR BYTE 'Defines the Terminator of the resonse Datagram


'Interface with the V2Xe
High SSNOT
LOW SSNOT 'Enable SPI Port

'Set the data componets to be read from the V2Xe (Heading and Magnitude)
LOW SYNC
PULSOUT SYNC,2 'Not required
ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,SetDataComponents,$1,Heading,Term]
'Set Heading as output
Pause 1
Begin:
ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,GetData,Term]
'Request output (Heading)

Loop:
ShiftIn MISO,SCLK,MSBPre,[noparse][[/noparse]FlagIn]
'Look for Sync Flag
If FlagIn <> $AA THEN Loop

ShiftIn
MISO,SCLK,MSBPre,[noparse][[/noparse]FrameIn,CountIn,HeadingIn,HeadingVal(0),HeadingVal(1),HeadingVal(2)
,HeadingVal(3),TermIn] 'Shift in data (Heading)


'IEEE 32 bit floating point to scaled integer
'Integer will be scaled * 8 (i.e. 1 = 1/8, 2 = 1/4, 3 = 3/8, 4 = 1/2 ... 8 = 1.0 )

'IEEE32 format:

'31............24...23............16...15.............8...7..............0
'S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F F F
'HeadingVal(0) HeadingVal(1) HeadingVal(2) HeadingVal(3)
//For Compass Heading
'MagVal(0) MagVal(1) MagVal(2) MagVal(3)
//For Magnitude

'S = Sign
'E = Exponent
'F = Mantisa or Binary Fraction

'Number = 1.F * 2^(E-127)

'The code below will assume Sign = 0 (number is positive) for all headings
'if the heading is less than 1 degree or zero (the IEEE32 version of zero)
'IMPORTANT!!! This code truncates to the nearest decimal instead of rounding.


HeadingVal(0) = HeadingVal(0) * 2 'Shift Exponent

IF HeadingVal(1) < 128 THEN Step1
HeadingVal(0) = HeadingVal(0) + 1

Step1:
Exponent = HeadingVal(0)

Step2:
IF Exponent > 126 THEN Step3 'Zero Test
CompHeading = 0
GOTO Done

Step3:
CompHeading = 1

Loop2: 'Main loop to extract the Heading
integer information
IF Exponent = 127 THEN Done
CompHeading = CompHeading * 2
HeadingVal(1) = HeadingVal(1) * 2
IF HeadingVal(1) < 128 THEN Step4
CompHeading = CompHeading + 1

Step4:
IF HeadingVal(2) < 128 THEN Step5
HeadingVal(1) = HeadingVal(1) + 1

Step5:
HeadingVal(2) = HeadingVal(2) * 2
Exponent = Exponent - 1

GOTO Loop2

Done:


'Display Heading
DEBUG "Heading: ",DEC CompHeading, CR,10

Pause 500

GOTO Begin 'Repeat
High SSNOT 'Disable SPI Port
END

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 22:30
    Hi Julian,

    What is your code supposed to do? It does not look like C++ really!

    Regards,

    Klaus
    Original Message
    From: "julianbntn" <julianb@s...>
    To: <basicstamps@yahoogroups.com>
    Sent: Tuesday, June 08, 2004 9:43 PM
    Subject: [noparse][[/noparse]basicstamps] Converting IEEE 32 bit floating point to scaled
    integer


    > I was given this bit of code from a coworker who used it in a C++ program.
    I have tried to
    > get it to work on the BasicStamp to no avail. Any help is appreciated!
    >
    > Julian
    >
    > '{$Stamp BS2p} 'Stamp Directive (specifies BS2P)
    >
    > '*********************************************************************
    > ' OEM Example Program for the Basic Stamp 2p uProcessor to
    > ' interface with a PNI Corporation V2Xe 2 Axis Compass Module.
    > ' This program shows how to get the Heading from the V2Xe.
    > ' Copyright 20Dec2003, PNI Corporation
    > ' Written by Julian Benton, Applications Engineer
    > ' Contact: jbenton@p... , 707-566-2260 x356
    > '*********************************************************************
    >
    > 'Declare Lines
    > SYNC CON 5 'SYNC is pin 5
    > SSNOT CON 7 'SSNOT is pin 7
    > MOSI CON 8 'MOSI is pin 8
    > MISO CON 9 'MISO is pin 9
    > SCLK CON 10 'SCLK is pin 10
    >
    > 'Declare Global Constants for Command Datagrams
    > Flag CON $AA 'Defines Sync Flag which is the first byte of any command
    > GetModInfo CON $1 'Defines the frame type that queries the V2Xe for
    > module information
    > ModInfoResp CON $2 'Defines the response frame type to command
    > GetModInfo
    > SetDataComponents CON $3 'Defines the frame type for the data components
    to
    > be sent back
    > XRaw CON $1 'Defines the Component ID for X sensor RAW Data
    > YRaw CON $2 'Defines the Component ID for Y sensor RAW Data
    > Heading CON $5 'Defines the Component ID for Heading
    > Mag CON $6 'Defines the Component ID for Magnetude
    > Dist CON $8 'Defines the Component ID for the distortion flag
    > CalStatus CON $9 'Defines the Component ID for calibration status
    >
    > SaveConfig CON $9 'Defines the SaveConfig frame type
    > GetData CON $4 'Defines the frame type which queries the V2Xe for data
    > components
    > DataResp CON $5 'Defines the response to command GetData frame type
    >
    > Term CON $00 'Defines Terminator which is the last byte of any
    > command
    >
    >
    >
    > 'Declare Variables for Response Datagrams
    > FlagIn VAR BYTE 'Defines Sync Flag in the response Datagram
    > FrameIn VAR BYTE 'Defines the Frame Type in the response Datagram
    > CountIn VAR BYTE 'Defines the number of components in the response
    > Datagram
    > XRawIn VAR BYTE 'Defines the XRaw ID in the response Datagram
    > XRawVal VAR WORD(2) 'Defines the XRaw value array in the response Datagram
    > YRawIn VAR BYTE 'Defines the YRaw ID in the response Datagram
    > YRawVal VAR WORD(2) 'Defines the YRaw value array in the response Datagram
    > HeadingIn VAR BYTE 'Defines the Heading ID in the response
    > Datagram
    > HeadingVAL VAR BYTE(4) 'Defines the Heading value array
    > CompHeading VAR WORD 'Defines the Heading
    > Exponent VAR BYTE 'Defines value for Heading calculation
    > TermIn VAR BYTE 'Defines the Terminator of the resonse Datagram
    >
    >
    > 'Interface with the V2Xe
    > High SSNOT
    > LOW SSNOT 'Enable SPI Port
    >
    > 'Set the data componets to be read from the V2Xe (Heading and Magnitude)
    > LOW SYNC
    > PULSOUT SYNC,2 'Not required
    > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,SetDataComponents,$1,Heading,Term]
    > 'Set Heading as output
    > Pause 1
    > Begin:
    > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,GetData,Term]
    > 'Request output (Heading)
    >
    > Loop:
    > ShiftIn MISO,SCLK,MSBPre,[noparse][[/noparse]FlagIn]
    > 'Look for Sync Flag
    > If FlagIn <> $AA THEN Loop
    >
    > ShiftIn
    >
    MISO,SCLK,MSBPre,[noparse][[/noparse]FrameIn,CountIn,HeadingIn,HeadingVal(0),HeadingVal(1),Head
    ingVal(2)
    > ,HeadingVal(3),TermIn] 'Shift in data (Heading)
    >
    >
    > 'IEEE 32 bit floating point to scaled integer
    > 'Integer will be scaled * 8 (i.e. 1 = 1/8, 2 = 1/4, 3 = 3/8, 4 = 1/2 ... 8
    = 1.0 )
    >
    > 'IEEE32 format:
    >
    > '31............24...23............16...15.............8...7..............0
    > 'S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F F F
    > 'HeadingVal(0) HeadingVal(1) HeadingVal(2) HeadingVal(3)
    > //For Compass Heading
    > 'MagVal(0) MagVal(1) MagVal(2) MagVal(3)
    > //For Magnitude
    >
    > 'S = Sign
    > 'E = Exponent
    > 'F = Mantisa or Binary Fraction
    >
    > 'Number = 1.F * 2^(E-127)
    >
    > 'The code below will assume Sign = 0 (number is positive) for all headings
    > 'if the heading is less than 1 degree or zero (the IEEE32 version of zero)
    > 'IMPORTANT!!! This code truncates to the nearest decimal instead of
    rounding.
    >
    >
    > HeadingVal(0) = HeadingVal(0) * 2 'Shift Exponent
    >
    > IF HeadingVal(1) < 128 THEN Step1
    > HeadingVal(0) = HeadingVal(0) + 1
    >
    > Step1:
    > Exponent = HeadingVal(0)
    >
    > Step2:
    > IF Exponent > 126 THEN Step3 'Zero Test
    > CompHeading = 0
    > GOTO Done
    >
    > Step3:
    > CompHeading = 1
    >
    > Loop2: 'Main loop to extract the Heading
    > integer information
    > IF Exponent = 127 THEN Done
    > CompHeading = CompHeading * 2
    > HeadingVal(1) = HeadingVal(1) * 2
    > IF HeadingVal(1) < 128 THEN Step4
    > CompHeading = CompHeading + 1
    >
    > Step4:
    > IF HeadingVal(2) < 128 THEN Step5
    > HeadingVal(1) = HeadingVal(1) + 1
    >
    > Step5:
    > HeadingVal(2) = HeadingVal(2) * 2
    > Exponent = Exponent - 1
    >
    > GOTO Loop2
    >
    > Done:
    >
    >
    > 'Display Heading
    > DEBUG "Heading: ",DEC CompHeading, CR,10
    >
    > Pause 500
    >
    > GOTO Begin 'Repeat
    > High SSNOT 'Disable SPI Port
    > END
    >
    >
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject and
    Body of the message will be ignored.
    >
    > Yahoo! Groups Links
    >
    >
    >
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 22:43
    Klaus,

    It was C++ but I have changed it to work with the Basic Stamp. The part that is giving me
    problems is where I am trying to convert the IEEE 32 bit number output into an integer.
    The output should be a value between 0 - 360. Right now I mostly just get 0 as an output
    with an occational random number.

    I keep thinking there must be an easier way, but I am new to the Basic Stamp.

    Julian

    --- In basicstamps@yahoogroups.com, "K de Jong" <klaus0@x> wrote:
    > Hi Julian,
    >
    > What is your code supposed to do? It does not look like C++ really!
    >
    > Regards,
    >
    > Klaus
    >
    Original Message
    > From: "julianbntn" <julianb@s...>
    > To: <basicstamps@yahoogroups.com>
    > Sent: Tuesday, June 08, 2004 9:43 PM
    > Subject: [noparse][[/noparse]basicstamps] Converting IEEE 32 bit floating point to scaled
    > integer
    >
    >
    > > I was given this bit of code from a coworker who used it in a C++ program.
    > I have tried to
    > > get it to work on the BasicStamp to no avail. Any help is appreciated!
    > >
    > > Julian
    > >
    > > '{$Stamp BS2p} 'Stamp Directive (specifies BS2P)
    > >
    > > '*********************************************************************
    > > ' OEM Example Program for the Basic Stamp 2p uProcessor to
    > > ' interface with a PNI Corporation V2Xe 2 Axis Compass Module.
    > > ' This program shows how to get the Heading from the V2Xe.
    > > ' Copyright 20Dec2003, PNI Corporation
    > > ' Written by Julian Benton, Applications Engineer
    > > ' Contact: jbenton@p... , 707-566-2260 x356
    > > '*********************************************************************
    > >
    > > 'Declare Lines
    > > SYNC CON 5 'SYNC is pin 5
    > > SSNOT CON 7 'SSNOT is pin 7
    > > MOSI CON 8 'MOSI is pin 8
    > > MISO CON 9 'MISO is pin 9
    > > SCLK CON 10 'SCLK is pin 10
    > >
    > > 'Declare Global Constants for Command Datagrams
    > > Flag CON $AA 'Defines Sync Flag which is the first byte of any command
    > > GetModInfo CON $1 'Defines the frame type that queries the V2Xe for
    > > module information
    > > ModInfoResp CON $2 'Defines the response frame type to command
    > > GetModInfo
    > > SetDataComponents CON $3 'Defines the frame type for the data components
    > to
    > > be sent back
    > > XRaw CON $1 'Defines the Component ID for X sensor RAW Data
    > > YRaw CON $2 'Defines the Component ID for Y sensor RAW Data
    > > Heading CON $5 'Defines the Component ID for Heading
    > > Mag CON $6 'Defines the Component ID for Magnetude
    > > Dist CON $8 'Defines the Component ID for the distortion flag
    > > CalStatus CON $9 'Defines the Component ID for calibration status
    > >
    > > SaveConfig CON $9 'Defines the SaveConfig frame type
    > > GetData CON $4 'Defines the frame type which queries the V2Xe for data
    > > components
    > > DataResp CON $5 'Defines the response to command GetData frame type
    > >
    > > Term CON $00 'Defines Terminator which is the last byte of any
    > > command
    > >
    > >
    > >
    > > 'Declare Variables for Response Datagrams
    > > FlagIn VAR BYTE 'Defines Sync Flag in the response Datagram
    > > FrameIn VAR BYTE 'Defines the Frame Type in the response Datagram
    > > CountIn VAR BYTE 'Defines the number of components in the response
    > > Datagram
    > > XRawIn VAR BYTE 'Defines the XRaw ID in the response Datagram
    > > XRawVal VAR WORD(2) 'Defines the XRaw value array in the response Datagram
    > > YRawIn VAR BYTE 'Defines the YRaw ID in the response Datagram
    > > YRawVal VAR WORD(2) 'Defines the YRaw value array in the response Datagram
    > > HeadingIn VAR BYTE 'Defines the Heading ID in the response
    > > Datagram
    > > HeadingVAL VAR BYTE(4) 'Defines the Heading value array
    > > CompHeading VAR WORD 'Defines the Heading
    > > Exponent VAR BYTE 'Defines value for Heading calculation
    > > TermIn VAR BYTE 'Defines the Terminator of the resonse Datagram
    > >
    > >
    > > 'Interface with the V2Xe
    > > High SSNOT
    > > LOW SSNOT 'Enable SPI Port
    > >
    > > 'Set the data componets to be read from the V2Xe (Heading and Magnitude)
    > > LOW SYNC
    > > PULSOUT SYNC,2 'Not required
    > > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,SetDataComponents,$1,Heading,Term]
    > > 'Set Heading as output
    > > Pause 1
    > > Begin:
    > > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,GetData,Term]
    > > 'Request output (Heading)
    > >
    > > Loop:
    > > ShiftIn MISO,SCLK,MSBPre,[noparse][[/noparse]FlagIn]
    > > 'Look for Sync Flag
    > > If FlagIn <> $AA THEN Loop
    > >
    > > ShiftIn
    > >
    > MISO,SCLK,MSBPre,[noparse][[/noparse]FrameIn,CountIn,HeadingIn,HeadingVal(0),HeadingVal(1),Head
    > ingVal(2)
    > > ,HeadingVal(3),TermIn] 'Shift in data (Heading)
    > >
    > >
    > > 'IEEE 32 bit floating point to scaled integer
    > > 'Integer will be scaled * 8 (i.e. 1 = 1/8, 2 = 1/4, 3 = 3/8, 4 = 1/2 ... 8
    > = 1.0 )
    > >
    > > 'IEEE32 format:
    > >
    > > '31............24...23............16...15.............8...7..............0
    > > 'S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F F F
    > > 'HeadingVal(0) HeadingVal(1) HeadingVal(2) HeadingVal(3)
    > > //For Compass Heading
    > > 'MagVal(0) MagVal(1) MagVal(2) MagVal(3)
    > > //For Magnitude
    > >
    > > 'S = Sign
    > > 'E = Exponent
    > > 'F = Mantisa or Binary Fraction
    > >
    > > 'Number = 1.F * 2^(E-127)
    > >
    > > 'The code below will assume Sign = 0 (number is positive) for all headings
    > > 'if the heading is less than 1 degree or zero (the IEEE32 version of zero)
    > > 'IMPORTANT!!! This code truncates to the nearest decimal instead of
    > rounding.
    > >
    > >
    > > HeadingVal(0) = HeadingVal(0) * 2 'Shift Exponent
    > >
    > > IF HeadingVal(1) < 128 THEN Step1
    > > HeadingVal(0) = HeadingVal(0) + 1
    > >
    > > Step1:
    > > Exponent = HeadingVal(0)
    > >
    > > Step2:
    > > IF Exponent > 126 THEN Step3 'Zero Test
    > > CompHeading = 0
    > > GOTO Done
    > >
    > > Step3:
    > > CompHeading = 1
    > >
    > > Loop2: 'Main loop to extract the Heading
    > > integer information
    > > IF Exponent = 127 THEN Done
    > > CompHeading = CompHeading * 2
    > > HeadingVal(1) = HeadingVal(1) * 2
    > > IF HeadingVal(1) < 128 THEN Step4
    > > CompHeading = CompHeading + 1
    > >
    > > Step4:
    > > IF HeadingVal(2) < 128 THEN Step5
    > > HeadingVal(1) = HeadingVal(1) + 1
    > >
    > > Step5:
    > > HeadingVal(2) = HeadingVal(2) * 2
    > > Exponent = Exponent - 1
    > >
    > > GOTO Loop2
    > >
    > > Done:
    > >
    > >
    > > 'Display Heading
    > > DEBUG "Heading: ",DEC CompHeading, CR,10
    > >
    > > Pause 500
    > >
    > > GOTO Begin 'Repeat
    > > High SSNOT 'Disable SPI Port
    > > END
    > >
    > >
    > >
    > >
    > > To UNSUBSCRIBE, just send mail to:
    > > basicstamps-unsubscribe@yahoogroups.com
    > > from the same email address that you subscribed. Text in the Subject and
    > Body of the message will be ignored.
    > >
    > > Yahoo! Groups Links
    > >
    > >
    > >
    > >
    > >
    > >
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 23:28
    Please see www.emesystems.com

    ken

    ===================
    I was given this bit of code from a coworker who used it in a C++ program. I
    have tried to
    get it to work on the BasicStamp to no avail. Any help is appreciated!

    Julian


    [noparse][[/noparse]Non-text portions of this message have been removed]
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 23:31
    Julian,

    All the BS2 math help you should need can be found at
    http://www.emesystems.com/BS2index.htm#math

    ken
    Klaus,

    It was C++ but I have changed it to work with the Basic Stamp. The part that
    is giving me
    problems is where I am trying to convert the IEEE 32 bit number output into
    an integer.
    The output should be a value between 0 - 360. Right now I mostly just get 0
    as an output
    with an occational random number.

    I keep thinking there must be an easier way, but I am new to the Basic Stamp.

    Julian


    [noparse][[/noparse]Non-text portions of this message have been removed]
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 23:32
    Julian,

    As Klaus wrote, no floating point math with the stamp, but there are ways to
    get floating point numbers......

    I posted a link to a sight that will help.

    Or, please give a calculation example of exactly what you want,,,,,ex



    Ken


    ========================
    Hi Julian,

    I believe the Basic Stamp has no floating point type, only bit-nibble-byte
    and word.

    Assuming the float value comes from anywhere outside of the Stamp the
    easiest approach might be to multiply the value before it comes into the
    Stamp in such a way that it fits in a word size. Then, when the value is
    transfered, it will be transformed to a word (=two bytes) automatically.
    Values will be cut to the lowest whole number, just as is done in your
    example code. Afterwards you can scale your integer value as you like.

    I hope this helps a bit,

    Klaus


    [noparse][[/noparse]Non-text portions of this message have been removed]
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-08 23:52
    Hi Julian,

    I believe the Basic Stamp has no floating point type, only bit-nibble-byte
    and word.

    Assuming the float value comes from anywhere outside of the Stamp the
    easiest approach might be to multiply the value before it comes into the
    Stamp in such a way that it fits in a word size. Then, when the value is
    transfered, it will be transformed to a word (=two bytes) automatically.
    Values will be cut to the lowest whole number, just as is done in your
    example code. Afterwards you can scale your integer value as you like.

    I hope this helps a bit,

    Klaus
    Original Message
    From: "julianbntn" <julianb@s...>
    To: <basicstamps@yahoogroups.com>
    Sent: Tuesday, June 08, 2004 11:43 PM
    Subject: [noparse][[/noparse]basicstamps] Re: Converting IEEE 32 bit floating point to scaled
    integer


    > Klaus,
    >
    > It was C++ but I have changed it to work with the Basic Stamp. The part
    that is giving me
    > problems is where I am trying to convert the IEEE 32 bit number output
    into an integer.
    > The output should be a value between 0 - 360. Right now I mostly just get
    0 as an output
    > with an occational random number.
    >
    > I keep thinking there must be an easier way, but I am new to the Basic
    Stamp.
    >
    > Julian
    >
    > --- In basicstamps@yahoogroups.com, "K de Jong" <klaus0@x> wrote:
    > > Hi Julian,
    > >
    > > What is your code supposed to do? It does not look like C++ really!
    > >
    > > Regards,
    > >
    > > Klaus
    > >
    Original Message
    > > From: "julianbntn" <julianb@s...>
    > > To: <basicstamps@yahoogroups.com>
    > > Sent: Tuesday, June 08, 2004 9:43 PM
    > > Subject: [noparse][[/noparse]basicstamps] Converting IEEE 32 bit floating point to scaled
    > > integer
    > >
    > >
    > > > I was given this bit of code from a coworker who used it in a C++
    program.
    > > I have tried to
    > > > get it to work on the BasicStamp to no avail. Any help is
    appreciated!
    > > >
    > > > Julian
    > > >
    > > > '{$Stamp BS2p} 'Stamp Directive (specifies BS2P)
    > > >
    > > > '*********************************************************************
    > > > ' OEM Example Program for the Basic Stamp 2p uProcessor to
    > > > ' interface with a PNI Corporation V2Xe 2 Axis Compass Module.
    > > > ' This program shows how to get the Heading from the V2Xe.
    > > > ' Copyright 20Dec2003, PNI Corporation
    > > > ' Written by Julian Benton, Applications Engineer
    > > > ' Contact: jbenton@p... , 707-566-2260 x356
    > > > '*********************************************************************
    > > >
    > > > 'Declare Lines
    > > > SYNC CON 5 'SYNC is pin 5
    > > > SSNOT CON 7 'SSNOT is pin 7
    > > > MOSI CON 8 'MOSI is pin 8
    > > > MISO CON 9 'MISO is pin 9
    > > > SCLK CON 10 'SCLK is pin 10
    > > >
    > > > 'Declare Global Constants for Command Datagrams
    > > > Flag CON $AA 'Defines Sync Flag which is the first byte of any command
    > > > GetModInfo CON $1 'Defines the frame type that queries the V2Xe for
    > > > module information
    > > > ModInfoResp CON $2 'Defines the response frame type to command
    > > > GetModInfo
    > > > SetDataComponents CON $3 'Defines the frame type for the data
    components
    > > to
    > > > be sent back
    > > > XRaw CON $1 'Defines the Component ID for X sensor RAW Data
    > > > YRaw CON $2 'Defines the Component ID for Y sensor RAW Data
    > > > Heading CON $5 'Defines the Component ID for Heading
    > > > Mag CON $6 'Defines the Component ID for Magnetude
    > > > Dist CON $8 'Defines the Component ID for the distortion flag
    > > > CalStatus CON $9 'Defines the Component ID for calibration status
    > > >
    > > > SaveConfig CON $9 'Defines the SaveConfig frame type
    > > > GetData CON $4 'Defines the frame type which queries the V2Xe for data
    > > > components
    > > > DataResp CON $5 'Defines the response to command GetData frame type
    > > >
    > > > Term CON $00 'Defines Terminator which is the last byte of any
    > > > command
    > > >
    > > >
    > > >
    > > > 'Declare Variables for Response Datagrams
    > > > FlagIn VAR BYTE 'Defines Sync Flag in the response Datagram
    > > > FrameIn VAR BYTE 'Defines the Frame Type in the response Datagram
    > > > CountIn VAR BYTE 'Defines the number of components in the response
    > > > Datagram
    > > > XRawIn VAR BYTE 'Defines the XRaw ID in the response Datagram
    > > > XRawVal VAR WORD(2) 'Defines the XRaw value array in the response
    Datagram
    > > > YRawIn VAR BYTE 'Defines the YRaw ID in the response Datagram
    > > > YRawVal VAR WORD(2) 'Defines the YRaw value array in the response
    Datagram
    > > > HeadingIn VAR BYTE 'Defines the Heading ID in the response
    > > > Datagram
    > > > HeadingVAL VAR BYTE(4) 'Defines the Heading value array
    > > > CompHeading VAR WORD 'Defines the Heading
    > > > Exponent VAR BYTE 'Defines value for Heading calculation
    > > > TermIn VAR BYTE 'Defines the Terminator of the resonse Datagram
    > > >
    > > >
    > > > 'Interface with the V2Xe
    > > > High SSNOT
    > > > LOW SSNOT 'Enable SPI Port
    > > >
    > > > 'Set the data componets to be read from the V2Xe (Heading and
    Magnitude)
    > > > LOW SYNC
    > > > PULSOUT SYNC,2 'Not required
    > > > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,SetDataComponents,$1,Heading,Term]
    > > > 'Set Heading as output
    > > > Pause 1
    > > > Begin:
    > > > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,GetData,Term]
    > > > 'Request output (Heading)
    > > >
    > > > Loop:
    > > > ShiftIn MISO,SCLK,MSBPre,[noparse][[/noparse]FlagIn]
    > > > 'Look for Sync Flag
    > > > If FlagIn <> $AA THEN Loop
    > > >
    > > > ShiftIn
    > > >
    > >
    MISO,SCLK,MSBPre,[noparse][[/noparse]FrameIn,CountIn,HeadingIn,HeadingVal(0),HeadingVal(1),Head
    > > ingVal(2)
    > > > ,HeadingVal(3),TermIn] 'Shift in data (Heading)
    > > >
    > > >
    > > > 'IEEE 32 bit floating point to scaled integer
    > > > 'Integer will be scaled * 8 (i.e. 1 = 1/8, 2 = 1/4, 3 = 3/8, 4 = 1/2
    ... 8
    > > = 1.0 )
    > > >
    > > > 'IEEE32 format:
    > > >
    > > >
    '31............24...23............16...15.............8...7..............0
    > > > 'S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F
    F F
    > > > 'HeadingVal(0) HeadingVal(1) HeadingVal(2)
    HeadingVal(3)
    > > > //For Compass Heading
    > > > 'MagVal(0) MagVal(1) MagVal(2) MagVal(3)
    > > > //For Magnitude
    > > >
    > > > 'S = Sign
    > > > 'E = Exponent
    > > > 'F = Mantisa or Binary Fraction
    > > >
    > > > 'Number = 1.F * 2^(E-127)
    > > >
    > > > 'The code below will assume Sign = 0 (number is positive) for all
    headings
    > > > 'if the heading is less than 1 degree or zero (the IEEE32 version of
    zero)
    > > > 'IMPORTANT!!! This code truncates to the nearest decimal instead of
    > > rounding.
    > > >
    > > >
    > > > HeadingVal(0) = HeadingVal(0) * 2 'Shift Exponent
    > > >
    > > > IF HeadingVal(1) < 128 THEN Step1
    > > > HeadingVal(0) = HeadingVal(0) + 1
    > > >
    > > > Step1:
    > > > Exponent = HeadingVal(0)
    > > >
    > > > Step2:
    > > > IF Exponent > 126 THEN Step3 'Zero Test
    > > > CompHeading = 0
    > > > GOTO Done
    > > >
    > > > Step3:
    > > > CompHeading = 1
    > > >
    > > > Loop2: 'Main loop to extract the Heading
    > > > integer information
    > > > IF Exponent = 127 THEN Done
    > > > CompHeading = CompHeading * 2
    > > > HeadingVal(1) = HeadingVal(1) * 2
    > > > IF HeadingVal(1) < 128 THEN Step4
    > > > CompHeading = CompHeading + 1
    > > >
    > > > Step4:
    > > > IF HeadingVal(2) < 128 THEN Step5
    > > > HeadingVal(1) = HeadingVal(1) + 1
    > > >
    > > > Step5:
    > > > HeadingVal(2) = HeadingVal(2) * 2
    > > > Exponent = Exponent - 1
    > > >
    > > > GOTO Loop2
    > > >
    > > > Done:
    > > >
    > > >
    > > > 'Display Heading
    > > > DEBUG "Heading: ",DEC CompHeading, CR,10
    > > >
    > > > Pause 500
    > > >
    > > > GOTO Begin 'Repeat
    > > > High SSNOT 'Disable SPI Port
    > > > END
    > > >
    > > >
    > > >
    > > >
    > > > To UNSUBSCRIBE, just send mail to:
    > > > basicstamps-unsubscribe@yahoogroups.com
    > > > from the same email address that you subscribed. Text in the Subject
    and
    > > Body of the message will be ignored.
    > > >
    > > > Yahoo! Groups Links
    > > >
    > > >
    > > >
    > > >
    > > >
    > > >
    >
    >
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject and
    Body of the message will be ignored.
    >
    > Yahoo! Groups Links
    >
    >
    >
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-09 08:49
    I like what Jack Crenshaw said about IEEE floating point format:

    "There are almost as many floating point formats as there are
    compilers; each vendor seemed to use its own until IEEE stepped in
    and defined the most complicated format humanly possible. Most
    compiler venders and CPU designers try to adhere to the IEEE
    standard, but most also take liberties with it because the full IEEE
    standard includes many requirements that affect system performance..."

    > 'Number = 1.F * 2^(E-127)

    This comment and others from your program suggests a 23 bit mantissa
    and an 8 bit exponent. The exponent offset by 127. No phantom bits.
    Presumably with the decimal point is assumed to be always just to the
    left of the mantissa, so the mantissa is always a number greater than
    or equal to 1/2 and less than one. So, some example numbers...

    N exponent mantissa mantissa represents
    Number
    1 EEEEEEEE=128 F=$400000 (F=0.5, binary
    %0.10000000000000000000000) (Number=0.5 * 2^(128-127)=1)
    2 EEEEEEEE=129 F=$400000 (F=0.5, binary
    %0.10000000000000000000000) (Number=0.5 * 2^(129-127)=2)
    0.5 EEEEEEEE=127 F=$400000 (F=0.5, binary
    %0.10000000000000000000000) (Number=0.5 * 2^(127-127)=0.5)
    360 EEEEEEEE=136 F=$B40000 (F=.703125 binary
    %0.10110100000000000000000) (Number=0.703125 * 2^(136-127)=360)

    This is where I am a little unclear. Is the data from the compass
    indeed in units of degrees and fractional degrees? Not radians or
    percent or something?

    About this step,

    > HeadingVal(0) = HeadingVal(0) * 2
    > 'Shift Exponent

    That discards the least significant bit of the exponent, which is
    probably needed. Maybe it should be:
    EEEEEEEE = (HeadingVal(0) <<1) + (HeadingVal(1)>>7) ' 8 bit exponent


    I wonder if something like the following would work to extract the
    integer degrees (0 to 360)?

    finalAnswer VAR word
    finalAnswer=headingVal(1) & 7f << 2 + (headingVal(2) >> 6) ' 9
    bits of mantissa
    finalAnswer = finalAnswer >> (136 - EEEEEEEE)

    The idea is to put 9 bits of the mantissa into one word. That will
    cover all integer angles up to 360 degrees. The statement works by
    combining the low 7 bits of headingVal(1) with the high two bits of
    headingVal(2). Then in the last statement, shift that right by the
    exponent. For example, if the angle is 360 degrees, you end up with
    %101101000 in finalAnswer, shifted by zero, 360 the final answer. If
    the angle is 2 degrees, you end up with %100000000 in finalAnswer,
    shifted by (136-129=7), resulting in %10 = 2, the final answer.

    I may be way off base about how the data is represented, but if not,
    the C++ transcription is needlessly complicated.

    -- regards,
    Tracy








    >I was given this bit of code from a coworker who used it in a C++
    >program. I have tried to
    >get it to work on the BasicStamp to no avail. Any help is appreciated!
    >
    >Julian
    >
    >'{$Stamp BS2p} 'Stamp Directive (specifies BS2P)
    >
    >'*********************************************************************
    >' OEM Example Program for the Basic Stamp 2p uProcessor to
    >' interface with a PNI Corporation V2Xe 2 Axis Compass Module.
    >' This program shows how to get the Heading from the V2Xe.
    >' Copyright 20Dec2003, PNI Corporation
    >' Written by Julian Benton, Applications Engineer
    >' Contact: jbenton@p... , 707-566-2260 x356
    >'*********************************************************************
    >
    >'Declare Lines
    >SYNC CON 5 'SYNC is pin 5
    >SSNOT CON 7 'SSNOT is pin 7
    >MOSI CON 8 'MOSI is pin 8
    >MISO CON 9 'MISO is pin 9
    >SCLK CON 10 'SCLK is pin 10
    >
    >'Declare Global Constants for Command Datagrams
    >Flag CON $AA 'Defines Sync
    >Flag which is the first byte of any command
    >GetModInfo CON $1 'Defines the
    >frame type that queries the V2Xe for
    >module information
    >ModInfoResp CON $2 'Defines the response
    >frame type to command
    >GetModInfo
    >SetDataComponents CON $3 'Defines the frame
    >type for the data components to
    >be sent back
    > XRaw CON $1 'Defines the
    >Component ID for X sensor RAW Data
    > YRaw CON $2 'Defines the
    >Component ID for Y sensor RAW Data
    > Heading CON $5 'Defines the
    >Component ID for Heading
    > Mag CON $6 'Defines the
    >Component ID for Magnetude
    > Dist CON $8 'Defines the
    >Component ID for the distortion flag
    > CalStatus CON $9 'Defines the
    >Component ID for calibration status
    >
    >SaveConfig CON $9 'Defines the
    >SaveConfig frame type
    >GetData CON $4 'Defines the
    >frame type which queries the V2Xe for data
    >components
    >DataResp CON $5 'Defines the
    >response to command GetData frame type
    >
    >Term CON $00 'Defines
    >Terminator which is the last byte of any
    >command
    >
    >
    >
    >'Declare Variables for Response Datagrams
    >FlagIn VAR BYTE 'Defines Sync Flag in
    >the response Datagram
    >FrameIn VAR BYTE 'Defines the
    >Frame Type in the response Datagram
    >CountIn VAR BYTE 'Defines the
    >number of components in the response
    >Datagram
    >XRawIn VAR BYTE 'Defines the XRaw ID
    >in the response Datagram
    >XRawVal VAR WORD(2) 'Defines the XRaw
    >value array in the response Datagram
    >YRawIn VAR BYTE 'Defines the YRaw ID
    >in the response Datagram
    >YRawVal VAR WORD(2) 'Defines the YRaw
    >value array in the response Datagram
    >HeadingIn VAR BYTE 'Defines the
    >Heading ID in the response
    >Datagram
    >HeadingVAL VAR BYTE(4) 'Defines the Heading
    >value array
    >CompHeading VAR WORD 'Defines the Heading
    >Exponent VAR BYTE 'Defines
    >value for Heading calculation
    >TermIn VAR BYTE 'Defines the
    >Terminator of the resonse Datagram
    >
    >
    >'Interface with the V2Xe
    > High SSNOT
    > LOW SSNOT 'Enable SPI Port
    >
    >'Set the data componets to be read from the V2Xe (Heading and Magnitude)
    > LOW SYNC
    > PULSOUT SYNC,2 'Not required
    > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,SetDataComponents,$1,Heading,Term]
    > 'Set Heading as output
    > Pause 1
    >Begin:
    > ShiftOut MOSI,SCLK,MSBFirst,[noparse][[/noparse]Flag,GetData,Term]
    > 'Request output (Heading)
    >
    > Loop:
    > ShiftIn MISO,SCLK,MSBPre,[noparse][[/noparse]FlagIn]
    > 'Look for Sync Flag
    > If FlagIn <> $AA THEN Loop
    >
    > ShiftIn
    >MISO,SCLK,MSBPre,[noparse][[/noparse]FrameIn,CountIn,HeadingIn,HeadingVal(0),HeadingVal(1),HeadingVal(2)
    >,HeadingVal(3),TermIn] 'Shift in data (Heading)
    >
    >
    >'IEEE 32 bit floating point to scaled integer
    >'Integer will be scaled * 8 (i.e. 1 = 1/8, 2 = 1/4, 3 = 3/8, 4 = 1/2
    >... 8 = 1.0 )
    >
    >'IEEE32 format:
    >
    >
    > '31............24...23............16...15.............8...7..............0
    > 'S E E E E E E E E F F F F F F F F F F F F F F F F F
    >F F F F F F
    > 'HeadingVal(0) HeadingVal(1) HeadingVal(2)
    >HeadingVal(3)
    > //For Compass Heading
    > 'MagVal(0) MagVal(1) MagVal(2) MagVal(3)
    > //For Magnitude
    >
    > 'S = Sign
    > 'E = Exponent
    > 'F = Mantisa or Binary Fraction
    >
    > 'Number = 1.F * 2^(E-127)
    >
    > 'The code below will assume Sign = 0 (number is positive) for
    >all headings
    > 'if the heading is less than 1 degree or zero (the IEEE32
    >version of zero)
    > 'IMPORTANT!!! This code truncates to the nearest decimal
    >instead of rounding.
    >
    >
    > HeadingVal(0) = HeadingVal(0) * 2
    > 'Shift Exponent
    >
    > IF HeadingVal(1) < 128 THEN Step1
    > HeadingVal(0) = HeadingVal(0) + 1
    >
    > Step1:
    > Exponent = HeadingVal(0)
    >
    > Step2:
    > IF Exponent > 126 THEN Step3
    > 'Zero Test
    > CompHeading = 0
    > GOTO Done
    >
    > Step3:
    > CompHeading = 1
    >
    > Loop2:
    > 'Main loop to extract the Heading
    >integer information
    > IF Exponent = 127 THEN Done
    > CompHeading = CompHeading * 2
    > HeadingVal(1) = HeadingVal(1) * 2
    > IF HeadingVal(1) < 128 THEN Step4
    > CompHeading = CompHeading + 1
    >
    > Step4:
    > IF HeadingVal(2) < 128 THEN Step5
    > HeadingVal(1) = HeadingVal(1) + 1
    >
    > Step5:
    > HeadingVal(2) = HeadingVal(2) * 2
    > Exponent = Exponent - 1
    >
    > GOTO Loop2
    >
    > Done:
    >
    >
    >'Display Heading
    > DEBUG "Heading: ",DEC CompHeading, CR,10
    >
    > Pause 500
    >
    > GOTO Begin
    > 'Repeat
    > High SSNOT
    > 'Disable SPI Port
    >END
    >
    >
    >
    >
    >To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    >from the same email address that you subscribed. Text in the
    >Subject and Body of the message will be ignored.
    >
    >Yahoo! Groups Links
    >
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-09 16:15
    Julian and all,
    You may also want to try out this new floating point coprocessor -
    http://www.parallax.com/detail.asp?product_id=604-00030a


    Erik Wood
    Parallax, Inc.

    Original Message
    From: smartdim@a... [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=HA8GS1yipLJO9Tz8s6oTaK1Ae1cPpim-wK7x8xYKwI-sjAg1ErmQZaQvkvfiStHVGa4RZsMh7Q]smartdim@a...[/url
    Sent: Tuesday, June 08, 2004 7:31 PM
    To: basicstamps@yahoogroups.com
    Subject: Re: [noparse][[/noparse]basicstamps] Re: Converting IEEE 32 bit floating point to
    scaled integer

    Julian,

    All the BS2 math help you should need can be found at
    http://www.emesystems.com/BS2index.htm#math

    ken
    Klaus,

    It was C++ but I have changed it to work with the Basic Stamp. The part
    that
    is giving me
    problems is where I am trying to convert the IEEE 32 bit number output
    into
    an integer.
    The output should be a value between 0 - 360. Right now I mostly just
    get 0
    as an output
    with an occational random number.

    I keep thinking there must be an easier way, but I am new to the Basic
    Stamp.

    Julian


    [noparse][[/noparse]Non-text portions of this message have been removed]



    To UNSUBSCRIBE, just send mail to:
    basicstamps-unsubscribe@yahoogroups.com
    from the same email address that you subscribed. Text in the Subject
    and Body of the message will be ignored.

    Yahoo! Groups Links







    This message has been scanned by WebShield. Please report SPAM to
    abuse@p....
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-09 17:42
    Erik,

    Yes, I saw the coprocessor and will be purchasing one, but not all of my customers will be
    using the coprocessor so I hoped to come up with another example that I could supply
    them.

    Julian

    --- In basicstamps@yahoogroups.com, "Erik Wood" <ewood@p...> wrote:
    > Julian and all,
    > You may also want to try out this new floating point coprocessor -
    > http://www.parallax.com/detail.asp?product_id=604-00030a
    >
    >
    > Erik Wood
    > Parallax, Inc.
    >
    >
    Original Message
    > From: smartdim@a... [noparse][[/noparse]mailto:smartdim@a...]
    > Sent: Tuesday, June 08, 2004 7:31 PM
    > To: basicstamps@yahoogroups.com
    > Subject: Re: [noparse][[/noparse]basicstamps] Re: Converting IEEE 32 bit floating point to
    > scaled integer
    >
    > Julian,
    >
    > All the BS2 math help you should need can be found at
    > http://www.emesystems.com/BS2index.htm#math
    >
    > ken
    >
    > Klaus,
    >
    > It was C++ but I have changed it to work with the Basic Stamp. The part
    > that
    > is giving me
    > problems is where I am trying to convert the IEEE 32 bit number output
    > into
    > an integer.
    > The output should be a value between 0 - 360. Right now I mostly just
    > get 0
    > as an output
    > with an occational random number.
    >
    > I keep thinking there must be an easier way, but I am new to the Basic
    > Stamp.
    >
    > Julian
    >
    >
    > [noparse][[/noparse]Non-text portions of this message have been removed]
    >
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject
    > and Body of the message will be ignored.
    >
    > Yahoo! Groups Links
    >
    >
    >
    >
    >
    >
    >
    > This message has been scanned by WebShield. Please report SPAM to
    > abuse@p...
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-09 21:17
    Hi Julian,

    It might help if we could see the 32 bit values that the compass
    kicks out at a few known compass points, N-E-S-W.


    -- Tracy




    >Erik,
    >
    >Yes, I saw the coprocessor and will be purchasing one, but not all
    >of my customers will be
    >using the coprocessor so I hoped to come up with another example
    >that I could supply
    >them.
    >
    >Julian
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-10 04:47
    Hi Julian,

    I've looked at the code you provided and it does properly convert 32-bit IEEE positive
    floating point values to the truncated integer value. As Tracy points out, if the values are
    known to be in the range 0 to 360 you can simplify the code using his suggestion, but it
    needs to account for the implicit one bit in the mantissa for normalized IEEE numbers.
    The modified code using your original variable names is as follows:

    Exponent = (HeadingVal(0) << 1) + (headingVal(1) >> 7)
    CompHeading = ($80 + (headingVal(1) & $7F)) << 2 + (headingVal(2) >> 6)
    CompHeading = CompHeading >> (136 - Exponent)

    Your original code does seem to work, but it is much less efficient with all the looping and
    testing.

    Since your original message indicated that you were getting lots of zeros and random
    numbers it might suggest that the input values are not correct. A couple of suggestions
    for testing:

    You can force the headingVal to a known IEEE number and see the converted result.
    e.g. the test value for 360 is:
    HeadingVal(0) = $43
    HeadingVal(1) = $B4
    HeadingVal(2) = $00
    HeadingVal(3) = $00

    If you go to the uM-FPU link on the Parallax site there's a free download of the uM-FPU
    Converter program. You can use this to easily generate test values and also to verify the
    values coming from your instrument. If you enter a floating point number in the Input
    String box it will convert to the corresponding 32-bit hex value, and if you enter a $ first it
    converts from a 32-bit value to the floating equivalent.

    You can also copy and paste, so if you put the following statement in your code just after
    you get the heading value from your instrument:

    DEBUG "$", HEX2 HeadingVal(0), HEX2 HeadingVal(1), HEX2 HeadingVal(2), HEX2
    HeadingVal(3), CR

    Then you can copy the resulting $xxxxxxxx string from the Terminal window and paste it
    into the Input String box of the uM-FPU converter and it will show the corresponding
    floating point value.

    Hope this helps,
    Cam
  • ArchiverArchiver Posts: 46,084
    edited 2004-06-10 15:11
    Hi Julian,

    A couple more thoughts on your problem. Since your application is
    compass headings you probably want rounding rather than truncation
    so that 22.7 degrees becomes 23 not 22. Also, 360 degrees usually
    wraps back to 0 degrees. If the values are problematic you should
    also do some error checking to ensure the number really is in the
    range 0 to 360. The following code is a further modification of the
    earlier code to provide a robust converter that can handle any
    floating point number and yields an integer in the range 0 to 359 if
    the value is valid or 999 if it's an error condition. The error
    condition is defined as follows:
    - any number less than or equal to -0.5
    - any number greater than or equal to 360.5

    Code:

    Exponent = (HeadingVal(0) << 1) + (headingVal(1) >> 7)
    IF Exponent < 126 THEN
    CompHeading = 0
    ELSEIF (Exponent > 135) OR (HeadingVal(0) > 127) THEN
    CompHeading = 999 'error condition
    ELSE
    CompHeading = ($80 | headingVal(1)) << 2 + (headingVal(2) >> 6)
    CompHeading = CompHeading >> (135 - Exponent)
    IF CompHeading.LOWBIT = 1 THEN Compheading = CompHeading + 1
    Compheading = Compheading >> 1
    IF Compheading = 360 THEN
    Compheading = 0
    ELSEIF Compheading > 360 THEN
    CompHeading = 999 'error condition
    ENDIF
    ENDIF

    Brief Explanation:
    - the exponent is extracted
    - if exponent < 126, the number is between 0.5 and -0.5 so it's
    rounded to zero
    - if exponent > 135, the number is larger than the 9 bits we're
    converting so the 999 error is set
    - if headingVal(0) > 127 the number is negative so the 999 error is
    set
    - ten bits are loaded into compHeading (9 integer bits and 1
    rounding bit)
    - compHeading is shifted right to get the value*2 with LSB bit as
    the rounding bit
    - if the rounding bit is set, it means the remaining fraction is
    greater than or equal to 0.5, so the value is rounded up
    - compHeading is shifted right to get final result
    - compheading is checked for wraparound at 360, or an error
    condition if > 360

    This should give you a solid base for your tests. If you see any
    999 values then you know you're getting reading that are out of
    range. If you're still having trouble, then as Tracy suggested,
    give us the hex value of headingVal(0) to (4) for N-E-S-W so we can
    check the format.

    e.g. put the following right after you get the reading:
    DEBUG HEX2 HeadingVal(0),HEX2 HeadingVal(1),HEX2 HeadingVal(2),HEX2
    HeadingVal(3),CR

    Regards,
    Cam
Sign In or Register to comment.