News:

Let's find out together what makes a PIC Tick!

Main Menu

Compare float values

Started by marekf, Apr 21, 2022, 08:15 PM

Previous topic - Next topic

marekf

Can I compare two float values in the "If" statement? It used to work in older Proton, now I seem to be having issues. Can someone help me to understand why the statement: If floatvalue1 < floatvalue2 Then GoSub LowValueAlarm does not work?

RGV250

I am not sure but if not you could try subtracting one from the other and then check to see if the remainder is positive or negative or possibly equal.

Regards,
Bob

marekf

wouldn't the remainder be still a float value to be compared with zero?

tumbleweed

You should be able to do what you've outlined.

Perhaps post a simple example showing what "doesn't work", along with the two floating point values you're comparing.
 

marekf

I have a subroutine as below

lva:
If lvpick < 0.1 Or DI_I_LIMIT==1 Then
    'if lv pickup is set to 0 or current limit is on then cancel lv alarm
    c_lo_vlt_dly=0
    a_lo_vlt=0
    Return
EndIf

If vsense <= lvpick  And a_lo_vlt==0 Then c_lo_vlt_dly = c_lo_vlt_dly +1

If c_lo_vlt_dly >= lvdelay Then
    a_lo_vlt=1
EndIf

If lvdrop < 0.1 Then lvdrop = lvpick + 1.0

If vsense > lvdrop And a_lo_vlt==1 Then     'reset alarm
    c_lo_vlt_dly=0
    a_lo_vlt=0
EndIf

Return

The alarm a_lo_vlt (As Bit) is never set even though vsense is below lvpick (both vsense and lvpick are float values), and the DI_I_LIMIT is 0. The lvdelay is as Byte type set to 5. It would be nice if a step trace was possible to debug where the problem is.

I have similar problem with high voltage alarm (almost the same subroutine with reversed logic). 
What am I doing wrong?

Yasin

lva:
If lvpick < 0.1 Or DI_I_LIMIT==1 Then
    'if lv pickup is set to 0 or current limit is on then cancel lv alarm
    c_lo_vlt_dly=0
    a_lo_vlt=0
    Return
EndIf

Hello. There is a logic error where there is "return". If the if condition is not met, gosub will not return. Also "==" for positron is the same as "=". Try using "=".
Best regards.

Yasin

I am sorry. What I said with "return" is incorrect. I thought the other "If...then" parts were separate routines.

trastikata

@marekf

Comparing FP variables in Positron works, used it many times.

The logic in your code seems correct.

However it might be a problem with how you compute the FP values. Also make sure these variables are not changed/affected in other parts of the code before you call this sub.

RGV250

Quotewouldn't the remainder be still a float value to be compared with zero?
Oops, you're right.

QuoteIt would be nice if a step trace was possible to debug where the problem is.
I keep hoping DaveS will update his brilliant Picd to work with the new compiler.
Anyway, what I would do is have a serial out with a number and then the variables at that point.

Bob

trastikata

Quote from: RGV250 on Apr 22, 2022, 07:41 PMAnyway, what I would do is have a serial out with a number and then the variables at that point.

I'd simply put the correct fixed values for those variables that should raise the alarm at the beginning of the Sub, for example something like this:

lva:
vsense = 0.9
lvpick = 1.1
lvdrop = 0.8
....

And observe the behavior of the sub. If it works, then you have to look elsewhere, as I mentioned earlier, maybe the way those values are calculated in other subs causes the trouble.

Yasin


John Drew

Quote from: John Drew on Apr 23, 2022, 06:54 AMThis works fine in Proteus using a 16F1827. W10 and latest version of the compiler

INITIALISE:
        Cls
        fTest2 = 1465.5
        fTest1 = 2033.567
MAIN:
       If fTest1 > fTest2 Then
          Print At 1,1, "ftest1 bigger"
       Else
          Print At 2,1, "ftest2 is larger"
       EndIf

top204

#12
A code snippet showing a possible anomaly is very important, so I can examine the assembler code produced.

Each device family has different assembler code requirements and different setups etc, so the device showing a possible issue is vitally important to know, as are the locations of the variables in question. Especially with 14-bit core devices that have fragmented RAM. The compiler manages all RAM within a microcontroller, so this should not be an issue, but it is always better to check and see. :-)

marekf

#13
I use PIC18F6722

Assembly snippet:
lva
F1_003252 equ $ ; in [TEST.BAS] if lvpick < 0.1 Or DI_I_LIMIT=1 Then
    movff lvpick,PP_AARG
    movff lvpickH,PP_AARGH
    movff lvpickHH,PP_AARGHH
    movff lvpickHHH,PP_AARGHHH
    movlw 205
    movwf PP_BARGHHH,0
    movlw 204
    movwf PP_BARGHH,0
    movlw 76
    movwf PP_BARGH,0
    movlw 123
    movwf PP_BARG,0
    call __fplessthan_32__
    movwf SP__P9_,0
    movlw 0
    btfsc PORTF,5,0
    movlw 1
    iorwf SP__P9_,F,0
    bz _lbl__1020
F1_003254 equ $ ; in [TEST.BAS] c_lo_vlt_dly=0
    clrf c_lo_vlt_dly,1
