I think that you are correct in your assessment of the PWM capabilities of the PLC. The lowest PWM frequency for the current PLCs is 50Hz. To get a 1% resolution on PWM you'd need a frequency closer to 0.5Hz. The PLC's PWM hardware/firmware doesn't go slow enough!
You need a slow PWM system for your SSR. I have sample code from an older project that does slow motion PWM. I used COUNTERS to get a PWM output with 1% resolution. At 1% the output will be one for 20mS. out of every 2S At 99% the output will be on for 1.98S out of every 2S.
I think that PID is an excellent approach for computing the next value for your hot plate.
The following is what I have done to get slow PWM
There are 2 custom functions:
[*]SetPWM - Function to adjust PWM duty cycle
'SetPWM - Custom function to determine PWM duty cycle
'
Call ComputePWM ' Compute next PWM value in A. A must be in the range of
' 0..SV of the TotalPeriod COUNTER
'
' This function is a dummy, the value in A changed via the
' on-line debug interface for the purpose to test/debug.
' The SV (Set Value) of the COUNTER, OnPeriod, determines the overall duty cycle of the PWM output.
' The range for the SV is bewteen 1 and the SV of the TotalPeriod COUNTER.
'
' If the SV of the OnPeriod COUNTER is set to 1, this is the minimum duty cycle.
' If the SV of the OnPeriod COUNTER is >= the SV of the TotalPeriod Counter, then the PWM output
' is always on. 100% duty cycle.
' If the SV of the OnPeriod COUNTER is set to 0, then the contact associated with this COUNTER
' is undefined, but treated by the ladder logic as being "FALSE". Setting the SV to the
' OnPeriod COUNTER does not get a 0% PWM output, but rather a 100% PWM output. The "fix" to
' this problem is to clear the EnablePWM RELAY when a 0% output is desired.
' EnablePWM is cleared to disable the PWM output when a 0% duty cycle is required.
'
IF (A = 0)
ClrIO EnablePWM ' 0% PWM is special, so disable the hardware
ELSE
SetCtrSV OnPeriod, A ' Non-zero PWM, so let the hardware run...
SetIO EnablePWM
ENDIF
[*]ComputePWD - Function to compute next PWM duty cycle value
This function, is currently a placeholder (dummy).
' ComputePWD Function to compute new PWM value, Value is returned in A
'
' This is a dummy function and is to be replaced by working code
'
RETURN
[/list]
Gary D