News:

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

Main Menu

Labels as Pointers and catching overflow

Started by TimB, Mar 31, 2022, 07:06 PM

Previous topic - Next topic

TimB

Hi,

I have some code where I'm using Cdata to feed a simulation for another circuit

It should be pretty easy, I use a pointer var to say where the next Cdata is. But I want to catch a roll past my data so I used a label as the stop. I then check my pointer against the label and if it >= then reset pointer to the start

The issue is Proton has flagged the line up. It actually says to contact Les and provides an email address.

Any get out of jail work arounds?

Proc BubbleHandler()

    If xBubbleInProgress = cFalce then
        Dec wBubbleToTmr
        If wBubbleToTmr = 0 then
            xBubbleInProgress = ctrue
        Endif
    Else
        Dec wBubbleLengthTmr
        BubbleIsActive
        If wBubbleLengthTmr = 0 then
            wBubbleToTmr = Cread wBubbleSimPointer
            wBubbleSimPointer = wBubbleSimPointer + 2
            wBubbleLengthTmr = Cread wBubbleSimPointer
            wBubbleSimPointer = wBubbleSimPointer + 2
            If wBubbleSimPointer >= BubbleDataEnd then   ;<<<<<<<<<<<<< Error line
                wBubbleSimPointer = BubbleDataStart
            Endif
            xBubbleInProgress = cFalce
            BubbleIsNotActive
        Endif

    Endif


EndProc


BubbleDataStart:
    Cdata as word   4567,237,_
                    7845,1246,_
                    5987,121


BubbleDataEnd:


TimB

OK found the workaround and corrected the typos on cFalce to cFalse

I declared a word and loaded that with the end of data info

top204

#2
Those warnings are when something inside the compiler has underflowed. i.e. An internal Stack variable.

I've never seen it actually happen, but I know it can because the compiler has such a complex internal stack arrangement, so if the stack value goes below zero, with too many virtual Pops and not enough Pushes, it could underflow to a stack below 0, which will give a warning to contact me and I will look at the code and see what is causing the issue, or if the compiler is not doing something with something I did not think could happen when I wrote the parser.

The real world is very different to the world when code is actually being written and tested. :-)

If using a set of values that have a minimum and maximum value in them, it is sometimes better to use $FFFF as the end of a 16-bit table, or $FF for an 8-bit table etc... You would also be better using the Dim As Flash16 mechanism, because then you can use the SizeOf and Bound functions to see how many data items are in the table for a loop to read them.

TimB



Here is the whole new code


'**************************************************************************************************
'* Name      :  C:\Users\timbo\PDS\User\\Untitled.bas                                              *
'* Author    :  Tim Box                                                                            *
'* Notes     :                                                                                     *
'***************************************************************************************************


Device = 16F628

Xtal = 4

$define set_timer1 1  'set to 1 to enable timer 1

Config FOSC_INTOSCIO, WDTE_OFF, PWRTE_ON, MCLRE_OFF, BOREN_ON, LVP_OFF, CPD_OFF, CP_OFF

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

    All_Digital True




    Dim tic As Word

    Symbol led = PORTB.0
    Symbol GIE = INTCON.7



    Symbol PEIE = INTCON.6
    Symbol TMR1IE = PIE1.0
    Symbol TMR1IF = PIR1.0


    DIm pBottomProbe as Portb.0                        ; Ports used to say what is happening inside
    Dim pTopProbe as Portb.1
    Dim pOverflowing as Portb.2
    DIm pVesselEmpty as PortB.3

    Dim pBubbleSim as PORTB.4
                                                       ; Tie these ports to the controling pic pins
    DIm pInletValve as PortA.0
    DIm pDrainValve as PortA.1

    Dim cOpen as 1
    DIm cClosed as 0

    Dim cFalse as 0
    Dim cTrue as 1


    Dim x100msFlag as bit

    DIm cOverfill as 50                                ; Count above top probe before overflowing these are fixed and not related to flow
    Dim cVesselLowerProbe as 50                        ; Value below which we have emptied the vessel
    Dim cVesselMin as 20                               ; Value below which vessel is effectivly drained

