Converting IEEE 32 bit floating point to scaled integer
Archiver
Posts: 46,084
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
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
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
>
>
>
>
>
>
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
> >
> >
> >
> >
> >
> >
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]
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]
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]
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
>
>
>
>
>
>
"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
>
>
>
>
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....
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...
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
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
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