Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 10:23 20 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : uM2(+): PID Controller

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 03:30am 22 Sep 2015
Copy link to clipboard 
Print this post

In the tutorial thread on CFunctions I developed a PID controller algorithm that can run completely transparently in the background on a uM2 or MM+.

However, I do realise that many BB members may not want to wade through a treatise on CFunctions

I thought it may be worth posting the Basic code as separate thread if it is useful for any control applications.

The code reads a user-specified analogue channel and controls a digital output using a coarse PWM to attempt to make the analogue input equal to a pre-defined setpoint. The setpoint is specified in ADC counts (0-1023) rather than voltage.

The PID controller code has the usual inputs of Kp, Ki, Kd and a bias setting.

Variable dt controls the PID loop time in millseconds you can set this to any required value but below 100 the output control will be somewhat coarse. The PWM will switch on the output for a calculated fraction of the loop time.

I tested the attached demonstration code using a thermistor to measure temperature and control a heater using a transistor switch.

The code uses the algorithms for themistors in this post

The example code plots the error between the setpoint and the measured temperature on a TFT display in my case a ILI9341



I'm not going to go into the techniques for tuning PID parameters, use Google for that. But the code does allow them to be changed in Basic and the PID control loop will be immediately updated.

There is no requirement for any Basic code once the PID has been set up but in the example I display the error each time through the control loop. I do this by checking for a change in the PIDs internal loop counter which is available in the PID controllers data block.

If you don't call the fucntion to turn off the controller "i%=PID(1,myaddr%)" it will continue running in the background even after the Basic program has terminated and control returned to the command prompt.

Any questions please ask - unless it is about tuning the PID constants


OPTION EXPLICIT
OPTION DEFAULT NONE
const display = 1
const PWMpin = 32
CONST ThermistorPin=24
const resistor = 15000
'
if display then
CLS
line 0,120,319,120,,rgb(green)
endif
DIM i%,j%=0,k%=0
DIM setpoint as float
dim myaddr%=peek(cfunaddr PID)
dim float setpointtemp=70
dim float setpointresistance=Temp_to_resistance(setpointtemp,0.6985229e-3,2.200879883e-4,0.7970586598e-7)
print "Resistance at ",setpointtemp," degrees = ",setpointresistance
setpoint= Resistance_to_voltage(1024,resistor,setpointresistance)'get the target temp in ADC counts
Print "ADC counts for a temperature of ",setpointtemp," degrees should be ",setpoint
'
DIM FLOAT Kp=-3.5,Kd=-2,Ki=-0.5
dim integer dt = 300 'set evaluation rate at 300msec
DIM FLOAT bias=dt*0.6 ' approximate output for stable running
DIM INTEGER errorcount,loopcount
'
dim PIDdata%=PID(0,myaddr%,PWMpin,ThermistorPin,dt,setpoint,Kp,Kd,Ki,bias) 'Start the controller
' PIDdata% contains the address of the PID controller data block
' use peek(word PIDdata%) to get the loopcount
' use peek(word PIDdata%+4) to get the error in ADC counts (subtract 1024 for the scorrect number)
'
'
do
i%=peek(word PIDdata%) 'get the current loop count
if i%<>j% then 'If the value changed log the current error
logvalues(PIDdata%)
j%=i%
endif
loop while k%<640
'
i%=PID(1,myaddr%) 'turn off the PID controller