F1_003255 equ $ ; in [TEST.BAS] a_lo_vlt=0
    bcf _B__VR1,6,0
F1_003256 equ $ ; in [TEST.BAS] return
    return 0
F1_003257 equ $ ; in [TEST.BAS] endif
_lbl__1020
F1_003260 equ $ ; in [TEST.BAS] if vsense <= lvpick  And a_lo_vlt=0 Then c_lo_vlt_dly = c_lo_vlt_dly +1
    movff vsense,PP_AARG
    movff vsenseH,PP_AARGH
    movff vsenseHH,PP_AARGHH
    movff vsenseHHH,PP_AARGHHH
    movff lvpick,PP_BARG
    movff lvpickH,PP_BARGH
    movff lvpickHH,PP_BARGHH
    movff lvpickHHH,PP_BARGHHH
    call __fpgreaterequal_32__
    movwf SP__P9_,0
    movlw 1
    btfsc _B__VR1,6,0
    movlw 0
    andwf SP__P9_,F,0
    bz _lbl__1022
    incf c_lo_vlt_dly,F,1
_lbl__1022
F1_003262 equ $ ; in [TEST.BAS] if c_lo_vlt_dly >= lvdelay Then
    movf lvdelay,W,1
    subwf c_lo_vlt_dly,W,1
    bnc _lbl__1024
F1_003263 equ $ ; in [TEST.BAS] a_lo_vlt=1
    bsf _B__VR1,6,0
F1_003268 equ $ ; in [TEST.BAS] endif
_lbl__1024
F1_003270 equ $ ; in [TEST.BAS] if lvdrop < 0.1 Then lvdrop = lvpick + 1.0
    movff lvdrop,PP_AARG
    movff lvdropH,PP_AARGH
    movff lvdropHH,PP_AARGHH
    movff lvdropHHH,PP_AARGHHH
    movlw 205
    movwf PP_BARGHHH,0
    movlw 204
    movwf PP_BARGHH,0
    movlw 76
    movwf PP_BARGH,0
    movlw 123
    movwf PP_BARG,0
    call __fpgreaterequal_32__
    sublw 1
    bz _lbl__1026
    clrf PP_AARGHHH,0
    clrf PP_AARGHH,0
    clrf PP_AARGH,0
    movlw 127
    movwf PP_AARG,0
    movff lvpick,PP_BARG
    movff lvpickH,PP_BARGH
    movff lvpickHH,PP_BARGHH
    movff lvpickHHH,PP_BARGHHH
    call __fpadd_32__
    movff PP_AARG,lvdrop
    movff PP_AARGH,lvdropH
    movff PP_AARGHH,lvdropHH
    movff PP_AARGHHH,lvdropHHH
_lbl__1026
F1_003272 equ $ ; in [TEST.BAS] if vsense > lvdrop And a_lo_vlt=1 Then
    movff vsense,PP_AARG
    movff vsenseH,PP_AARGH
    movff vsenseHH,PP_AARGHH
    movff vsenseHHH,PP_AARGHHH
    movff lvdrop,PP_BARG
    movff lvdropH,PP_BARGH
    movff lvdropHH,PP_BARGHH
    movff lvdropHHH,PP_BARGHHH
    call __fpgreaterthan_32__
    movwf SP__P9_,0
    movlw 0
    btfsc _B__VR1,6,0
    movlw 1
    andwf SP__P9_,F,0
    bz _lbl__1028
F1_003273 equ $ ; in [TEST.BAS] c_lo_vlt_dly=0
    clrf c_lo_vlt_dly,1
F1_003274 equ $ ; in [TEST.BAS] a_lo_vlt=0
    bcf _B__VR1,6,0
F1_003277 equ $ ; in [TEST.BAS] endif
_lbl__1028
F1_003279 equ $ ; in [TEST.BAS] return
    return 0

top204

#14
A small section of assembler code for a piece of code is not what is required.

I need to see a snippet of BASIC code that will compile and show the possible anomaly.

I've tried many iterations of floating point comparisons and they all give the correct response on a serial terminal. For example:

    Device = 18F25K20
    Declare Xtal = 16
'
' Setup USART1
'   
    Declare Hserial_Baud = 9600
    Declare HRSOut1_Pin = PORTC.6

    Dim Floatin1 As Float
    Dim Floatin2 As Float
    Dim Floatin3 As Float
   
'--------------------------------------------------------------------
Main:
    Floatin1 = 0.2
    Floatin2 = -0.25
    Floatin3 = -0.3
   
    If Floatin1 < Floatin2 And Floatin1 < Floatin3 Then
        HRSOutLn "Correct"
    Else
        HRSOutLn "Wrong"
    EndIf

But there are countless thousands of comparison iterations, so I cannot test them all, and they all create the same assembler codes for each comparison type, so I need something that I can see and test.

marekf

Unfortunately, I inherited this project from a retired engineer, and it counts over 7000 lines of code.
What puzzles me that the lva subroutine is working as soon as I move calls to a few other subroutines around, which are unrelated to variables used in this one.
It looks like this was some addressing problem.
Is it possible that the bootloader has some bugs that is causing me issues?