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]
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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.
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.
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.
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.
Kent, Thanks for the tip. I have changed the design so that I no longer need the PWM. Ed.
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.
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.
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.