PymateIO-PID-controler

From pymate.io wiki
Jump to navigation Jump to search


About PID

A PID controller is a feedback-based control loop used to manage machines and processes that require continuous control and automatic adjustment!

PID regulator can be used to regulates temperature, pressure, speed, illumination, position, ...

The aim of a PID is to continuously reduce the amount of error between the measured value and the setpoint.

PymateIO-PID-controler.png

Let's examine the practical case of an oven set to 200°C

In theoretical world:

  • you set the value (eg: 200°C) and
  • the device immediately reach the target temperature (eg: the oven is at 200°C).

In real world:

  • you must starts heating the resistor followed by the air in the oven then the internal walls before getting the temperature stabilized at 200°C. This is named Thermal Inertia.
  • So you give a lot of power to the heating resistor to make the temperature raising fast toward 200°C
  • You stop early power delivery soon enough to not overshoot too much the final temperature (otherwise you may reach 300°C... where the meal will carbonize).
  • Finally, giving some transcient pulse of heating will somewhat keep the oven temperature around 200°C.

Additional ressource about PID regulation:

Pymate software PID

The PymateIO includes the PID class (pid library).

The PID controler do use a Timer to perform its treatments (it is an autonomous process).

As for each PID Controller, the following parameter are required:

  • Kp : Proportional constant
  • Ki : Integral constant
  • Kd : Derivated constant

The software controller requires additional parameters:

  • dt: time (ms) between two consecutive measurement
  • measure_func : the function that returns the PID input value.
  • output_func : the function(value) called by the PID controler to set the output.
  • output_min : minimal value for the output.
  • output_max : maximal value for the output.

The PID controller starts when setting the setpoint (see setpoint(value) ) and stop when stop() is called.

This controller have been deployed with success into the Plancha-CMS project.
Do not hesitate to read the test_pid.py of Plancha-CMS for implementation example.

The following shows the PID controler in action into the Plancha-CMS project.

The example code is made based on a Pico 2 implementation and clearly demonstrate the usage of PID with a SSR relay and a Type-K thermocouple.

Here follows the power circuit:

PymateIO-PID-Plancha-CMS-00.png

Here follows the sensor circuit:

PymateIO-PID-Plancha-CMS-01.png

# Control the plate temperature with a PID
#
# The aim is to learn the PID parameters
#
# Compatible with:
#  * Raspberry-Pico : using the only Timer() available.
#
from lfpwm import LowFreqPWM
from max31855 import MAX31855
from pid import PID
from machine import Pin, SPI
from os import uname
import time

CUTOFF_TEMP = 270 # Cut PWM when temperature (°c) is reached

# User LED on Pico
heater = None
if uname().sysname == 'rp2': # RaspberryPi Pico
	print( 'Attaching Heater to Pin GP13' )
	heater = Pin(13)
	print( 'Attaching SPI to SPI(0) : GP5=CSn, GP4=Miso, GP6=Sck, GP7=Mosi')
	cs = Pin(5, Pin.OUT, value=True ) # SPI CSn
	spi = SPI(0, mosi=Pin.board.GP7, miso=Pin.board.GP4, sck=Pin.board.GP6, baudrate=5000000, polarity=0, phase=0)
else:
	raise Exception( 'Oups! plateform %s not supported' % uname().sysname )

# Setup pwm
pwm = LowFreqPWM( pin=heater, period=1.5, ton_ms=9, toff_ms=10 ) # period=1.5s, needs 9ms to get activated, 10ms to get it off
pwm.duty_ratio( 0 )
tmc = MAX31855( spi=spi, cs_pin= cs )
_target_temp  = 150 # Temperature to reach
_current_temp = tmc.temperature() # Global copy of temperature
_current_pwm  = 0 # Global copy of pwm ratio

def measure_temp():
	global tmc
	global _current_temp
	_current_temp = tmc.temperature()
	return _current_temp

def output_pwm(value):
	global pwm
	global _current_pwm
	_current_pwm = value
	return pwm.duty_ratio( int(value) )

# attaching PID
# dt=1500 ms, set_point=150°C, output from 0..100 (for PWM)
pid = PID(Kp=1.95, Ki=0.0125, Kd=4.5, dt=1000, setpoint=150, measure_func=measure_temp, output_func=output_pwm, output_min=0, output_max=100)

print( 'Target Temp: %s C' % _target_temp )
print( 'PID Started!' )
print( '-----------------------------------' )
print( 'Press CTRL-C to stop the PID ' )
print( '-----------------------------------' )



print(  "elapsed (sec)", ",", "ratio (%%)", ",", "temp (°c)" )
start = time.time()
try:
	while True:
		elapsed = time.time() - start # In seconds
		print( elapsed, ",", _current_pwm, ",", _current_temp )
		# CutOff temperature reached?
		if (_current_temp!=None) and (_current_temp >= CUTOFF_TEMP):
			print('CUTOFF reached! PID stopped!')
			pid.stop()
		time.sleep(1)
except:
	print('Stopping PID...')
	pid.stop()
	print('Stopped!')

Other example

A typical application of PID would be speed regulation:
  • Kp, Ki, Kd : to determine
  • dt = 100ms
  • measurement_func : returns the measured RPM
  • output_func : set the PWM duty cycle (in percent) for the motor
  • output_min : 0
  • output_max : 100

PymateIO all right reserved © 2026 - Written by MCHobby for PymateIO