News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

floating number display problem

Started by basiclover, Jan 08, 2022, 11:26 AM

Previous topic - Next topic

basiclover

Hi all
using PIC16F877 and an alphanumeric LCD
1)a floating value of 1250000 displays as 1250000.125
2)when I add a digit i.e. 12500000 it displays as 0.000
Is this due to the compiler or to the pic?
thanks for explanation

trastikata


basiclover

'****************************************************************
'*  Name    : 16F877 32 bit floating calculation.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 1/7/2022                                          *
'*  Version : 1                                              *
'*  Notes   : 32 bit floating calculation                                                 *
'*          :                                                   *
'****************************************************************

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16F877A

Config FOSC_HS, WDTE_OFF, PWRTE_OFF, BOREN_ON, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, CP_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------

 ' LCD defs
    Declare LCD_Type = 0       'HITACHI HD44780 controller
    Declare LCD_DTPin PORTB.4  '4 pin config, data on 4 top pins(PortB4 to B7) of port B
    Declare LCD_RSPin = PORTB.3
    Declare LCD_ENPin = PORTB.2
    Declare LCD_Lines = 2
    Declare LCD_DataUs 75     'LCD time to wait beween data sent(microsec)for some older 16x2 44780 compatible displays (default = 50)

    Declare Xtal = 20     
   
    Dim var_1 As Float
    Dim var_2 As Float
    Dim var_3 As Float
     
    Dim Result As Float
   
   
    var_2= 2251800     'displays as 2251800.250, but 0.000 if I add a digit
   
     
    ADCON1 = 6 ' Set all ports A to digital
    TRISA=%00000000 'set all portA to output
    TRISB=%00000011 'RB0 RB1=inputs, other=outputs
    TRISC=%00000100 'RC2 =input
    TRISD=%00000000 'RCD =ouputs
   
    Cls
    GoTo main
main:
   
    Print At 2,1, Dec var_2
    GoTo main
    End

trastikata

Try this code:

'****************************************************************
'*  Name    : 16F877 32 bit floating calculation.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 1/7/2022                                          *
'*  Version : 1                                              *
'*  Notes   : 32 bit floating calculation                                                 *
'*          :                                                   *
'****************************************************************

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16F877A

Config FOSC_HS, WDTE_OFF, PWRTE_OFF, BOREN_ON, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, CP_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------

 ' LCD defs
    Declare LCD_Type = 0       'HITACHI HD44780 controller
    Declare LCD_DTPin PORTB.4  '4 pin config, data on 4 top pins(PortB4 to B7) of port B
    Declare LCD_RSPin = PORTB.3
    Declare LCD_ENPin = PORTB.2
    Declare LCD_Lines = 2
    Declare LCD_DataUs 75     'LCD time to wait beween data sent(microsec)for some older 16x2 44780 compatible displays (default = 50)
    Declare Float_Display_Type = LARGE
   
    Declare Xtal = 20     
   
    Dim var_1 As Float
    Dim var_2 As Float
    Dim var_3 As Float
     
    Dim Result As Float
   
   
    var_2= 2251800.00     'displays as 2251800.250, but 0.000 if I add a digit
   
     
    ADCON1 = 6 ' Set all ports A to digital
    TRISA=%00000000 'set all portA to output
    TRISB=%00000011 'RB0 RB1=inputs, other=outputs
    TRISC=%00000100 'RC2 =input
    TRISD=%00000000 'RCD =ouputs
   
    Cls
    GoTo main
main:
   
    Print At 2,1, Dec var_2
    GoTo main
    End

basiclover

no change with your suggestion
looking in the manual found "Declare Float_Display_Type = Fast"
tried that, but when adding a digit it displays nothing anymore

trastikata

Looks like limitation of the 32-bit floating point representation.

With 8 digits in the floating point number, there's no place in the mantissa for fractions. This seems to cause troubles in the print routine.

With 7 digits, increase by 1 in the mantissa LSB equals to 0.25 in deimal.

Thus use integer variables if you can with 8 digit numbers and they should print correctly. Or better use Dwords and work-out the fractional decimal math in two Dwords and write a routine for printing the two dwords as a float number.

basiclover


top204

#7
32-bit floating point variables have a limit as to what they can format into their bits, so large values are not recommended for them, because they will not give the accuracy in their fractional parts. Remember, floating point is a form of compression for fractional decimal values, based upon rotations, so it does have limitations. If larger floating point values are an absolute requirement, use the Positron16 compiler with PIC24 or dsPIC33 devices and its 64-bit Double variables.

However, quite large values will still be handled and displayed. Below is a simple demo of a large value being displayed on an LCD and transmitted to a serial terminal, using an old standard 14-bit core device, using the value you gave in your enquiries. The fractional display part of the Dec command is set to 1 (Dec1), because accuracy is at a minimum with such large values. If the value is too large for the 32-bit floating point format to handle, internal exceptions may occur and values reset or folded over. This, unfortunately, is the limitations of floating point, and has caused many mishaps to occur over the years, from spacecraft missing a planet, or plunging into a planet, to aircraft falling out of the sky when their calculations accumulated the errors and came back with an incorrect answer!

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Demonstrate a large floating point value being displayed on an LCD and being transmitted to a serial terminal
' The value held in the 32-bit floating point variable is quite large, so will not give accurate fractional values
'
' For larger floating point values, use the 64-bit Double variables within the Positron16 compiler on PIC24 and dsPIC33 devices
'
' Written for the Positron8 compiler by Les Johnson
'
    Device = 16F877                             ' Tell the compiler what device is being compiled for
    Declare Xtal = 4                            ' Tell the compiler what speed the device will be operating at
    Declare Float_Display_Type = Fast           ' Use the faster, more accurate, floating point display library routine
'
' Setup the alphanumeric LCD
'
    Declare LCD_DTPin = PORTD.4
    Declare LCD_RSPin = PORTE.0
    Declare LCD_ENPin = PORTE.1
    Declare LCD_Interface = 4
    Declare LCD_Lines = 2
    Declare LCD_Type = 0
    Declare LCD_CommandUs = 2000
    Declare LCD_DataUs = 50   
'
' Setup HRSout
'
    Declare Hserial_Baud = 9600                  ' Set the Baud rate to 9600 for HRSout
'
' Create a variable for the demo
'   
    Dim MyFloat As Float                       
   
'---------------------------------------------------
' The main program starts here
'
Main:
    MyFloat = 2251800                           ' Load MyFloat with a large value
   
    Cls                                         ' Clear the LCD before the loop
    Do                                          ' Create a loop
        Print At 1, 1, Dec1 MyFloat             ' Print the floating point value on the LCD, with 1 fraction digit
        HRSOutLn Dec1 MyFloat                   ' Transmit the ASCII floating point value to a serial terminal, with 1 fraction digit
        MyFloat = MyFloat + 0.5                 ' Increment MyFloat
        DelayMS 200                             ' A small delay so things do not happen too fast
    Loop                                        ' Do it forever

Below is a screenshot of the above program operating within a simulator. The simulator will give an accurate representation of the actual program's operation because it is not using any underlying, or complex, peripherals of the microcontroller.

Screenshot.jpg

basiclover

thanks a lot Les for that explanation