end
'
sub logvalues(address%)
local i%,measured_value%,fvaladdress%
i%=peek(word address%+4)-1024 'get the error i.e.the difference between the meassured value and the setpoint
print "error is ",i%
if i%>-120 and display then
pixel k%\2,i%+120,rgb(white)
k%=k%+1
endif
end sub
'
FUNCTION Temp_to_resistance(T as float,A as float,B as float,C as float) as float
LoCAL x As float = (a - (1 / (T+273.16))) / c
LoCAL y As FLOAT = b / c
LoCAL R As FLOAT = 0
LoCAL a1 As FLOAT = (-x / 2)
LoCAL a2 As FLOAT = (x ^ 2) / 4
LoCAL a3 As FLOAT = (y ^ 3) / 27
LoCAL b1 As FLOAT = (a2 + a3) ^ (1 / 2)
LoCAL Alpha As FLOAT = (a1 + b1) ^ (1 / 3)
LoCAL Beta As FLOAT = Abs(a1 - b1) ^ (1 / 3)
R = (Alpha - Beta)
Temp_to_resistance = exp(R)
end function

Function Resistance_to_voltage(VIN As FLOAT,RTOP as float,RBOTTOM AS FLOAT) AS FLOAT
Resistance_to_voltage=RBOTTOM/(RTOP+RBOTTOM)*VIN
end function

CFunction PID
00000129
'msec
27BDFF70 AFBF008C AFBE0088 AFB70084 AFB60080 AFB5007C AFB40078 AFB30074
AFB20070 AFB1006C AFB00068 3C029D00 8C43008C 8C720000 8E5E0020 8E430024
AFA30048 8E470028 AFA70054 8E57001C 8E560010 8E430044 AFA30058 8E500014
26100001 AE500014 8C42007C 0040F809 8E44003C 001027C3 0083282A 54A0000B
8E430014 14640003 0202102B 54400007 8E430014 3C029D00 8C42001C 8E440008
0040F809 24050005 8E430014 8EC20000 0062102B 144000F0 8FBF008C 8E420000
24420001 AE420000 3C109D00 8E130064 8E020080 8EC40000 0040F809 00002821
00408821 8E02009C 0040F809 3C04447A 02202021 0260F809 00402821 AFA2004C
8E470038 AFA70050 8E420030 AFA2005C 8E020068 8E440058 0040F809 8EE50000
54400001 AE400048 8E420030 AE420040 AE400014 27B30010 24140001 00008821
3C159D00 10000004 2410FFFF 26310001 26730004 26940001 8EA20018 0040F809
8E44000C 1220FFF9 AE620000 8E65FFFC 00A2182B 10600014 2626FFFF 2624FFFE
00111880 27A70010 10000009 00E31821 8C65FFF8 8C62FFFC 2487FFFF 00A2302B
10C00009 2463FFFC 00803021 00E02021 00063080 27A70010 00E63021 ACC20000
1490FFF3 AC650000 2E82000E 5440FFE0 26310001 27A20018 27A50040 00002021
8C430000 24420004 1445FFFD 00832021 3C109D00 8E130064 8E020080 0040F809
00002821 00408821 8E02009C 0040F809 3C044120 02202021 0260F809 00402821
AE420018 8E030060 8EE40000 0060F809 00402821 0040A021 AE42002C 00409821
8E110068 8E02009C 0040F809 00002021 02802021 0220F809 00402821 2403FFFF
1443000A 0280A821 3C029D00 8C500060 8C42009C 0040F809 00002021 00402021
0200F809 02802821 0040A821 3C029D00 8C430068 AFA30060 8C510064 8EF00000
8C42009C 0040F809 3C044248 02002021 0220F809 00402821 02A02021 8FA70060
00E0F809 00402821 2403FFFF 14430004 3C029D00 24020001 AE420048 3C029D00
8C50005C 8C420058 02602021 0040F809 8FA5004C 8FA40050 0200F809 00402821
8E430048 50600004 AE400038 0040B821 10000002 AE420038 0000B821 3C119D00
8E300064 8E220060 02602021 0040F809 8FA5005C 00402021 0200F809 8FA5004C
00408021 AE420034 8E220058 8FC40000 0040F809 02602821 0040A821 AFA2004C
8E220058 8FA30048 8C640000 0040F809 02E02821 0040B821 AFA20050 8E220058
8FA70054 8CE40000 0040F809 02002821 0040F021 8FA20058 8C420000 AFA20048
8E30005C 8FA40050 0200F809 03C02821 8FA4004C 0200F809 00402821 8FA40048
0200F809 00402821 00408021 AE55004C AE570050 AE5E0054 8E350068 8E220080
8EC40000 0040F809 00002821 02002021 02A0F809 00402821 04400006 3C029D00
8C420080 8EC40000 0040F809 00002821 00408021 3C029D00 8C510068 8C42009C
0040F809 00002021 00402021 0220F809 02002821 04430008 AE40003C 12000006
AE50003C 3C029D00 8C42001C 8E440008 0040F809 24050006 AE540030 3C029D00
8C42007C 0040F809 02602021 24420400 AE420004 8FBF008C 8FBE0088 8FB70084
8FB60080 8FB5007C 8FB40078 8FB30074 8FB20070 8FB1006C 8FB00068 03E00008
27BD0090
'main
27BDFFD0 AFBF002C AFB60028 AFB50024 AFB40020 AFB3001C AFB20018 AFB10014
AFB00010 00808821 00A0A021 00C09021 00E09821 3C029D00 8C42008C 8C500000
16000008 8FB50044 3C169D00 8EC2003C 0040F809 24040100 00408021 8EC2008C
AC500000 8E230000 24020001 14620019 3C029D00 8E220004 14400016 3C029D00
3C119D00 8E220084 AC400000 8E220044 0040F809 02002021 8E22008C AC400000
8E220010 8E040008 00002821 0040F809 00003021 8E220010 8E04000C 00002821
0040F809 00003021 00002021 10000034 00002821 244204A4 3C039D00 24630000
0062202B 10800004 00621023 8E840000 10000003 0044A021 8E840000 0044A021
8E420000 AE020008 8E620000 AE02000C 3C119D00 8E220010 8E040008 24050008
0040F809 00003021 8E220010 8E04000C 24050001 0040F809 00003021 AE000030
AE000038 AE000014 AE00003C AE000048 AE000000 AE15001C 8FA20048 AE020020
8FA20050 AE020024 8FA2004C AE020028 8FA20040 AE020010 8FA20054 AE020044
8EA20000 AE020058 8E220084 AC540000 0411FE72 00000000 02002021 00002821
00801021 00A01821 8FBF002C 8FB60028 8FB50024 8FB40020 8FB3001C 8FB20018
8FB10014 8FB00010 03E00008 27BD0030
End CFunction




 
ztoti
Regular Member