;   Fill time conversion to ms (counts below)
;   1 Min = 6000ms
;   1 second = 100
; Eg 4:32.34 mins/seconds is (4 x 6000 =24000 )+(32 x 100= 3200)+34 = 27234

    Dim c100mlFillTime as 27234  + cVesselLowerProbe   ; The time it will take to fill 100ml from hitting bottom probe to top probe this is a calculation to represent the
                                                       ; time taken to fill the vessel using the flow rate of condence based on the pressures around the oriffice

    Dim cVesselMax as c100mlFillTime + cOverfill       ; Value that indicates we are overflowing

    Dim cVesselDrainSpeedStep as 31                   ; Guestimated time to empty a full vessel eg 8.6 seconds

    Dim wVolumeLevel as word                           ; Main timer counter

    Dim xFilldirection as bit                          ; Indicates if we are filling or empting

    Dim wBubbleSimPointer as word                      ; Points to the current bubble Cdata
    Dim wBubbleDataEnd as word
    Dim wBubbleTimeTo as word                          ; Time to the next bubble
    Dim wBubbleLength as word                          ; Length of the bubble

    Dim wBubbleToTmr as Word
    DIm wBubbleLengthTmr as word
    Dim xBubbleInProgress as bit


                                                                                         
    Dim cFilling as 1
    Dim cEmptying as 0


    $Define TopProbeActive High pTopProbe
    $Define TopProbeNotActive Low pTopProbe
    $Define BottomProbeActive High pBottomProbe
    $Define BottomProbeNotActive Low pBottomProbe

    $Define Overflowing  High pOverflowing
    $Define NotOverflowing Low pOverflowing

    $Define VesselEmpty High pVesselEmpty
    $Define VesselNotEmpty Low pVesselEmpty

    $Define BubbleIsActive high pBubbleSim
    $Define BubbleIsNotActive Low pBubbleSim

    Goto Start

'------------------------------------------------------------


     On_Interrupt GoTo int_routine




int_routine:     ' interrupt every 1mS

    Context Save

    If TMR1IF = 1 Then
        TMR1H = 216
        TMR1L = 255
        Clear TMR1IF

        Set x100msFlag

    EndIf

    Context Restore


Proc Initialise()


    OPTION_REG = %11000000

    TRISB = %00000000
    TRISA = %00000011

    CMCON = 7  '
    VRCON = 0  '

    T1CON.5 = 0   ;bits 5-4  Prescaler Rate Select bits
    T1CON.4 = 0   ;bit 4
    T1CON.3 = 1   ;bit 3 Timer1 Oscillator Enable Control bit 1 = on
    T1CON.2 = 1   ;bit 2 Timer1 External Clock Input Synchronization Control bit...1 = Do not synchronize external clock input
    T1CON.1 = 0   ;bit 1 Timer1 Clock Source Select bit...0 = Internal clock (FOSC/4)
    T1CON.0 = 1   ;bit 0 enables timer
    TMR1H = 216   ;preset for timer1 MSB register
    TMR1L = 242;  ;preset for timer1 LSB register


    Set PEIE
    Set TMR1IE
    Clear TMR1IF
    Set GIE

    wBubbleSimPointer = BubbleDataStart
    wBubbleToTmr = Cread wBubbleSimPointer
    wBubbleSimPointer = wBubbleSimPointer + 2
    wBubbleLengthTmr = Cread wBubbleSimPointer
    wBubbleSimPointer = wBubbleSimPointer + 2
    xBubbleInProgress = cFalse
    wBubbleDataEnd = BubbleDataEnd

    Endproc


Proc BubbleHandler()

    If xBubbleInProgress =cFalse then
        Dec wBubbleToTmr
        If wBubbleToTmr = 0 then
            xBubbleInProgress = ctrue
        Endif
    Else
        Dec wBubbleLengthTmr
        BubbleIsActive
        If wBubbleLengthTmr = 0 then
            wBubbleToTmr = Cread wBubbleSimPointer
            wBubbleSimPointer = wBubbleSimPointer + 2
            wBubbleLengthTmr = Cread wBubbleSimPointer
            wBubbleSimPointer = wBubbleSimPointer + 2
            If wBubbleSimPointer >= wBubbleDataEnd then
                wBubbleSimPointer = BubbleDataStart
            Endif
            xBubbleInProgress = cFalse
            BubbleIsNotActive
        Endif

    Endif


EndProc

    '-----------------------------------------------------------
    Start:


    Initialise()

    While 1 = 1

        If x100msFlag = Ctrue then
            x100msFlag = Cfalse
            BubbleHandler()

            ; If inlet is open we sim a fill
            If pInletValve = cOpen then
                If wVolumeLevel < cVesselMax then
                    Inc wVolumeLevel
                Endif
            Endif

            ; Drain valve control
            If pDrainValve = cOpen then
                If wVolumeLevel > cVesselDrainSpeedStep then
                    wVolumeLevel = wVolumeLevel - cVesselDrainSpeedStep
                Else
                    wVolumeLevel = 10
                Endif
            Endif


            if wVolumeLevel >= c100mlFillTime then
                TopProbeActive
            Else
                TopProbeNotActive
            Endif

            If wVolumeLevel >= cVesselLowerProbe then
                BottomProbeActive
            Else
                BottomProbeNotActive
            Endif


            If wVolumeLevel >= cVesselMax then
                Overflowing
            Else
                NotOverflowing
            Endif

            If wVolumeLevel <= cVesselMin then
                VesselEmpty
            Else
                VesselNotEmpty
            Endif


        Endif

    Wend



    ; Bubble sim data, First data is the lenght of time in ms before a bubble is simmed,
    ; the next number is the length of the bubble in ms. It works in 2 wrd packets after the data reaches "BubbleDataEnd it wraps round to the start
BubbleDataStart:
    Cdata as word   4567,237,_
                    7845,1246,_
                    5987,121


BubbleDataEnd: