Menu

Bug in GCB

2011-10-30
2013-05-30
  • Edward LaBudde

    Edward LaBudde - 2011-10-30

    I am getting a strange error message associated with the PWMoff command.  If I try to comment out line 103 or 129 I get this message:
    Error: Program is too large, cannot fit all subroutines into available program memory
    Here is the code:

    'Snow melt V 3.0 08-23-11
    'Tried to remobe PWM for Snow Sensor
    'Copyright E.V. LaBudde 2011
    'Tested all modes 08-09-11 
    'Chip model
    #chip 16F88, 8      'Pic model and clock MHz
    #config INTRC_IO    'Use internal Oscillator
    Osctune = b'111110' 'works from 111000 to 000011
    'Set the pin directions
    dir portA.0 In  'Cold pin 17
    dir portA.1 In  'Hot pin 18
    dir portA.2 In  'Ambient Temp pin 1
    dir portA.3 Out 'Heater pin 2
    dir portA.4 Out 'Pump pin 3
    dir portB.0 In  'New Snow signal pin 6 Tied to pin 8
    dir portB.1 In  'Manual Heat mode pin 7
    dir portB.2 In  'Snow pin 8
    dir PortB.3 Out 'Test port Pin 9
    dir portB.4 In  'Manual Circulate Mode Pin 10
    dir portB.5 Out 'LCD pin 11
    'set defines
    #define SendAHigh Set PORTB.5 Off                   'Note Polarity for 4X20 Newhaven display
    #define SendALow Set PORTB.5  On 
    #define Cold An0
    #define Hot An1
    #define Temp An2
    #define Heater PortA.3
    #define Pump PortA.4
    #define ManualMode PortB.1
    #define Snow PortB.2
    #define Test PortB.3
    #define ManualCirc PortB.4
    #define LCD PortB.5 
    dim AmbientT as integer
    dim WaterinT as integer
    dim WateroutT as integer
    dim AmbientTemp as word
    dim E_timemin as word
    dim DeltaT as word
    dim DisplayAmbT as word
    dim DisplayinT as word
    dim DisplayoutT as word
    dim WaterinTemp as word
    dim WateroutTemp as word
    dim MeltTime_s as word
    dim MeltTime_m as word
    dim MeltTime_L as word
    'Set inital parameters
    InitSer 1, r2400, 1, 8, 1, none, invert                 'LCD interface Positive going Standby bit 2400 baud
    Set LCD = On                                            'Init LCD
    wait 200 ms
    Option_reg.7 = off                                      'Enable WPU
    MeltTime_s = 0                                          'Zero Melt times
    MeltTime_m = 0
    MeltTime_L = 0
    E_timesec = 0                                           'Zero Elapsed times
    E_timemin = 0
    E_timehrs = 0
    Tons = 0
    On Interrupt ExtInt0 Call SnowCheck
        
    Standby:
        Set Pump = Off                                      'Turn system Off
        Set Heater = On                                     'Keep heater on to defrost
        E_timesec = 0                                       'Zero Elapsed times
        E_timemin = 0
        Ambient = ReadAD(Temp)                              'Read Ambient air sensor
        ReadTable Tconvert, Ambient, AmbientTemp            'Look up temeperature value
        AmbientT = AmbientTemp - 80                         'Correct for lack of negiative numbers in table
        call ReadWater                                      'Check Water Temp
        call StandbyDisplay                                 'Refresh display    
        Count = 0                                           'Zero Write counter for EEprom writer
        If ManualMode = Off and ManualCirc = On then Goto Manual    'Goto manual mode
        If ManualCirc = Off and ManualMode = On then Goto Circ      'Goto circulate mode
        If ManualMode = On and ManualCirc = On then nop     'Prevent going to neverland
        If ManualMode = Off and ManualCirc = Off then nop   'Prevent going to neverland
        If AmbientT > -25 then Goto Standby                 'Bypass fluid measurement
        Set Heater = Off
        Set Pump = On                                       'Circulate water to measure WaterinT
        wait 30 s
        Set Pump = Off
        Set Heater = On     
        call ReadWater      `                               'Read water temperature
        If AmbientT < -25 and WaterinT < -15 then Goto Warm 'Keep unit off for as long as possible
        Wait 1 h                                            'Do hourly
    Goto Standby
    'Subs
    Manual:                                                 'Turn on system Checked 10-19-11
        Call TurnOns
        Set Pump = On
        Set Heater = On
        PWMOff                                              'Turn on heater on snow sensor
        If Snow = On then MeltTime_s += 1                   'record melt time
        MeltTime_m = MeltTime_s/60
        EPWrite 255, MeltTime_m                             'Record melt time
        call Elapsed_time                                   'Measure on time
        call ReadWater                                      'Read water temperature
        call ManualDisplay                                  'Refresh display
        call Write                                          'Measure DeltaT in 10 min intervals and write to EEprom
        If ManualMode = On then Goto Standby                
        Wait 673 ms                                 
    Goto Manual
    Circ:                                                   'Checked 10-19-11
        Set Pump = On
        Set Heater = Off
        call Elapsed_time                                   'Measure on time
        call ReadWater                                      'Read water temperature
        call CircDisplay                                    'Refresh display
        If ManualCirc = On then Goto Standby                
        Wait 713 ms                                 
    Goto Circ
    Heat:                                                   'Checked 10-19-11
        Call TurnOns
        Set Pump = On                                       'Turn on system
        Set Heater = On
        PWMOff                                              'Turn on heater on snow sensor
        If Snow = On then MeltTime_s += 1                   'record melt time
        MeltTime_m = MeltTime_s/60
        EPWrite 255, MeltTime_m                             'Record melt time
        call Elapsed_time                                   'Measure on time
        call ReadWater                                      'Read water temperature
        call HeatDisplay                                    'Refresh display
        call Write                                          'Measure DeltaT in 10 min intervals and write to EEprom     
        If Snow = Off then                                  'Clear snow and wait 30 min.
            Wait 30 m
            goto Standby
        End If
        Wait 685 ms
    Goto Heat
    Warm:                                                   'Checked 10-19-11
        PulseOut Test, 1 ms
        Set Pump = On                                       'Turn on system
        Set Heater = On
        call ReadWater                                      'Read water temperature
        call WarmDisplay                                    'Refresh display
        if WaterinT > 100 then goto Standby                 'Warm up water then turn off
        Wait 703 ms
    Goto Warm
    Sub SnowCheck
        wait 1500 ms
        If Snow = On then goto heat                     'Test for sensor fail
        If Snow = Off Then call FailDisplay
    Return
    Sub ManualDisplay
        call Clear
        serprint 1, "Mode:"
        serprint 1, "Man"
        serprint 1, " T"
        MeltTime_m = MeltTime_s/60
        Serprint 1, MeltTime_m
        Serprint 1, "m"
        call CommonDisplay
    Return
    Sub CircDisplay
        call Clear
        serprint 1, "Mode:"
        serprint 1, "Circ"
        call CommonDisplay
    Return
    Sub StandbyDisplay
        call Clear
        serprint 1, "Mode:"
        serprint 1, "Sby"
        EPRead 255, MeltTime_L
        Serprint 1, " MTime:"                                   'Read melt time
        Serprint 1, MeltTime_L
        call CommonDisplay
        Wait 1 s
    Return
    Sub WarmDisplay
        call Clear
        call First
        serprint 1, "Mode:"
        serprint 1, "Warm"
        call CommonDisplay
    Return
    Sub HeatDisplay
        call Clear
        call First
        serprint 1, "Mode:"
        serprint 1, "Heat"
        call CommonDisplay
    Return
    FailDisplay:
        call Clear
        call First
        serprint 1, "Mode:"
        serprint 1, "SENSOR FAILURE"
        call CommonDisplay
    Goto FailDisplay
    Sub CommonDisplay
        call second
        call Elapsed_time                                   'Measure on time
        serprint 1, "Ambient:"
        If AmbientT_H.7 = On then
        DisplayAmbT =  65536 - AmbientT
        Else
            DisplayAmbT = AmbientT
        End If
        If AmbientT_H.7 = On then
            serprint 1, "-"
            serprint 1, DisplayAmbT
        Else
            serprint 1, DisplayAmbT
        End If
        serprint 1, " ET:"
        serprint 1, E_timemin
        serprint 1, "m" 
        call Third
        If Waterin < 52 then
            DisplayinT =  65536 - WaterinT
        Else
            DisplayinT = WaterinT
        End If
        serprint 1, "WIn:"
        If WaterIn  < 52  then
            serprint 1, "-"
            serprint 1, DisplayinT
        Else
            serprint 1, DisplayinT
        End If
        call Fourth
        serprint 1, "WOut:"
        If Waterout < 52 then
            DisplayoutT =  65536 - WateroutT
        Else
            DisplayoutT = WateroutT
        End If
        If Waterout < 52 then
            serprint 1, "-"
            serprint 1, DisplayoutT
        Else
            serprint 1, DisplayoutT
        End If
        EPRead 254, Tons
        serprint 1, " Tons:"
        serprint 1, Tons
        'wait 1 s
    Return
    Sub ReadWater
        Waterin =  ReadAD (cold)
        ReadTable Tconvert, Waterin, WaterinTemp
        WaterinT = WaterinTemp - 80
        Waterout = ReadAD (hot)
        ReadTable Tconvert, Waterout, WateroutTemp
        WateroutT = WateroutTemp - 80
    Return
      
    Sub Elapsed_time
        E_timesec += 1                  'Seconds
        If E_timesec = 60 then
            E_timesec = 0
            E_timemin += 1              'Minutes
        end if
    Return
    Sub Write
        DeltaT = WateroutT - WaterinT
        EPWrite 0, DeltaT                   'Store first Delta T measurement
        If E_timemin % 10 = 0 then          'Measure DeltaT in 10 min intervals and write to EEprom     
            Count += 1
            EPWrite Count, DeltaT
        End If
    Return
    Sub TurnOns
        TurnOn +=1
        EPWrite 254, TurnOn
    Return
    Sub TestDisplay
    Call Clear
        serprint 1, "First line"
        Call second 
        Serprint 1, "Second line"
        Call Third
        Serprint 1, "Third line"
        Call fourth
        Serprint 1, "Fourth line"
        wait 1 s
    Return
    'NewHaven Display utilities
    Sub Clear
        sersend 1, 254  'start CMD
        sersend 1, 81   'clear screen
    Return
    Sub First
        sersend 1, 254  'start CMD
        sersend 1, 69   'First line
        sersend 1, 0
    Return
    Sub Second
        sersend 1, 254  'start CMD
        sersend 1, 69   'second line
        sersend 1, 64
    Return
    Sub Third
        sersend 1, 254  'start CMD
        sersend 1, 69   'Third line
        sersend 1, 20
    Return
    Sub Fourth
        sersend 1, 254  'start CMD
        sersend 1, 69   'Fourth line
        sersend 1, 84
    Return
    Sub Baud
        '1=300, 2=1200, 3=2400, 4=9600, 5=14.4k. 6=19.2k, 7=57.6k, 8=115.2k
        sersend 1, 254  'start CMD
        sersend 1, 97   'baud select
        sersend 1, 4    '9600-
        wait 100 us
    Return
    /code]
    
     
  • Edward LaBudde

    Edward LaBudde - 2011-10-30

    Hugh, this is the second time I have post about this problem.  The first time it was necessary to comment out the HPWM command to make the error go away.  This time tying to comment out the PWMOff comment brings the error.  There is definitely something going on with the HPWM code!

    BTW, I really love GCB!  It is a very useful and powerful tool .  This project is a controller for the hot water system I had put under the driveway this summer.  I hope I can get it finished before the snow flies.    When you get around to it it would be great to have a serprint command for Integer variables.  Thanks, Ed.

     
  • Mauried

    Mauried - 2011-10-30

    Have a look at the LST file and see if GCB is leaving a large gap at the page boundary ie 07FF-0800.
    Ive had this problem before where the code needs more than 1 page and it gets worse with chips with multiple pages like 16F88 and worse again with 16F886 / 887 .
    The problem seems to be that GCB calculates the program size incorrectly and concludes that all the code wont fit.
    Try adding some NOP instructions in the vicinity of the code thats causing the problem, ie near the HPWM commands and then see if the error dissapears.
    You may need to add a lot , sometimes Ive needed 64 or more.
    Add them in lots of 8.

     
  • Edward LaBudde

    Edward LaBudde - 2011-10-30

    Mauried, I think you are correct!  I added some new features to the code and increased the code size from 2830 bytes to 3396 and the problem went away!  There is definitely a bug in there somewhere.  Ed.

     
  • kent_twt4

    kent_twt4 - 2011-10-30

    Ed,  If your heater control ends up needing extra PWM resolution, the 18f1330 can give you up to 14 bits to play with.  Drop in replacement for the 16f88, 3 hardware PWM's, and no paging issues that I'm aware of.  I could post some PWM manual setup code if you go down that road, it's a totally different beast.

     
  • Edward LaBudde

    Edward LaBudde - 2011-10-30

    Kent, Thanks for the tip.  I have changed the design so that I no longer need the PWM.  Ed.

     
  • Edward LaBudde

    Edward LaBudde - 2011-11-01

    Kent, I think I will take you up on your offer,  There is an article in Circuit Cellar this month on a high accuracy voltage reference using an LT 1236 reference regulator.  A 14 bit PWM would be great.  Please post your code.  Thanks, Ed.

     
  • Nobody/Anonymous

    Ed, no problem.  Here is the hardware PWM code that exercises a Futaba servo motor.  The Fpwm  and PTPER will be different for a standard PWM.  Hope the comments will make sense when comparing to the datasheet.  Let me know if something is amiss, it's been awhile since I did this.

    ;Servo code using the hardware Power PWM module of the PIC18f1330
    #chip 18f1330, 4
    #config osc=INTIO2,HPOL=HIGH,LPOL=HIGH 'set PWM polarity bit for active high
    #define Servo PortB.1   ;Futaba s3003 servo 
    #define forward 570     ;500?
    #define neutral 330     ;375?
    #define reverse 90      ;250?
    dim PDC0 as word alias PDC0H, PDC0L
    dim PTPER as word alias PTPERH, PTPERL
    dim forward as word
    dim neutral as word
    dim reverse as word
    init_PowerPWM
    #define WaitLed wait 1 s    '5 10ms
    Main:
    PDC0 = forward
    wait 3 s
    PDC0 = neutral
    wait 3 s
    PDC0 = reverse
    wait 3 s
    goto Main
    sub init_PowerPWM
        SET PTEN OFF    ;Turn off the timer base
        ;set PTCON0 bits
        SET PTOPS3 OFF  ;Time base output postscale bits
        SET PTOPS2 OFF
        SET PTOPS1 OFF
        SET PTOPS0 OFF
        SET PTCKPS1 ON  ;Time base input prescale bits
        SET PTCKPS0 OFF  ;PRESCALE bits: 11= 1/64, 10=1/16 , 01=1/4, 00=1/1 
        SET PTMOD1 OFF  ;Time base mode select bits
        SET PTMOD0 OFF  ; 00=free running, 01=single shot, 10=up/dn, 11=up/dn double update
        ;set PTCON1 bits
        SET PTDIR ON ;PWM TIME BASE count direction: 0=counts up, 1=counts down
        ;PWMCON0 PWM control register
        SET PWMEN2 OFF  ;PWM module enable bits
        SET PWMEN1 OFF  ;001 is PWM1, 110 is PWM1 &pwm3
        SET PWMEN0 ON
        SET PMOD2 OFF   ;PWM output pair mode pins
        SET PMOD1 OFF   ;0= independent mode
        SET PMOD0 OFF   ;1 = complementary mode 
        'PWMCON1 PWM control register, no deadtime or special interrupts set
        ;*************************************************************************************
        ;* PTPER = (Fcy/(Fpwm*PTMRPrescaler))-1
        ;* Fcy = Fosc/4
        ;* for 20ms or 18ms servo update
        ;* Fpwm = 1/.020 or 1/.018 = 50 or 55.55Hz
        ;* PTPER = (1000000/(50*16))-1 = 1249 (12 bit no. max (i.e. 0xFFF for 18f))
        ;*************************************************************************************
        ;could up the INTOSC to 8Mhz and PTPER=2499?
        PTPER = 1249
        ;*************************************************************************************
        ;* Servo duty cycle is 1-2ms over the 20ms period or,
        ;* 1/20*4*PTPER 'full reverse', 1.5/20*4*PTPER 'neutral', 2/20ms*4*PTPER 'full forward'
        ;* to get the correct duty cycle must multiply by 4 because of Q1:Q0 in PTMR register
        ;* PDCx (PDCxH and PDCxL) will be forward = 500, neutral = 375, reverse = 250 
        ;*************************************************************************************
        PDC0 = 0
        ;PDC1 = 0
        ;PDC2 = 0
        SET PTEN ON     ;Start up the timer base
    end sub
    
     
  • Mauried

    Mauried - 2011-11-02

    If you need a better voltage referance then a Microchip MCP1541 is the answer.
    Its a high precision 4.096 V referance intended for 10 bit A/D apps.
    The 4.096 V allows easy math to display voltages as 1 bit = exactly 4 mv.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.