Joined: 27/10/2011
Location: Canada
Posts: 65
Posted: 03:45am 22 Sep 2015
Copy link to clipboard 
Print this post

This is exactly what I looking for. Thank you Peter.
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1141
Posted: 03:52am 22 Sep 2015
Copy link to clipboard 
Print this post

Hi Peter,

thanks! This seems to be pretty useful!

One question (Just out of curiosity): Was it necessary to use a CFunction?
Or is this because the CFunction tutorial?

Michael
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8608
Posted: 03:57am 22 Sep 2015
Copy link to clipboard 
Print this post

  Quote  One question (Just out of curiosity): Was it necessary to use a CFunction?
Or is this because the CFunction tutorial?


Don't know is the honest answer. You could certainly use SETTICK to set up the controller loop. There would be more overhead in parsing the Basic each time but I don't have a feel if that would be an issue
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1085
Posted: 07:34am 22 Sep 2015
Copy link to clipboard 
Print this post

Very interesting.
Very interesting indeed.

Could you explain a bit more about tasks running in the background? Is there a range of background task frequencies? Can there be more than one background task? Is it easy to get data back and forth between tasks atomically?

Thanks!
Visit Vegipete's *Mite Library for cool programs.
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 01:58am 23 Sep 2015
Copy link to clipboard 
Print this post

Seems like the uMite controlled reflow oven is getting closer..... If it wasn't for that pesky tuning dealeo...
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024