From 25794fa012c9f3a7d3105655fbcc8284bde54c05 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Fri, 30 Apr 2021 22:53:43 +0100 Subject: [PATCH] add docs on ziegler-nicols tuning --- docs/kiln-tuner-example.png | Bin 0 -> 32621 bytes docs/ziegler_tuning.md | 83 ++++++++++++++++++++++++++++++++++++ zieglernicols.py | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/kiln-tuner-example.png create mode 100644 docs/ziegler_tuning.md diff --git a/docs/kiln-tuner-example.png b/docs/kiln-tuner-example.png new file mode 100644 index 0000000000000000000000000000000000000000..9f4c28d6db33152d40ff82561a3cc74d3d2bd45f GIT binary patch literal 32621 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

x0d%xlQP`f)CdO+e1 zx;QK8$hS^oglXw~aR9M<*nEcLtvAk+Aw6whfi`G?3hlnNSdC89*4DPYxgoJ}>BS-+ zjWq9Z|2%U%E`^Fsrl^xPd5uVp7#J9QTTC{{j`)XcMwXiBAK+u#_h)(PWzh%)Fd9_% z_k}6m@6EtrKSid&2{o&p+Tb#y_AKU7J@MC8a!PaSoQ{__+0DN8sY4t3?WM!=%n?R2 zl(qRazuoS=MIIRcJnJ|#h!)vaQk2v7`EqqOPrp{X7vuCfB5nBy@+LMv;Py79=Gycw zJ;1@Tvi3>7RT8sKBPl_Qpnc1t=mPYQnlx6&as@BgBO*dnk)lu20BiG- zf#E7TUD670Jf4jPhxHXCJ7i?c2732RabYBEx%P|o5|UB~2#oal@Fk`MsbxvwTsgdp zbw9T(3mR`v5bz6j=n2+!*ql4m1g0Duu!xE=K+bH_*@Gs8>IoO6K7oNn%6URMv8VM1 zx=0K^*@@WUiq1jj2=N=-56owNe$LL#QK^s;vabnYVm&fq!BhsKisv|jBnF;H8(CSi zfEw8V#O+rSFda*oa2~>)urwWZo3C%~r8YSGd~rXV>jF5N4e&m<0_^^b4Zilf+VjMO z$8JsrP~s+^FnZFhD(gvW7|e%H5kgz&(;LUEFZKIMyZeXi(-%(X6_Bb}b(ItErVr^H zG2$V(2$Oezyk>3FXC=GTBD#E4^#;NV!tyn#tzsxt0PacR{(*ZER3^ya%SsRMQ1n33 z!syuEnwWZU$(A6XHtfnSM9_Av&a8h)85j})@}+1CVXB!QN}-vv?>}H&f=;jAYiIt9 zic(o!ssL($_4t&^Ip_au86nu^E~f3Ebwm*j!MXSK^}TlX&j(nzZ(mE+*FTvK#IZ=3 zn3#+fl5suO3BRQ<&|~KThUHyM5#lbHcR3IU1v)x9N`D;i0fIrM>G~sv#QpN+=kxRP znA}I+7q0*)s*x~C6Tis_o=d9Q3tWni76&^x3!LB40?Tohdh+;68UOzlB?%cbHV3JX zJ%yyy)qkyAcw=&>iy?SkIe@vc0V)7wRFPZ1%1tu=^PCFiO^%{2mxH+-J`iC?soL(v zMF8~<5M;vCn&>n@z^2<30Y`waHaVEDso_Z_#(w0lWwcbph!9Vd;ztKqC*?ZXE`3Ja z)@y|>`}hGKIuVLGg1JU#`hTjM{&$4mk6b;Cu_O|L%a&*l{daC(|IYy5{x`?~s9vuR z0vffy)RYY5?^qqBRK&o(vVTgV1Hd{_s7;Wp;0Mmk2q2eoKUz{an5!xp0-&n;WPheC z5GZMCCvOk};6#*BTCXq-GT);Ns35joTKdQHOh7$hM^5~H7tK;0RR7hN>zZ84^*@8q~+d3n8tY6*zOrHb%v8TwyU6V zO2Oqw(d7{8R`x;-{M?B^gv#fHOk)zzi8Z)4JI-Yw4W|5Y)M?K{L%>!pWc^d^nW9$X z%++=E{Bo@33p%<|#rCvEEdTPIuYPxTS?a?pA=Q4q<2WL`%g>VesIuAX1!`!!Q$ZL+ z%cAhl-4R7Zs$U)(3uO8#9jH6I-bp;=dw#qUqTJkgME5$0SQap^GJR(k)1#FPSd>Zg z#MC8@I&%McV&z24gvRv{%jc?H)3EJt))XVd%D->DNUC$B8_ZW%G*0LyC zRpQ^zboEk>td*g@$ZEOQm;AA+3jban`GWF{2t`wG#b==caztnL<=;tP_YMcQ1!nqq zK%b8b`xFwXqW&wn_6|ev&1MqpIPmCXh*!KT^fR|A-Q$9K6R)7~_C=37Vu`MK?L~7B)DJCQpID3bi#MVNB%81Cii*qO5EG)2-}+k;0}{>lX!95Z zc6N?ik((8+)YLNd1r24Ib{TDQzNJ6Tjxbf%{OctA-@aK&)>$L~)^pCgPV zgMg9p|`HVpY#WHdmWr#Cwt!{{9Ph=lctoNTcY1IMGLW}-X& z`s#G>0ScoeXRv(^p78Ol}pz^BTUGI9XO6^HI`O5Kh6IVw@g9AIOk1HoChx*>vJFPF@qtTAsO_;9_p2L zOuv>!@XAzrycoL}b3k8lK|P$_|J$G+{GCC!B&8r-OYP+S1Z8 z#HAn=K`uFz#Qi-q^tX5jj_pz-|479PPR^KSzdO|&IilZLS#_6lHnVju7GesyaQJs$goUQI*44KPp*i7Guks2MFxWcwv0b-S6Qm~LN$&)|-c z*CTY=OY6Ef6#+blQt1F~P8IgKbliy5yq(u$B>`dsi<{F8P@#53FwnXakd(x2Ggj+l z3RYkTdK7@1`_(cXph@dORGyn;0FVJ|1iN5^#;IN{LSFizV`AjBHhP_DHMp~^bw^ZC znT(_fgVak5gfp7FFLq(3K9~D10jy_iP3jN~);g_yi-@>@T2B`v$~SoEO%BbUqiFqH zl#c2#Kb8d3DHLkZSbRvt%@cIr&oFH9A50aD2RM{HW6_RNHo0-GNSg`)?V(cR4nCl_ z2VQO3gM)}!WwzaRpCY5S0%j(K{~4uS(KG(6eqS;D3Ulnc%Y!V*Fk&EA0!oMS@vIv_ zXxzEtc5z~)0&B7xbM$IMNsgT`#*TYi_8Y%7X0rH3JqJ*fW_ibQ;)`wCrU>b+#NxIRw*eh ztybr32KIr&9>@gUnX$>aGTsHEhEod0IdAkk&D+%=J)@u)Xu4V&X#I@*N3ZT}ETe|W zXvRA(tFiT3Nlif9U7KNSzL{M7v%KNpt3@NGGe0%eC%P8IRHbv#~v zH&&taT_xk&qg{XuxRU53w_0&QT+w`vhIKiEo*db-aj}w7G;9z_4i*_Z!9#z zS66Q}YV!=t_N(uwzx5_U0?0d~U&}wCq6luwQ^_LbwpJJOF#uW~J|y!*SdHgu;{v-% znBL^GlACNa`xd$uLiL3~&G#;aSaoT+?oL^1G@$lQSzynDif-OiCyg@A;C9nvwV$61 zEKX2tt=HkL)&3P>++?g&i&NOLyE|KLO5Tm6O@*#K-9uurYO7$!p&Z)Gth4dj__2xc z$5;-j3ad|Upq%GscAw{YR9y=WeLlA>>hK!~+{xIwBGTM6sZGf}*m#-QBeZH~HeqSG z3WWC;4|W&y$IYVl#QW4xSvf(+f*%5&=kUm-C=ryXQc(;y71u~(#!cJ5XDiW7(2>qY zPG02IEK;tTr4rJn&vWB1<;O7GbMtYssAnOn+sAX?SA_mbdOzviSj(xXyjN)&`Np?s zhr3U4q*{HQ@k7y&amUK3pNPWvt2@hY)|e-CY#)j)TnrQD-uoS5s_A|k@iVqox&*G; zWr|!)&7FU65_lcbTG)WCFHM#Sjy7&5-?oQc#z~Lll z2aCA1qhjNUOmt8_=Ce)cG2n&phFs!jBa)OVNl+`}}3+@QN1rNs7D6Op~`q zTBzPe{x4I!rn~T{k0X|?23p|@W-b9s`EPi)~il;wW!?v;&2_D{!*VJWnzL;N%tQBwq`97>q z7baA;t48guDB!BGWRimhx>-$kwsYb_^{yT~sV%AmFau)MG*2gg-m}g7O!IoEK*T9Q zQ-gXPzopMw;;xF$9CD0#p+dD0N4D!R4Wec0>-8sr6tcApNCD}hutZ!Rf6G6;lWP%F zTziXH0e0yQYfXno+KkR_sY|g_k(H>+M`qx&%?$?~;8N1ecX?F9Ct_oBuMBJ+l5%J? z?>aACNhgs4*3)AW|9VOpy`!>2tJ>(_^3_ZiyuUKeol3O^MlV;AuWy>b4#>KTeEVna z6|iQ^!}@@|O+B>hCkx+2t|IJhI~Cw{eei3EDgo*1uWS6P^LNnPwt1zppr;?lrc}`* zVK7o%1vVcX$l0CCfNb)WOY6y3Q{I5cBiUu;$v2>+Vwu(UqnLZQkLinEB6l{|OX69R zca~M3AUQPCzjZ0fw``#wL$~Z^l;+vs0C;atyIp3rp&p6_EgRIVy4M!K%%SIbJ?ZfL zr>*?DxXw59U@b;xmWFzq`6P98OL>8mw#a#Srrkq7(t-0PLq_OVF&!OpVbOE!ENlxt zy!Fc@z&s=>iLA6=-Kl=(GNS*^)&0T)iLEtOEzbGH+;sB7X(V{`;`fsS`My#fSyJ{N zi%(wB(UAk)yd2RnF%kc5gLQT;X94*+9sGtpyNgg7$OEM3)N+OD9 z)lUL@d`lUPqLl`G*9PE*CCjbg--BnleB%q)#hv-9tgNhlu^CbYfG=U!6Tev;T^rkTBpeD&(@vlb;|>!S3#_6g$MN0s$OsO+fA)0D<)<#eBr?;Ngg8jqh? z1sv@ohiTfbtts>|-*A&%m1Uk7bzI&se6X`3T}AUef`utIpjG9yw8(z}ntQL zTVfaxwurXfX%$|=kD*~xlX`x{ByDVsovgxDCG~gW{ffwdq=s%D!X7+NwkGMqJe?9ClgUdkBf@>cOKBbXaSJ?h!F@bL8>YVbLf z1YkWzrl2#|(r?p0X)HHs2==lkuWdUa**6?9EjaRhZ*eJy!xA^yGiGO&iLi!IGXgzwI%UX64QOS(N@(%m^cI^rcPERG-e6?UM0?0p+dIs=$P zR)IgZG$ESv0vK7UCXYE|%1cbJoJs55UhjE=(abh*E3YjqNxP`HCwb(j|GOExQSD51 zId(*16=kw{l63Cl!J=~1Je2VOKG`R_Li(xKOjA-__g7WlQL*72^vBj%jj4E$D#PE$ zydm^2upZCTgN<;#b9`W6)BuOws!unvn@Pl-^^oH1_aD4$DrCMtcAu(ZId3M}-+A*> z`@j8s3*Yawn@RAUr7Yxw{HeOnrb*=y;418oAW_dbBQ#9*R>-MTMi6HV@2N`q&f#{Z zxA1D`wYe_e)5(Hbq1jilB_E(v;#&GlZMVM&>hBvFg+>qcbf$~GE}H)YEDsC7S^zVA z|Kjc2Xouz#?8zNf2+fmbBY}fGsHfS^(Wly`@S9aL?;_oQTBk2`IktCU&zVVVygtH! ziO@k^ku-UW$YzSqB7eO{Y@<=l{LW}*AW-b+&kGWLeR7Sq*XQW-U?;yEDc*?h1<mAeJ!pQE>b3MAr!ch($Iv#Gxc#23R?d>?)DfuVd3R z+QWVn4QC0bEknq$iZ$9SnV4`R8CZ3#?=7KcHafljBT+Dm2@t1Zd-)9Rh? z5dzB&coKYm=D8BB`^U$TWSq4*XlQZ|?Kx(y*MSzQ`wa=nWI>^UTGWe26k@zM`sv@5 z6;fw&;G1jU%#>?PI}Y^P?WI?WZ15#nFsiaYvSaki0KAiHe%y$@MjEy5p)#wxycG8D~p7ZfcTXKxJ_AGLkJh ztmFLDCr1Y;RWR+1|4^G~$`ydiSY;!u6;4PXP<8;URrc3%gZxV8xtFab|rs?MODck?bLGu$3J7HI{ORl;qV_>I&<%S2d})A}3kc1!w9PTopaAJS{u7`@yzy*U5QIpV>Z8MC(0_U0sT=GJ%b0Mg z-c^K3pp?PU-40Uci4bbyOW!Ij`C8qUF(WF!qFmTyx>3`N7uOYM-Ox)|4nge_&7AFyfma zwo=vnX@j~|2vn29tBsH`hx+AfnowiS3p3cw!Ku)m=QLNuR*-HIQ$i>q9>TCO5EKHy zEAp^484k%pn$cxFW{@DmX{H|BO99fN6E?>O}C7;{{pGcpl%WqY1{#!2M?Qp@3x{Z&gSFT+FqY3hak}ITdRFlllx_AvYcbV4rKAI8zSWqPs0WbT%>WrUqo!*oSAva(z@43uBomeM26u}n$A0qkPLsO`$i^BL)+`)c+VGwm9HAjgI#x4w zBP~b!KnygReqY?p?mBb*64uQ|-z9DD_- zA`4hQCGy%&YLoCR*H&$by(l%5r5Gb&z(go-b|*RybRsrYc6GYqx>%8u7`6wrE>Bx+ zirVMM$A*4=WDprtz6|jec^J{N`Mpg$i-Bj)vkho{yn3&y_tz_pNG6_<2;Jck7bZ`W z9lRGe9Xv13;=c_Kzo^rDj$DsB$eUu#XPEs7;ZUNED^1Z}(XX8(*)F*yL{1$VT^NS+ zYIpzI4gWoYOYMBt&4#4q@2+;M&-rcrG}hUWHZr>Qyh6t?~-Q+*ib@I&77{%8pY?z1TBfGVPk{GmhS_b0T#lT0k)5< zWXS%{DZ>!c`M-9WC{Lq+c&#ULYr$m%WqF7fnhnILg}OCAzJ7g5r zp7lhFv`m++;d`KSy0fzrG>V|q?)EtWN=|ih!PPqV;Mt)VIWlgY*SoE zw|r7DA~FETM+@kOk09q>4I(jE?xRm%2U;OPzDU&onbQbZ9ii*xz~>^q39}UzXP5I1 z&leO-tx_W--~fxamIOxcqirJxP)iS;vKtP*My-u# zEn(zErC6mnR(P1Y2_E-hE9w~VsAMKsQAezOBG7vf;FqlCt66|!VnD`{7AXo#09eu+ zWOJZ(4SBafvt-y1{D9I5ObTG>GfcWddnWg12|N|H8-cd}zQMtBQ4!~LnY1j`XyC}( zSd$OH!;=&8YxLMrn~@5EcMcjaR`LP_(C9`C-O)(fIxMWx9LU2FK4YimIsq{Mkr#W@ zF59CoMQ*og59{|><5=}~MeVf|zvfy|O`E%wCpoQkb9kRy+5nxKi3GNHd8diebxz~( zCvyv=wm(GU9rk!|EknvVpz7I$qtDC}co!tS=KzPh%CWXNV^ zfS~uT^1FL_Vq#;v+5*weiqOqxN{xXXodM66nTAvWzI%d#6MW{h!eu2I?ho=3F)(p;;$l&YqyVQRR2$swR8>_Icpa$Z(ZQ8GQo8DvFcrh5{?1E}8y_VmNkOk%Y150O zP(&Qry42*eGg&|)D=XXC-91)mrAEwV@BuiBhD7@I(?2^qJLfy&JuND5fIM7*A`=x6x;T*DtL?_LR?|81Pu2tie$CBMR<<0K|I_*BvseLa@bUfL)#FaN_0zO7W*V$<{uz$WCv(_ zxE~%mp{V z+acYa`}F81bIC`yi6o+_GDWm~pXMlq0LS0xXI!)PaVxMoQh*HMO;r)Lo2Kj-@(LAP z`?-=?N$hU1K-Bn}w`A?yd&Zy)HS&_Qe{=T&+1h#AIfuq91~Eb4^jaK?E^4b;ynb$% zlWOjN(x>}~&rP}f<#sqJ2Ds^I&>t)MRIevBhIO7;He0>hxu?yELOcxg@jKpZ#3MJ$ zV@pX(>oQ982OGI4An6@4zol%xiE?3UOlnzM^}9<%B^yH<;$^`?Omj@?0jNRYkFd_X zPxqKc{i+5;ioK^-+UK`fou6_kZMd$h4Z<>3xW=s3Hs)E?`G^?S9_wuoyTSXR9(}xg zxw&_ABk3O+M5mEPP0#Q*d5(ycW8ycHLuGIfp$xy-yDJ`)IoJh(nyAkYYb!Kak6O?C zGx2+fEKGB1{AcsG^&CVr19>&$tCl=14&699n>qEGQDD<$N*|&H0{EKzt#vPRRy!bO zYC~j*GMOk1dJJOlqos{9q9f#E|Cr%d?*2cqEV6Sj^l$=0=BFV*j|}-3Nz~fEw*xLV zX)PjddhB5OC~>Kpo|?D0-J3MPUSZYiWNH&5mj+Swi+To7Cm&My{(=p&xiA0^e|Rx^ zQxnT9a)b}Ui3{84_c3fY#cU>lY$gS#{U-qa3N&Us1xg0hJYm1c+cuNCsb@zfM$)o| zhKGcf>_G78T3WGD$NainN$G#xj-BRLwH;-${&JT2j&ez~b zrGLErsCG`Cf;F&~IP(W$iG}}zKlIPQsRx}Jd+cr1K-JU#6-(Ta`=)dB1Xg8tB%n>M zqv6_tqZ7mS3ArwvpMj8mB2Av&_S$*OkZx~>8<8hRv^eEB=lDY|?s43vO>CbrCZpL;+?P_4dt-NuCSNq4_O6 zfo1uX2gtz64>@LT@%z00y=KsW@v-CG?fJosviL0xzH?8yn?&{~pzy%)Ti6}V3N!F* zw@>xSl26CCKDn**JPfRT9)K^X!N}|TTO=z4q`!J?TpzaotA7aVVm|Ow-aW3Q%2w63Rcm%a^=slo(q2ekW zp0+)P-(_4BB(wPtv}eHd-Ud+dLtVZ<8|g70MoC@tl#DEtR`?_U7*9>DP<*H2`8jRYtGj`gf`nIYG^d727N z(ua+Lg~k(kP|^_$rD2+&a+=WBC)xTg?>H9`;v*u}9Ocp=<*h?_a=ZxHh}RvwJFG1% zexW^#1o}mDMO~sj97wHY81QY28FKp+C|Xu`*bHCxr}i~(ho0ZTFAs&9zrTeeUt5?v za|yqZX2bYLQiVBQ>ll>nRwwaHpNLRM`ETro@>5AXeH=|?F^M|8$n?B#p11k7bLFd@tq1Q7$<0IuOo30gD|MUscPIMu_8Qy* zdRUSY7Wl}Fcq(6yYibxkui}YJrnZV5Z`~RW6NFsf{^;U5`{T4`@`eTj1uIWN0@-)gz_!nb`ie2jscn z8u^y|Gk?cs2D~8r$9py$nym_pp16qUelZqo>5i&>s^`>$|4X9F+fTzS#X(LYGZ-oM z%|GE%w1+Kl{}G?xx0}Ed5Ya1>J~X8lMQ?BwWxJWk#8s?+T;4JomYJiR74P-m3kZ6Z4u=Ih6)(v-&oRsUz<{!BpVb_0{WK=B?g{@eGC+*Qcbmgb~qU50`X z73l{ptuNGlol7CRt;D2D4uuMGLoyW;qiB6x?nU;lP& z4Ui*znv}b;+!hE5s2COqizLs^IOBy9f^0+a%Ab`Epb90rQ5ftxalg1ZBHGX!@9n(9 zm83yc|NWv=r$|O#9=TN-Th;MTQfoBZl~G^!qGRn=G6qt`ZorVylUL}tIL&AWp+Ag# z23-7FuAd&-kgO zI&X%&gW-w?nC0XBCR27J9qTpKw@=kT+pr#ZspmnArM@aC*+eYF6s=6KtO&6vUf}jF z#PIL)i$>92pksSHl%nGLJ}`zSg+i07JFg3IyUYZU_S``{-(eftcDm)29S}2Yw*pyD>dlFQ`k}J>~>lWCQsKl?Faa0jm6?T zr&y7#WPFwEWdlM935(G+>Z8_L4N(nT2}(3-SSdWC%IL)LduZ5aY{*Vp-vvFM+W&@j+1FFl#wPCUQc+f z`Hpu-Aa?gY`2*oo^9nMc=sd|waHBEqJ1&o7-@{4GDh5EZLrOHFiDeEX7O}!LRcN&2 zrq2(pj9PmLp}|9_3Gyi~RDDYQ!}TG{!rcLd^4H)+mN_we|KNM2+EN9fT&&%1@^dxI zKSl5)Um^DS+56?0GE-0hkip4t4-#Z|4?&4lzne*Fo&WVc7b&F#9e<36CHw_57v{c6 z7YJZF?-N}Dzrp9oz(;u}DTxvt9Su5G30zNaxyfw;LqjEjNt$#ysgn*Rh&T#Oxx$i_ zA}BPs)fD~<40R=Sh2^`Zpal4=qOGvrZ_x+?wCa~-t9Mk8nFONi+K~U@j*Yw{Jm+`+!ZjKu!?!Uf4m*wcI<2i5ZTJC%wbN-Pb2;Cl6Op(~e+lASxjR zlHUG-0by?7Kf!dg2Vs_d>ch94Ek^;m`$*Z1Kyvc(!rU=*3hhA4MydCOwe4Ibx|x|7 zsetPnb&ZROXDaKbHP0BUUQri76N168D@sr+6A4aR0hzd;b>pI&wxE!}uQP@3c}{E3 zL<5vWA11c0H{uPYfE>oz*?F|a!SJ7#rIvqbKBS9KP8;~JfPmIGgLlr(Z-E*|P{UC( zMORms=T6T5)!J7_Rk?lbzBD4;0#XMg3_!YDK}kskkx*Jf8l+QDKvY0LT4Ga*(kZDT z-3=m*bmyI0&+q&0z2n|7?jQFI$2fcN#$J1^xn@4|S#j$lHbrT^XQznYo6CCXkW<(P zYsF{T#k@8d5XP#cO24)@y7l17zB^fhPHcJ;55~OVIY1nYe86NWC>U*q9h9}I#f~tSNO6+3wnFia>$%hwNurH}6 zKL-#*Dr6iGzl@vrYghpWJnO0PdeH~>P-_|~vH9pYbK|q!_(*SZ%ul-5-o2o?`FSr-9pJ@*^uMOI zwzk=eiO*KO8is}|9v8)&l^)2M$l?2MZa#S(7bl%tP{DQMf{?+hsp)=$KEXSU9a zPj1h2AMF)D{&%|1HrnCA8S#*i8EGRI4$hi1Uf{>o%2JVypuXBw?cp@$dv*e8oCpgYX|iA*-!0Y9m1A7>r-xU5 zuIL^=vI^jmUu|spe__|%yZy}_7}P<9-ur`+llEJPc{|Ds&^=mdXj=($4(tB$Ir?E*)8;q5F{AG8qobLdcmfQ);#7N zNx9OqWK>ka%@H(akRLeIQlK>dYeGLB=SlXLMlY4QMQ|itt9d9wZREp)O$idL<@1tuV*>tYdeGyOREn zh@4^?l=|sp6a`8qOpOVPTa%PCJYcz~ZelCBAp&)7?9&oQ%I^$h3VQxpSBToket$?~ z&f?NF6zQ99IAMCssSG~3@Qi3(QT`x0^eqb0pIb=ts z5=&{OYV)$D^i_6V>|t~Wzvqwm*YoMKJV>-3DP6!f^0W}@I9TS@R&HsK5;i$tAC%8C zd2};`aVFVBYePP<#ZC~S!Wd_%SN?$|CD*pS&hCK>aZ7i zas9i#5K6o(nw1r0u_DW!ej{zfl#|6_Ye0Q{frh6(U(8`XR?xlbwyy})S()PM<68=S z4#$(vo`tan!4y{=T0H$M+1X2Nak+I&o!V@nP!;hbnl}u>D@@Wh6PcX=f*GQ=v+?*a zPR#t#^0J``SLn zo9nxN+gW&BN1}x{84<%d_}xMhTq{U?AkGh`){8Oc28u_J` zx&Q;Y?KzHMO?EG^ZYywVvu+}eMzs5$s zc6QEZ;L`i~)aJ4YJU>~hir?I^;l(F9N_cPD&`)A=^NCkc5z16ZY2RXQIDTji$Y0Vw zwERcfb8~XKgf%7Cg)>Qz@T|1SWF})$x(W5prfvTjO}oh5Tu1sIcAU=0>gX@8S#jYP zS;4$<+V0c$xH)m-j`6QxY@d45PptOTp{Giaot3~F_BWJ2!8nJq^t?dxzealMgI0$lIba8Z2A>!D@Xcko3eJ{nAGCOD#an zt9ZMKf45arPfX7(pC1+Gb=*pfW?8QbDy8+^ksnIzYFWPQ?Fb>2rn{*OI|1h1*q3kL zE_$eEt4R;`{jLy(Cv@T{NtGdDlhd0a;7Ll@r;jg`_9 zm?d~xZ;NEAD^Om5d0lwESypD%7K15Ki^ zD`vgn!C+G-LdNnZgy#8gQ6})rI9Ime<)vrk z7DHJ7ON0|fcMknx8ZbU-qxn1ThY{oYUGwH&a}u1ER72{u;>HP;P8;X%$CWf@$XAet zhvo21lS*rnel32^DCy}wA#4r?bB$hlCgZ`T#N!9q_rrdFv&h&=@$x>^SqTand+oID zG7@Z5aBXb#b&lP?5duw?FalQrqZ>d_bT^>ukcjIH4E?{csb z5cnppV%67A);2ao(XbBK1#8`bn2`WGDdzduuTOb9$!LjY?QydtCBsqZ$8IV5u|cnf z!7N=W`a@0pbTo@Ui|{S>Y?GmOVAoSm^^E7&V_z(FH~;`2G&ey=csK#n*02x&5&J`v z>wU$CC@ZB&)1sh$N*rV;!IROBL6pWot22=MTlq|D$%3o1aOr#J_3h**N+}C{f&(Bl zLc3sf{7EtKh#3IEmw)7#0J`>YnqeHo0k z(VXRqT{rI5^_y5RK~>jgsP8CbXYfH-w)qk7O&DgnHRfLa;W?%=&%W$&)1oFb`q-Jn z2XzQCwz<_BFJ&2^PJ}!iUBx6UcM>&iCy3o}d=F$|cwhqh@2bil&Ql*pzGsqnMjRZP zdh0s%4&$@;agpn}j#d9tBEkr!Z4(`MSVObmLenT$3eecsUJJ`X$9VGq16!iK^p=@@3{1Wx=$r768+AVWtCnG$5*j+ z8CAXr58yz0CG7ZKnIwtU9n#naO!6ez%A#sD2?us-cnoLBL&? zpAN6sR2YP)q|26aim>ZhyjfWZh|vZw2YhJ2*<&DRdeVrSL<0jhBbmj7TT&jlddIsL zk*QC_aZ~=6Invm;b@jfnc&GDoF|0`|l%N$ACJQ!*-?RtQlG=!kr(9A2W*oyYj_a_W zXxyYf)djtSi#<#|>=!yCe??1mza_WZV@j{gsjW;SJA}flW513bi=ZG?4BIqBse7V4 zLG?f0^1n<-AOOvqpPz3{(eqe{9tyi*kR5<3t})cx&`^DKB27;BMgQ;Q@7WQBkmR~wm~on06xppU(BH(eSBK^McQ zuNj81-;Ong7EL8(^~}D(B_Pja_N-X(-g78>^Vp z-%zJ|z1`=83z5;XIcMa)#%EaT7LolMeBJ%`kMN4P2QzLxsM|8NP2>v$ZL6ToBho}- zygv1XR>J*5?FGNQJ?HLp#ds-ivBH|&dk{w#RR=(;X#Twt0_gV;4v&b~=()`^T{37S z4^=u01c*KqAl_R)m`^c-s`|uaOwN~nq0AIVcf92L;!Fj%&UYOw7(JXgVO_z^sC^!h z8Wxr#`vI?n`e<*h65u zNr^-!C9U)(CnY@x$~wfMKVIdMfXzVuy%$HzCvPG1Vcwqb-u{x}6UqnDa6T_DF zc(gQm&*Ii&gPRqCd7LekaU87gS9rAPRN}kO?5c-dQaj~1?Jg=(GRn=K%2TQk=9IuH zV@xfvKOQcApDigZJ=vR=5EFx0H6EFs&YEJ>cYOSGd#S(8Dc?dU(L^Y5r=2nc8hbXt z1}`VlKS!Ora%w6J8ic-M>7RpsO2yWhwohI^)8#8@ecR=Sz`vfC@KSx&(E7IajIaK=z~g$@&3^~7;IG-D~pQ}c%p>n#Ni`+m*NP7gltm9&Cw6yh?v)wTE_#k8A- zgCzUhtfHl+&zO@$-lR0I?RKx!bf4tlYlE9)WZiF@7`4&S!O$m*sCjn~j-g7I%aG}a zgzV~hbn+%i)Cpu2&v~H>!)fk^th2KK)Z}rHu&Aikcs?`UN8c$wTXthYDX0~;T-3Gu zmF~Jb6gUR=L$@$e2iFWXe%w6&fuD~k}Q!867xZk=NI&w6$wSyvffZS-X=%%4z(!5Qw&!H79A?|Zp zK1|&_s*}T=#&D|3shr{2A*^xz){2w0-WcVK$HpJ^ovFU)jFxKJ6=(gNu-7yDIoA)~ zT-rd&Uq}@ zcM_Vz0@^j$Uxr3@XFM)2n2AS0PLc1s3iZDZpGQX`5&7v`51~uD;&JF*P5A`;Ik|Wc zi-RX5u|6eut`_5-Hz-w`pYs^Wz@x5g?@f-uJNMnvMGU_<8xDxZua^-MLWo3JjD9k@ zs&%_!r6woejMqi$5e`MDYIE4{Wxl;labx~?#9^5e^cE9%+AK{MRpRW%utIf1KOR$D zo20T4pkox6uJTvw4 zgBedmlhpglla@|GIko>}T~$;F2?z+b+c~Jd#%g+E`5qB(4PKS2E?{V$qgAQdGkq2+fgH;fen zMiG7Wz*N}i`1Gq4(F~SMRo!WQ4@t5@_OUnOhk@tYKy^mfnf8>GHQXImE?XIN>8R5W zr|RvznrKx`BPxIT(tqgDRUQ2*D&M;a%tzhX>)U~5LuN1sFEFvVySX-f7_1Z(gHN}) z_{44FH=4I-OMdes_0!iRyEbP8_q`GaDsQo}rhkPp1ZApmLCfC!g9o*Knxj&Imz3)p zNiueRy!G>E0-I-Txc@3Dhxl*0+kNL~a^s*wI&Gj=Ea>dvL{Q#$lGJa-7XGIvJ81G> zIvnt%rN{iYM{98QH}+U<#SIA!u12xGd2a5lRd8kZ7U9^*#Q~QS`WB0KL)WdRIb~vZ zz-to>kBl4;CJPn>d7`NHQm#9G;3MM|`#p;@N$}vl_m;8?r-t5G5hOZY~Fy2*35uk{vyDQdA#_nDCB&G(ev;i@ygHj@9eM0{0vMnxEmRji{}w9MKC6=Ho!?zDG<_vgzX&i(o^yNnE(*#eeykYLYF9if z=jf)IY5enwaLLJ^)`kG83dNf$gqg;BcD?7q8`PUUh~Y`0R#2}ljWN@TWncGu35pVY zW)dz?QvSt+WgT?1Jt!fuJ;5VlG~Jbw&g?)kGwG;&xrs-ln-lxP!*jfk2#m|B=H3?G zo83Y`qsz-VQL-bf`HH&9ud=F$M{bW9Q#r_VjHR ztnYcRGY`Yc(Iw0wyVZ|vUf8~4#Xn?|EWz{e94gIP@Icvy{Tyne&zdTfAU9+fM-Edv zTb_6P1)j?+S%J9(mlB9GPXD^fLQ%7|{bv8LYB3H-FlR&oR9`?ER< z|2_iMdXoZ=U#!vhhM60UUB?T9Nga|NDzK&AQw(82Ew%d9jIFv1=rNbXT=`!K~fY`y>VRt&b;HrK$ti=+u>_YmG@?cdd8N(G;K&i!WVlp@X)O6{yE9B4PP3nkMz z8<#OoIg+t%JYbYfi^33;JNauHs}#OnlA9q&is~t$^fjm7q*I+WM{A0`uBsTw1C=w($*cQndYZE-b*B`{?+m>P zefa0;A9j8p(9y2g3Kj20SwQ+^uk&eCXSPpaUe0yT8OzUY)_BNQ4=KD9mHno&`nIo8 zH-3(>%wr-x9w#(U9ggrS!?_3RTqMPa*07PG3UiK$3y!8|`qG6y2iArTiOXVZ2eu>= zw1**u>EEZ=10B2fBM=0yPBcvKny;ds=KHhi(}fcmdqieJ-NSt&oyLVq=eos1RvU9_ zB-PjgBi7Am)nID2=ZL4d{s0RDX~v7#P#NKeFO_WBsgHgyk04a7+#i^~Nv330+GSKt zCr}L{4mjl%AD!S$Jw@uR>t&%{k?Ojm)8C0{cQ!aXHv%$o1VbiE-#&I6)hqLeOtIP{ zTzdz!VY)O_Dyb(4Wd^+EVgtY%m^@?HwQYi>#N`@zXPsm3?`^%URimu|#wAF*|A zgx6kn_|^Ik+?7s|z9I7kD|u!RuPzdcLu${n#quA8Yb)zw%gfqpWGT|xJHv+2)yO67U{k+6eBm`O>|iO__ir97Ne^{@yYT2-(WJ*m ziv^$lrAdt(p3Q%@0dvHT<|NKDSXpFVT!j>LF_UL(o%8x!_ieSOTrnXi9!)8Ly zuM!Rp&K)bO+`d|GuiVsB8KJi-w?OCTTP5&`iH$5ch^Qdx5AQ~j$u*s0NqA&oF?g(g zQ7ktmhPgye^h!=#$56iCoZ!j zN67ZUAdBeY-~*Et4}Xgc@A;QcEmeQ!mA>ieCi#YQ{i$2e2omxOGnZ(7y2{TQi?);` zv$WI%_8b-+d=&CSf81%@_3y(Kuw_zujG#XzuP|a@>(Y14OGS?$QhWY=AzPBHLjea{ z;)ajR&5f=q-+9TV{5~P;4OWf--HTmF#)MvJiv;qMcDu4XK>myXGk^kkz)C7Alz?zF zg@CeO%3($Jg$B)g!JD@zK6Uce?TvjO>C-E4%gI+YF41A3MF`0qzT8#qM&;r_c%#D~ z(V3oAxq0fpl4eyOfCJVYD@qbqB@q|l%^Wy!e2@DHgLm2Bgv34Xdv%Ix94ADL6U2)td+K5OV}K0L=C>Jt7{=h!?j=vu)~7+-VtiF1JEJ1R;f z<0e*0QoMAD69==xiyAb+Jf#RokE`N*to!QRdG$&Xl$&~nbd2+%dH_Mopm3DXKP(;3 zUtiKJR}yBMG_F0RqZK6=d4e4lj!Dhq`nb9io!_F=1_QDh-f@+WS+aS)JBz5NmsVMT zC|;aqf3VJQP23fG!t?w>kKzMm_&(WszY%=S;-HC(uo;>l>)akqkM+2mXG>Yc*m0y%5Hguu-VD)O*eMNt2G5h{e z5^yecUw~}+3xijeWDJv*cYa3Hhmjo;z#FZN33K}PMHmWAyd!X;A5Hb^-IvUrPs%{| z(WmqKIcelNiaH<*qcpU_g{Z46{?p(ta|ZFI-kI6>f+w@LTE91mwN^*MAeLFg3{Q{( z-sEMc9o}jcN%8YO) z{_`nrJFlfS@z-bLWb$+m!AoW(pdieV-JVOdH|@z(M(106P7f>$U55c+?#>G*2;}g* zH`cEpU+Bi#pQT|Iy`W#m=)S^NU*FCJgK4;cWleh3u$gI> z`2f&*Z!Vlh5@|>))lZ(z-Fpv2A+-VM$4ILZ0-Ef~{^8)jBaz&WRzHH&DjHpoA|#yH zj+@v%Cwh&GYeVd|&pFMK1*_AisahOU9pd*5Zh=HB}K5~5J7aFR#1q^Rfx zXmZ%Ga!P~@3V_iii-g7qa?Rxso;pH95B4eN%8?)DgFiXZX|D9J20yxoF?P5AK_^bi zfcqe=ynJX2%GS}fK}c#oVfl{kRHQhdGjNQ&R3FH~w2}qMAIru>Mo^E!!Vz8bB)2x0qBNn5|x;gDJVLiZscY+1vZS7eFEUwsP#RH*H`PdJ$$G+dM( zN8;>wOT>Mh8R-1;c;1glY~u4;L@u91v($%E$;bt$pMyD3yoB4wTnQ{D8v6QS&^_@F z4-W}YrLdc^{|o;vGGWcM@;^XrLGPSk}?Ns{zb4FM5Tw9tR;lrx(iC zbOYApUB#nk_dzc4;3_&OyP7kGsnj(-1 zCwJkm*1v`VZ|$rN@fok^r)D;}Tv4uX2qw&iG5@0R(#ZAk-Xh|C!nWSZB%_G4zLfW8 zbgWD(vhNSUQp`kQ-Mw4r;5p$@f3mln2O=4UG9lr{nN0DmoQty?ni8v>r3NAl;K3=2 zgo|HEAfzcwVlZCNm|D=RH+9769kuJ#gPAAm55ss9u$=$NP(5g=?^}ttwrAxZ8DGeR znb@YH(fe(d5Rae#V9oQow)1EEi)abH=lCGNpX$23Ox)d!axIz<1-X?kyi-z}HH zG%SecG>nLUq>#k7|Cy=uUdX+3>`jNt%y$$%&OnSi7|>-+)^yKi#XG-J#)(yu2?^1$C1!=ht%0o}c)tgXBfjU4G+c z0zDqIY0<=jQd7l{ZGF=-V5_QV0Av%ULD_Y*cxeWj$*|L~__ZhAU&~g*DgNaDsbjMM z&1++gF#NP%339mlG&~#=EZk7Z`SQ(Mf2SzWMCNgRzOHc(8|W#pZvC#i!-X{PP2Cro z{6=VhkIZ^XEbjh>2)1m}sH79rEL>?3&3V!O{f*3xkjqJz*fCO`HlVGm0!uJP$;X@= zhsR7VZC49#zA^Htuz7Rphw(>_)A_^Yp-~_U1BB?s9{ag?J}g+W!F8yLkZFd&CsJ+|c1}3H=X?gUY?ug)(e2iv8t0h)~^I#SK{1NhA zu%?`uP`*dMP6=uVa6LU5RtkLs4D1bD50is@4_qe;rUV0xegW72>kFDw?Nj-0;$tA3 zTwLAnU{cdHW=|`ApNgtwLu?iFIyM#)f$onCar7Y53O|3Q+}PMSG#3N(E(;sfB0`BT z${89muqpSXNL^)TXSeLlA|k#h7IaB9VL@FhY|4dzq*`s-e~?Q;p}~b*E)`yoo11&6 zpK3yHKe&hK20 zn*IK`L1dcVAd&yB!wCKrgHl3Zp#U6&+>IN!wFh(b-sk#XRXEM3L)T8Hu;knf=%xBfZhQ=03pB?jGt6I5^&J;pd zVqe@H$^YL_NDT)xY_e1OOrp~D_fl`ivhy4j6;&Eg?*dM3|JN(^4?ra)vD2qzIr2F- zI|P0xoLKY9eYIl#13)fU#wsY#2+ZSyt&c!?s!mj-GxO7^l@ee1EP>A~MB?eb13Mg( z1ze*hD(dROM2r$cNiScLLA&BwIbaM0mZ2Ohf`p7td@s9X1Fh;g+3k0G5Iw=e;#2K7dOCXf#x_?c6LRHjV6lZgzw*P0nHRo zve&98OAu*m6cf#j49$F_nh~unK)~SNjcv|O@maFU=+(P-j~l!QX29k#1B9{}*rF~6 z!Cs&Oyj&`p;-PjpaFENH@WOS4F~`=6QjY=QS%6;IVA5*cmpMSt(FpnaLqnf~+3`bI zOP0%*^IQPj7jp=mU->X`jsWuO2Jz7Z-g@Cj4s zsH+cpe$zn+t0QHFe2(2=yx4Ho%%0V}3jq-{v?@k1O7g<|12#7e&Qx&+S~Q7yk9Tr6 zQ>47tf$M9kY|;k{u^lZX0vE6W@T=$i22mf2^{=oB3zw-4$I$QGgr$#^)zM+&;5hos z!NGw(%LCk^GXVHXcwC2H8`$wq9LsNBY`^LT6y1?26yIAFONb3i=!{yY?$&q;`W!BD zfOskTh7WQntc;eCw8inXLSyU3dLzk9D3edUGnc*ve?PlR;6KRWuL~v?f;ICeY~`6F8<73fAiNJJ-N*fr3h zva@-K?Jzln<5G{I5vJCnn?qVXZN?vuv0k1;GKk*3n(Th1^Ovh-V*${xO9Fy|Q*WbK zVkYy#_|mI$@KPv12dW>15Ycz#>G7lpp_t_GRsPQ~*6>cj;y)PHUBe9UlWAYvNJ*%! zmO%F-gYfkfJ&=Z-%LCQBy!n2Z&oSp-RdgwDq|Cl^nGzFPk?%iFES-cv7K)rW^_^Or zfa3DIa&&`GQBz`6W#gXaW6E;f+d9yU%1%W|sRa7x4rEsPptUl$y4p~Pmav#jxtLT= zlTwika(Q=!FnQ0jTmkW|vI#gBjJ9S|-8Y#O^K=W~=&NABv>Jn}><(Rj-lgVghkUR% zs!tD>-RIxAMJFVL7Z+cD{pO9VCMEm~r5J1-9X=onOmds>(9od*{OcDc-(!frd>O%f z0Ss5<$uE2;vIhVi1cV>7upxlan<4q><~M6;Y)%Kb3Hm^#igfaH)4Y#%(UJpOtm&@B zyI>$M{9??T3PgDO+r8?1P}q~$9Wn!N`f`yLK5#2?7wkDc-^5EbAP62ENw#FB}C(93#>5MLmU07_&O8^f+33hWd z6yY+VU|j(Ma>vJ~mK-*!Qp`iJke1iqsw8CHrBr-IE!Sj~Fd!i=euQ%_<>F8lXK8MyvJ;v@bdnoUrC<>6pp96SRp{ zQdg%zNNH#|o;W#4&J*GWI&{jud34wP#Q(2vNq6CHte{)ydvPZ2a8|esyQcw$5HtX% zZ}I^^gD!A|t6lc$)vMqpp8qtwqV|mrQPt7;<9esxxX~-1s!6HZ`|KLc^7`SrJ-AxEkS z_?mP16%`fWM^dcXdR#BT?MvVcXU*5mgVk7V%Ey@cq=pU==q|7XEv+gF(!EINx85P# zprNK7@Nj&cD3uyc!Gq{*p${zvwUPuZYE%>Iuh1foLUAM6-ImS)e^xoC`z71A>5hO^ zM(w~a%wt}uo<&o8{AYa}zL>yHpgcP_=UJNYM1%p=Zr(e_(hp)Jp!#XC?(a$_qEN0? z_IxoV*?>rVt1U3`xJ_6hHIiqDIK=-)#ia5Ne-Tafe0G%Ra!(-#)bNaiy?iI}UsrCpjxOa5M^T~hj z=!m_2`}TVv_B?>Lo#J6z-Kmjt^{FV7W=tlhqGmcAqB!}9HA&q{e zt@uh%^cWAqOKX^Tt~_eI?oU{C^2Gkb+G+oybNi69bYvj(BtVRabxb+ z(&_JAy{G}w@bE4*s2;en`57~uXHk&l;5k)~0YK+W_Dh$-!A6bNT+E%E95lF(m6~n0 zzdrp092e)}WNp>n=W_TNUyLDw(G^gAH8!n{&r%UJj?rf+P+3<4Sq!vpI@HucYY+t0 zu=q@Jjpf}?*jdx6Dx5jl$EN(GzC^#aaGEkF%8#IL;uXm1ox68)Im6R)P}~<@+_>8- z@a-fVLT|(};gZMMpNP~VRy?}Ww;(@1=;_Zz4cH%{jcMoOs!yIJDoLt_G<91KY;+L=aL0@ z#J`6=%0D65^V-X#rlGk^9iiwd_AUm6iW#=u9lk1~qx0=ZPdK8Pd?6(it(XGptxFDr zltE+d6;1qxLBZ~~(aqEOq<`g}>h$Nri1cktqM-he!y0*%ml_I2y7pu|^=W%XkwTYwd!cEhCAmU3Sk4y-%R?iUZ3JED9hN z9FmsSZlZspMRd0%B?29%*a#&xbvQJ?wVQqnyVqd#E--gA7q{irZYHpo7;#^|{0j5{ zHUi276BS?$saCa}y+3g&uC~7Z0)-0fA;gfxAsqHRs1Oll5ga<+)XM&$SJox>-UA;o z2J-#;_oqHgZVrE*>YDQ*cx_;7n~(TGLmhPUO#1}orZ~_!@VbbPr|O%jb0d%sxFxeA zvqW5o9w_AqXi)FSaeqPB1W4h#cgI0mQ-tv2tR-`iDPol8>eL^hNNc~Surp>5d3Y|{ zXBmquKUKegg9;gw)hWvQ_l9Ql4PHsOpXU3n4#{@gYZNG}V#J~sqa%MrXt*fKc!_$& zPd|H2&*0y&PH}_{WEQ%Vpo&uUA56xfZA%=B)4p~~X&6)hOq)U2T mUMf3~Bt#GUzp^IZ&#>b6K6kq>rkzLNKV?NVg+e*wfd2t}7s)&T literal 0 HcmV?d00001 diff --git a/docs/ziegler_tuning.md b/docs/ziegler_tuning.md new file mode 100644 index 0000000..6215efb --- /dev/null +++ b/docs/ziegler_tuning.md @@ -0,0 +1,83 @@ +# PID Tuning Using Ziegler-Nicols + +This uses the Ziegler Nicols method to estimate values for the Kp/Ki/Kd PID control values. + +The method implemented here is taken from ["Ziegler–Nichols Tuning Method"](https://www.ias.ac.in/article/fulltext/reso/025/10/1385-1397) by Vishakha Vijay Patel + +One issue with Ziegler Nicols is that is a **heuristic**: it generally works quite well, but it might not be the optimal values. Further fiddling may be necessary. + +## Process Overview + +1. First of all, you will record a temperature profile for your kiln. +2. Next, we use those figures to estimate the parameters. + +## Step 1: Record Temperature Profie + +This must be done without any interference from the real PID control loop. To do so, run: + +``` +python kiln-tuner.py ziegler.csv +``` + +The above will drive your kiln to 400 and record the temperature profile to the file `zn.csv`. The file will look something like this: + +``` +time,temperature +4.025461912,45.5407078 +6.035358906,45.5407078 +8.045399904,45.5407078 +10.05544925,45.59087846 +... +``` + +## Step 2: Compute the PID parameters + +Once you have your zn.csv profile, run the following: + +``` +python zieglernicols.py zn.csv +``` + +The values will be output to stdout, for example: +``` +Kp: 3.853985144980333 1/Ki: 87.78173053095107 Kd: 325.9599328488931 +``` +(Note that the Ki value is already inverted ready for use in config.py) + +------ + +## Sanity checking the results + +If you run +``` +python zieglernicols.py zn.csv --showplot +``` + +It will display a plot of the parameters. It should look simular to this ![kiln-tuner-example.png](kiln-tuner-example.png) +(Note: you will need python's `pyplot` installed for this to work.) + +The smooth linear part of the chart is very important. If it is too short, try increasing the target temperature (see later). + +Note the red diagonal line: this **must** follow the smooth part of your chart closely. + +## My diagonal line isn't right + +You might need to adjust the line parameters to make it fit your data properly. You can do this as follows: + +``` +python zieglernicols.py zn.csv --tangentdivisor 8 +``` + +`tangentdivisor` modifies which parts of the profile is used to calculate the line. + +It is a floating point number >= 2; If necessary, try varying it till you get a better fit. + +## Changing the target temperature + +By default it is 400. You can change this as follows: + +``` +python kiln-tuner.py zn.csv --targettemp 500 +``` + +(where the target temperature has been changed to 500) diff --git a/zieglernicols.py b/zieglernicols.py index 913fbea..82abece 100644 --- a/zieglernicols.py +++ b/zieglernicols.py @@ -90,7 +90,7 @@ def calculate(filename, tangentdivisor, showplot): Kd = Kp * Td # outut to the user - print(Kp, 1 / Ki, Kd) + print(f"Kp: {Kp} 1/Ki: {1/ Ki}, Kd: {Kd}") if showplot: plot(xdata, ydata,