Open prussiap opened 10 years ago
Greetings!
1) While I haven't attempted an autotuning method for Temper (I have done manual tunings for the three systems I have used temper and it's sibling, mruby-pid, on), I imagine an automated Z-N open loop tuning algorithm could be applied with Temper without too much effort. Any attempts/patches are welcome.
2) That is a perfectly reasonable way to handle manual tuning and the translation into the kP, kI, and kD.
3) I really should update the example with SSR output, as that's what I have been using for brewing (40A SSRs controlling 240VAC heating elements). While the window of cooling/heating may not be fast, you still want to keep a reasonably narrow window of on/off cycles. I use a 5000ms window, and translate the output value into milliseconds on/off. Here's an example:
class HeatingElement
attr_accessor :pulse_width, :pulse_range, :name, :adapter
def initialize adapter, options = {}
@pulse_range = options[:pulse_range] || 5000
@on = false
@pulse_range_end = (Time.now.to_i * 1000) + @pulse_range
@adapter = adapter
@pulse_width = 0
@name = options[:name]
end
def pulse
set_pulse_time
update_pulse_range if pulse_exceeds_range?
if pulse_within_width?
on!
else
off!
end
end
def set_pulse_time
@pulse_time = (Time.now.to_i * 1000)
end
def pulse_within_width?
@pulse_time <= pulse_end
end
def pulse_exceeds_range?
@pulse_time > @pulse_range_end
end
def update_pulse_range
@pulse_range_end += @pulse_range
end
def pulse_end
@pulse_range_end - (@pulse_range - @pulse_width)
end
def on!
@adapter.on
end
def off!
@adapter.off
end
def on?
@adapter.on?
end
def off?
!on?
end
end
class TempControl
attr_reader :input, :output, :pid
def initialize options = {}
@pulse_range = options[:pulse_range] || 5000
@input = TempSensor.new
@output = HeatingElement.new adapter: GPIO.new(pin: 17)
configure_automatic_control options
end
def configure_automatic_control options
@target = options[:target]
@pid = Temper::PID.new maximum: @pulse_range
@pid.tune 44, 165, 4
@pid.setpoint = @target
end
def read_input
reading = input.read
@last_reading = reading if reading
end
def calculate_power_level
if read_input
set_pulse_width pid.control @last_reading
end
end
def set_pulse_width width
if width
output.pulse_width = width
end
end
def control_cycle
calculate_power_level
output.pulse
end
end
# creates temperature control with a 152.0F target
control = TempControl.new target: 152.0
loop do
control.control_cycle
end
What the above does is creates a TempControl object that interfaces with the temp sensor, feeds the input into the PID object, and feeds the PID output to the HeatingElement. The HeatingElement takes the PID output and converts it into the timeframe in milliseconds of being on, relative to the current time. When it exceeds the pulse width, it shuts off. When it exceeds the pulse range (the five second window), it resets the range timestamps. This allows multiple sampling within the 5 second window but does not change the pulse width in the middle of a window.
I just extracted this from one of my applications, so if it's a bit rough or you need clarification, feel free to ask.
Hi, Thank you for the feedback. I've been working through the code and haven't had much free time. So there seem to be a few important tricks (other then the math)
In other news though how did you do your manual tuning ? Do you have any sample code of what you did ? Just curious if we should start there before doing an autotune. I have some time this weekend so my plan was to experiment.
hola, So i'm re-visiting this after a little time off. I've actually been using my sous-vide for the last 7months now and am wanting to improve on several factors. One of them is the tuning. Your tuning method just looks at the difference between the last time point and this one correct?
I'm noticing because my heating element is so efficient and rapid (rice cooker with no insulation) that It is almost impossible to find a low stepping point and then to step up one notch and not plateau. This has caused the tuning for the rice cooker to jump over the desired temp by a few degrees and to not predict it properly.
Have you explored the tuning of your PID? If so what experiments and what code have you been using for it. It might be of interest to collaborate on some of this. Also you mentioned your SSR changes which I used when I first started but was wondering if you had any new changed or modifications that have worked for you.
I'm going to slowly refactor what I have now and I would like to provide a PR with any new changes that might be useful to you
Thanks and I hope this msg finds you well.
Hi, I'm in the process of building a sous-vide Pi system and I was hoping to use your PID library to avoid re-inventing the wheel. I have a few questions though:
In any case your project is much appreciated. I look forward to being able to contribute.