Fórum témák

» Több friss téma
Fórum » PIC PID library
 
Témaindító: kyrk, idő: Aug 6, 2008
Lapozás: OK   5 / 6
(#) watt válasza forrp hozzászólására (») Dec 28, 2013 /
 
Vannak olyan folyamatok, amiket csak a beavatkozó egység drasztikus használatával lehet szabályozni. Ezen PLC sem segít (egyébként a PLC-ben is valamilyen PID dolgozik).
(#) kit6263 hozzászólása Jan 2, 2014 /
 
Üdv Watt !
Látom nagyon otthon vagy a témában.
Szeretnék csinálni egy hőfokszabályozót fűtőlaphoz. Nagy tömeg nagy időállandó, ráadásul még néha van egy jókora hőelvonás is a nyugalmi állapothoz képest. Jó lenne 1-2 fokon stabilizálni.
Kitúrtam pár PID példa programot.
A "pid_controller_calculus_v320" alapján állítottam be a paramétereket...sörfőző...nagy tömeg.
Sajnos a különböző rutinok nagyon mást adnak...van ami nagyon durva.
A calculus-ból csak a Takahashi-faragtam ki. Ez nem variál szűrővel, de pid változást ad.
Nekem ez a matek már nagyon gáz vagy 30 éve tanultam, sajnos nem igazán látom át.
Ránézhetnél a kódra. Nagyon érdekelne a véleményed, hogy melyiket javaslod.
Köszi

_main.c
    
(#) jym válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Üdv!

Nem néztem a programot, de elmélet frissítéshez ezt ajánlom:

Szabályozás technika

Először is le kell mérni a "szakaszt". Ha mondjuk 24V-os a fűtési feszültség, akkor először megvárod amíg a fűtőlap felveszi a környezet hőmérsékletét, aztán ráadod a 24V-ot, méred a fűtőlapot, aztán ezt az egészet valamilyen SW-es megoldással folyamatosan rögzíted az értékeket. Valószínűnek tartom, hogy ez egy egytárolós, holtidős rendszer lesz, tehát az elején lesz egy holtidő, aztán exponenciálisan növekszik a fűtőlap hőmérséklete, és elér valamilyen max. értéket. Amikor látod, hogy már tovább nem nagyon megy, akkor leállítod az adatgyűjtést, identifikálod a szakaszt (matlab-al vagy kézi papír/ceruza módszerrel), és mondjuk az 5-ik előadásban látottak alapján kiszámolod a PI paramétereket hozzá (ebben az előadásban PI szabályozót tervez hozzá, és nem PID-t).

Ha jól emlékszem, akkor 60 fokos fázistartalékra:

Ha a szakasz: (k / (1 + Tp1*s)) * e ^ (-Th*s), akkor

Ap = (PI/6 * Tp1) / (k * Th), ahol PI = 3.1415, Tp1 = az azonosított szakasz időállandója, k = az azonosított szakasz számlálója, Th = holtidő. Tehát ez az Ap lesz a P, a Tp1 pedig lesz az I sec-ben (a zérus/pólus kiejtés miatt így kiejti Tp1-et).

Imi.
(#) kit6263 válasza jym hozzászólására (») Jan 2, 2014 /
 
Köszi, de más a gondom !

Ha Z-N vagy egyébb módszerrel meghatározom a paraméterket...az idáig egyértelmű..
Most csak kivettem a calculus sörfőzőből.
Sajnos ahány PID rutin annyiféle eredmény !!!!:
Mondjuk a NET mindent elbír.
Pl a Microcontroller Based Temperature Monitoring & Control, Elsevier (2002)
Szöveges algoritmus :
BEGIN
DO FOREVER
r(kT) // Get set point
w(kT) // Get system output
e(kT) = r(kT) - w(kT) // Calculate error
p(kT) = be(kT) + p(kT-T) // Calculate I term
q(kT) = cw(kT) - cw(kT-T) // Calculate D term

u(kT) = p(kT) + aw(kT) + q(kT) // Calculate PID output

Send control to actuator

p(kT-T) = p(kT) // Save variables
w(kT-T) = w(kT)

Wait for next sample
ENDDO
END

Kód:
rkt=set_point;
/* Calculate error */
ekt=rkt-ykt;
/* Calculate I term */
pkt=b*ekt+pkt_l;
/* Calculate D term */
qkt=c*(ekt-ekt_1);
/* Calculate PID output */
ukt=a*ekt+pkt+qkt;

A D résznél az elméletben a mért értékekkel a kódban a hibával számol !
Jó kis könyv...lehet rá alapozni !!!
Biztos nagy gond lett volna azonos elnevezéseket használni hol v hol w...ez van ingyen.

Ha már belevágok a lehető legjobbat szeretném.
Szóval tovább keresem a megoldást...
Most ezt próbálom átfaragni C-re...de előbb próbálom megérteni:
http://bestune.50megs.com/piddesign.htm

SSR kapcsolgat. PWM alap 10 msec. Most 1..100 ig tudom állítani ...az 1 sec ciklusidő.
Lehet, hogy 200 lesz akkor 2 sec, nem tudom hogy a finomabb PWM, vagy a rövidebb ciklus válik be.
Most van elektronikám egy korábbi projectből 46K80 PIC 12 bit ADC-vel.
A fűtőlap még nincs nálam.
A hozzászólás módosítva: Jan 2, 2014
(#) jym válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Üdv!

PLC-ben ezt használom PI-re (PID-et szinte soha nem használok):

  1. FUNCTION_BLOCK PIW
  2.  
  3. (* deklaráció *)
  4. VAR_INPUT
  5.         IN : REAL;
  6.         KP : REAL := 1.0;
  7.         KI : REAL := 1.0;
  8.         LIM_L : REAL := -1.0E38;
  9.         LIM_H : REAL := 1.0E38;
  10.         RST : BOOL;
  11. END_VAR
  12. VAR_OUTPUT
  13.         Y : REAL;
  14.         LIM : BOOL;
  15. END_VAR
  16. VAR
  17.         init: BOOL;
  18.         tx: DWORD;
  19.         tc : REAL;
  20.         t_last: DWORD;
  21.         in_last : REAL;
  22.         i: REAL;
  23.         p: REAL;
  24. END_VAR
  25.  
  26. (* program *)
  27. IF NOT init OR RST THEN
  28.         init := TRUE;
  29.         in_last := in;
  30.         t_last := T_PLC_US();
  31.         i := 0.0;
  32.         tc := 0.0;
  33. ELSE
  34.         tx := T_PLC_US();
  35.         tc := DWORD_TO_REAL(tx - t_last);
  36.         t_last := tx;
  37.  
  38.         p := KP * IN;
  39.  
  40.         i := (IN + in_last) * 5.0E-7 * KI * tc + i;
  41.         in_last := IN;
  42.  
  43.         Y := p + i;
  44.  
  45.         IF Y >= LIM_H THEN
  46.                 Y := LIM_H;
  47.                 IF ki <> 0.0 THEN
  48.                         i := LIM_H - p;
  49.                 ELSE
  50.                         i := 0.0;
  51.                 END_IF;
  52.                 LIM := TRUE;
  53.         ELSIF Y <= LIM_L THEN
  54.                 Y := LIM_L;
  55.                 IF ki <> 0.0 THEN
  56.                         i := LIM_L - p;
  57.                 ELSE
  58.                         i := 0.0;
  59.                 END_IF;
  60.                 LIM := TRUE;
  61.         ELSE
  62.                 LIM := FALSE;
  63.         END_IF;
  64. END_IF;


Forrás

A
Idézet:
„T_PLC_US”
egy olyan függvény, ami mikrosec-ben visszaadja a bekapcsolás óta eltelt időt. Az
Idézet:
„IN”
bemenetre a Setpoint-Actual-t kell bevinni.
A
Idézet:
„KI”
bemenetre pedig 1/Ti-t kell bevinni.

Imi.
(#) watt válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Mielőtt nagyon belebonyolódnál a PID-ek matematikájába, megvizsgáltad, hogy a főzőlapod képes-e egyáltalán a feladatra? Mert +-2C egy ilyen lomha vasdarabtól úgy, hogy a folyamat azzal van terhelve, hogy pl. ráteszel egy másik hideg vasdarabot, fizikai lehetetlenség! Probléma a nagy hőellenállás és a mérési pont is problémás valószínűleg. Ha ezeket megoldod valahogy(másik fűtőegység), akkor jön a terheléskor szükséges teljesítmény adag előállításának problémája.
Ezután jön a képbe, hogy milyen PID algoritmust használsz, ami egyébként nem egy nagy durranás, nincs olyan, hogy jobb, meg nem jobb, ha jó, akkor mind ugyanazon az elven működik. A hibás képleteket a neten, ne vegyük figyelembe.
P tag erősítés(arányos szabályzás):
Y_P=(SP-CV)*P
I tag korrekció:
Y_I=Y_I+(SP-CV)/I
D tag "ellenkormányzás": (Cve=előző hőfok)
Y_D=(Cve-CV)/D
Beavatkozó jel:
Y=Y_P+Y_I+Y_D
Az arányokat kell belőni egy szabályzó körnél az alap képleteken és PID együtthatókat jól meghatározni.
De a szabályozandó egység fizikai korlátain túl semmilyen szabályzó algoritmus nem képes túllépni!
(#) jym válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
PID-re:

  1. (* DER segéd *)
  2. FUNCTION_BLOCK DER
  3. VAR_INPUT
  4.         in : REAL;
  5.         K : REAL := 1.0;
  6.         run : BOOL := TRUE;
  7. END_VAR
  8. VAR_OUTPUT
  9.         out : REAL;
  10. END_VAR
  11. VAR
  12.         old: REAL;
  13.         tx: DWORD;
  14.         last: DWORD;
  15.         init: BOOL;
  16.         tc: REAL;
  17. END_VAR
  18.  
  19. tx := T_PLC_US();
  20. tc := DWORD_TO_REAL(tx - last);
  21. last := tx;
  22.  
  23. IF NOT init THEN
  24.         init := TRUE;
  25.         old := in;
  26. ELSIF run AND tc > 0.0 THEN
  27.         out := (in - old) / tc * 1000000.0 * K;
  28.         old := in;
  29. ELSE
  30.         out := 0.0;
  31. END_IF;
  32.  
  33. (* PI segéd *)
  34. FUNCTION_BLOCK PIW
  35. VAR_INPUT
  36.         IN : REAL;
  37.         KP : REAL := 1.0;
  38.         KI : REAL := 1.0;
  39.         LIM_L : REAL := -1.0E38;
  40.         LIM_H : REAL := 1.0E38;
  41.         RST : BOOL;
  42. END_VAR
  43. VAR_OUTPUT
  44.         Y : REAL;
  45.         LIM : BOOL;
  46. END_VAR
  47. VAR
  48.         init: BOOL;
  49.         tx: DWORD;
  50.         tc : REAL;
  51.         t_last: DWORD;
  52.         in_last : REAL;
  53.         i: REAL;
  54.         p: REAL;
  55. END_VAR
  56.  
  57. IF NOT init OR RST THEN
  58.         init := TRUE;
  59.         in_last := in;
  60.         t_last := T_PLC_US();
  61.         i := 0.0;
  62.         tc := 0.0;
  63. ELSE
  64.         tx := T_PLC_US();
  65.         tc := DWORD_TO_REAL(tx - t_last);
  66.         t_last := tx;
  67.  
  68.         p := KP * IN;
  69.  
  70.         i := (IN + in_last) * 5.0E-7 * KI * tc + i;
  71.         in_last := IN;
  72.  
  73.         Y := p + i;
  74.  
  75.         IF Y >= LIM_H THEN
  76.                 Y := LIM_H;
  77.                 IF ki <> 0.0 THEN
  78.                         i := LIM_H - p;
  79.                 ELSE
  80.                         i := 0.0;
  81.                 END_IF;
  82.                 LIM := TRUE;
  83.         ELSIF Y <= LIM_L THEN
  84.                 Y := LIM_L;
  85.                 IF ki <> 0.0 THEN
  86.                         i := LIM_L - p;
  87.                 ELSE
  88.                         i := 0.0;
  89.                 END_IF;
  90.                 LIM := TRUE;
  91.         ELSE
  92.                 LIM := FALSE;
  93.         END_IF;
  94. END_IF;
  95.  
  96. (* PID *)
  97. FUNCTION_BLOCK PIDW
  98. VAR_INPUT
  99.         IN : REAL;
  100.         KP : REAL := 1.0;
  101.         TI : REAL := 1.0;
  102.         TD : REAL := 1.0;
  103.         LIM_L : REAL := -1.0E38;
  104.         LIM_H : REAL := 1.0E38;
  105.         RST : BOOL;
  106. END_VAR
  107. VAR_OUTPUT
  108.         Y : REAL;
  109.         LIM : BOOL;
  110. END_VAR
  111. VAR
  112.         piwl : PIW;
  113.         diff : DER;
  114. END_VAR
  115.  
  116. IF rst THEN
  117.         piwl(rst := TRUE);
  118.         piwl.RST := FALSE;
  119. ELSE
  120.         IF TI = 0.0 THEN
  121.                 piwl(in := IN * KP, KP := 1.0, KI := 0.0, LIM_L := LIM_L, LIM_H := LIM_H);
  122.         ELSE
  123.                 piwl(in := IN * KP, KP := 1.0, KI := 1.0 / TI, LIM_L := LIM_L, LIM_H := LIM_H);
  124.         END_IF;
  125.  
  126.         diff(IN := IN, K := KP * TD);
  127.         Y := piwl.Y + diff.out;
  128.  
  129.         IF Y < LIM_L THEN
  130.                 LIM := TRUE;
  131.                 Y := LIM_L;
  132.         ELSIF Y > LIM_H THEN
  133.                 LIM := TRUE;
  134.                 Y := LIM_H;
  135.         ELSE
  136.                 LIM := FALSE;
  137.         END_IF;
  138. END_IF;


A "PIDW"-t kell használni PID-re, a másik kettő csak segédfüggvény.

Imi.
(#) jym válasza watt hozzászólására (») Jan 2, 2014 /
 
Üdv!

Abban teljesen egyetértek, hogy ahány különböző "terhelés" a főzőlapon, annyi különböző szakasz lesz, ezt jó közelítéssel szerintem egy PID paraméter sereggel (5-10, nem tudom mennyi) lehetne megoldani. Ha lesz főzőlapja, akkor úgyis leméri terhelés nélkül, ilyen-olyan terheléssel, lesz X db szakasz, aztán utána lehet gondolkodni.

Imi.
(#) watt válasza jym hozzászólására (») Jan 2, 2014 /
 
Neked is azt tudom mondani, hogy ha a főzőlap fizikailag képes tartani a felmerülő igényeket, akkor lehet szabályozni, különben nem.
(#) kit6263 hozzászólása Jan 2, 2014 /
 
Nagy a lap, terhelés nem annyira vészes, inkább a holtidő a gáz.

set_point 65
pid start 50

watt | BestTune | Saját | m_point

50.00 | 50.00 | 50.00 | 64,4
276.21 | 155.82 | 189.92 | 64,5
276.21 | 155.82 | 189.92 | 64,6
257.80 | 200.7 | 223.43 | 64,7
248.41 | 242.92 | 139.25 | 64,8
239.21 | 256.74 | 83.66 | 64,9
230.00 | 247.53 | 28.64 | 65

Meghívtam a PID rutinokat egymásután, közben növeltem a mért értéket 0.1 fokkal.
Elég lehangoló az eredmény.
Ahogy közeledek a set_point-hoz van amelyik még több szuflát ad.
Valamit biztosan nagyon elrontok...de mit ?
(#) watt válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Az eredmény inkább semmitmondó, mint lehangoló. Azt tudni kell, hogy az eltérő PID megoldásokhoz eltérő PID paraméterek is tartoznak. Erre értettem, hogy az arányokat be kell állítani a képletben az alkalmazáshoz. A képlet csak egy összefüggést ad meg, ezt illeszteni kell. Emellett a valós körülmények nem azonosak a teszteddel. A tagokat külön kellene vizsgálni és az I tagot a folyamat időállandójához illeszteni és a tesztet ilyen időállandóval futtatni.
A hozzászólás módosítva: Jan 2, 2014
(#) jym válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Üdv!

A _main_kit.c-ben így számolod az I tagot:

Idézet:
„pi = pid_i * ( err + err_1 )”


Ez teljesen rossz. Hol a halmozódás ??? Az I tagnak összegződnie kell, tehát a korábbi I értékéhez hozzá kell adni az újonnan számoltat (olyan, mint ha területet számolnánk). Ezen kívül azt sem látom, hogy 2 pid_calc függvényhívás között néznéd, hogy mennyi idő telt el.

Valahogy így kellene:

  1. pi = pi + (err + err_1)/2 * pid_i * tc; /* ahol a tc a 2 hívás közötti eltelt idő SEC-ben(persze a tc is egy double lesz, és előtte ki kell számolni) */


Ezen kívül a pid_calc függvényben a pi változód nem static !!! Ennek static-nak kell lennie, két hívás között értékét meg kell őriznie, és 0-val kell indulnia.

Azért kell két függvényhívás között időt mérni, mert semmi nem garantálja, hogy a programodban mindig X usec-enként hívod meg. Nézd meg a korábbi példát, amit írtam.

Imi.
A hozzászólás módosítva: Jan 2, 2014
(#) kit6263 válasza jym hozzászólására (») Jan 2, 2014 /
 
Köszi szépen !!!! Kijavítottam ! Ez működik legjobban !
50.00
97.93
77.27
56.61
35.66
14.89
-5.77
Ez már szímpatikusabb !
A PIC-ben minden 1 sec-ben hívódik meg. A bemeneteket csak meghasaltam. Feltételezve, hogy fűt a rendszer és folyamatosan nő a hő. Most szépen csökken a kimenet és a végén látszik, hogy már hűteni akar !
Ez már jónak tűnik induláshoz.
(#) watt válasza kit6263 hozzászólására (») Jan 2, 2014 /
 
Ezt bármelyikkel meg lehet oldani, csak jól kell paraméterezni...
(#) kit6263 hozzászólása Jan 5, 2014 /
 
Próbáltam átrágni magam a pid_controller_calculus_v320 -on. A hangolásnál sehogy sem értettem a tau kiszámítását. Túrtam a NET-et és ezt találtam. Messze a legjobb amit én ki tudtam kukázni a szemétdombból. Rengetek cucc van a témában, de gyakorlatban használható szinte semmi.
Ebből kiderült, hogy nem írta bele, hogy 1.5-el is kell szorozni. Szerintem máshol is vérzik, mert a számításoknál keveri a két mérést. A holtidőt és a meredekséget a 100%-os fűtésből veszi, a taut meg a 20%-osból. Persze lehet hogy ez a helyes !!!! Nem tudja valaki ????
Csinálok egy xls-t, még nincs teljesen kész, hiányzik pár képlet.....majd feltöltöm.
Remélem nem hiába dolgozok és a kapott értékekkel jól fog működni az leírt PID C kód.
(#) kit6263 hozzászólása Jan 5, 2014 /
 
Van egy könyv ! Sajnos fizetős, de bele lehet nézni !
Próbáltam letölteni...de csak az előző kiadást találtam meg. 27 Mega
A 3. kiadást kell kukkolni !
books.google.hu keresés : Digital Control and State Variable methods by M Gopal 3.62
A 145. oldalon van a 3.62 3.63 képlet.
Ezt kéne egy mezei C-re lefordítani !!!
Megpróbálom, de biztosan van akinek ez jobban megy !!!!
(#) watt válasza kit6263 hozzászólására (») Jan 5, 2014 /
 
Nekem inkább olyan érzésem van, hogy azt kéne megérteni, hogyan működik a PID, mit lehet tőle elvárni és hogyan kell paraméterezni, hogy jól működjön(nem tudom, ezzel hogy állsz!?). A dolog sokkal egyszerűbb, mint aminek hiszed és amilyen feneket kerítenek neki egyes irodalmak. Ha megvan az alap, akkor egyes alkalmazások egyedi tulajdonságai alapján lehet még egyéb függvényeket állítani, de az már túlmutat a PID-en, egyedi igényekhez illeszkedik és ott jó kiegészítő lehet. De fel kell ismerni meddig terjed a PID és akkor látható, mivel érdemes kiegészíteni, esetleg módosítani. Én a határértékeket tartom a leghatékonyabb kiegészítőknek, amik korlátozzák az I tagot, valamint kaszkád esetén az a kiszámolt alapjelek min-max értékét. De ez is alkalmazásfüggő, van amikor nincs rá szükség.
(#) jym válasza kit6263 hozzászólására (») Jan 5, 2014 /
 
Üdv!

Amennyire én tudom, a holtidő (7-2.6a ábra) az origó-tól addig terjed, amíg az érintő nem metszi a t tengelyt. A tau (időállandó) pedig ettől a ponttól az érintő másik pontjának (ahol eléri a max. értéket) t tengelyre eső vetületéig terjed. Nem értem, hogy miért írja a doksi, hogy ez miért "nem nagyon" reprodukálható (nyilván arra gondol, hogy nehéz lemérni).

A 7-2.6b és a 7-2.6c ábrán máshogy méri a tau-t, de ott is tudnia kell, hogy mekkora értéket ér el végül a c(t), különben nem tudja, hogy mekkora a 28 % és 63 %. így nem látom, hogy ezek miért lennének egyszerűbbek.

Tudtommal a 7-2.6a ábrán látható módszer a "hivatalos". A Matlab ident-je is ez alapján azonosítja a szakaszt. A magyar szakirodalomban, amit találtam, ott is ezt a módszert használják.

Amennyiben ezzel a módszerrel azonosítottad a szakaszt, akkor amit már korábban is írtam:

Ap = (PI/6 * tau) / (k * t0), ahol PI = 3.1415, tau = az azonosított szakasz időállandója, k = az azonosított szakasz számlálója (ez a delta c(s), vagyis ahová_értem - ahonnan_indultam), t0 = holtidő. Tehát ez az Ap lesz a P, a "tau" pedig lesz az I sec-ben, és ilyen szakaszhoz szerintem nem kell PID, elég a PI is, a fűtési rendszereket általában lehet ilyen szakasszal közelíteni.

Imi.

7-2.6a.png
    
(#) kit6263 hozzászólása Jan 5, 2014 /
 
Sajnos nincs semmi tapasztalatom PID-el, már 30 éve tanultam. Sok PIC-e kütyüt csináltam már, de ez az első szabályzós projektem. Mindenesetre azért aggódok, mert 200 fok környékén kell 1 fokra tartani a lapot. PLC-vel kb fél évet görcsöltek vele, míg elfogadható lett.
Már lassan azért újra megtanulom a PID lényegét, de amit olvasgatok róla az kicsit elborzaszt. Az egyszerű algoritmusoknak úgy olvasom több hibája is van. Attól tartok nehogy egyszer csak megbolonduljon menet közben.
A hangolásnak is a módszere a sörfőzős doksiban elég durván eltér egymástól.
Attól félek, hogy hiába keresem meg az értékeket, mert a különböző PID algoritmusok másként reagálnak rá. Amit feltettem doksit az elég jól leírja, hogy kell meghasalni a paramétereket.
Majd holnap meglátom....
Program készen van. Soros porton küldöm az adatokat a PC-re. Egyenlőre Excel-el megnézem, de van egy SerialChart nevű free progi, ami jónak tűnik.
A hozzászólás módosítva: Jan 5, 2014
(#) jym válasza kit6263 hozzászólására (») Jan 5, 2014 /
 
Üdv!

Ha lesz mért adat excel-ben, akkor tedd ide fel, és megnézzük.

Imi.
(#) watt válasza kit6263 hozzászólására (») Jan 5, 2014 /
 
Álj neki kísérletezni és ráérzel. Több mint 25éve állítok be PID köröket, soha nem számoltam még képlettel...
(#) kit6263 válasza watt hozzászólására (») Jan 6, 2014 /
 
Valószínűleg igazad van...most, hogy kicsit tanulgattam.
Csatolok egy XLSt. Ez tökéletesen behangolható. Először PI utánna a D.
Kerestem hőmérséklet kifejezetten szimulátort, de nem találtam.
Mondjuk ha 10 perceket kell várni akkor kicsit gáz a próbálgatás, azért szeretnék valami kiindulást.
Ma nem volt időm, de felteszem amit eddig csináltam. Az ITAE nincs kész.
Szeretem a megalapozott dolgokat...bejönnek.
Felteszek egy XLS-t, abban egy korábbi projekt-ben NTC hőmérés volt, ott csak állásos kapcsolgatás volt. A gyakorlat tökéletesen hozta az elméletet. Hátha kell valakinek....
A hozzászólás módosítva: Jan 6, 2014
(#) kit6263 hozzászólása Jan 6, 2014 /
 

Haleluja !!!!
Bővebben: Link
Hogy miért nem találtam ezt meg eddig .....
Ebben minden benne van és nagyon érthetően, az igazi kód az Cpp, de nagyon jól van megírva.
Ez legalább klasszikus PID és látom mi történik.

Link javítva.
Már csak a link gombot kellene felfedezned.
-moderátor-
A hozzászólás módosítva: Jan 6, 2014
(#) watt válasza kit6263 hozzászólására (») Jan 6, 2014 /
 
Ez ugyanaz, amit én írtam neked...
(#) kit6263 válasza watt hozzászólására (») Jan 6, 2014 /
 
Nem egészen ugyanaz !!!!

A kód:
Error = mySetpoint - Input;
// P
KTerm = kp * Error;
// I
ITerm += ( ki * Error );
double dInput = ( Input - lastInput );
// D
DTerm = kd * dInput;
// Compute PID Output
myOutput = KTerm + ITerm - DTerm;

Amit Te írtál :
P tag erősítés(arányos szabályzás):
Y_P=(SP-CV)*P
I tag korrekció:
Y_I=Y_I+(SP-CV)/I
D tag "ellenkormányzás": (Cve=előző hőfok)
Y_D=(Cve-CV)/D
Beavatkozó jel:
Y=Y_P+Y_I+Y_D

A kódban az I tag szorozva van Nálad osztva.
A D szintén.
Az összegzésnél Te mindent összeadsz a kódban D kivonva van.

Ezért kaparom a falat, hogy minden kód más.
Hiába számítom ki a hangolást, ha ott Ti re 100 jön ki és az adott algoritmusba 1.5 kell.
(#) watt válasza kit6263 hozzászólására (») Jan 7, 2014 /
 
Hidd el ugyanaz! (pl. 10/10=1, vagy 10*0,1=1 )
A Dtagot azért vonjá ki, mert a képlet pozitív eredményt ad, az enyém negatívot, de ettől eltekintve jellegében ugyanazt az eredményt adja.
Írtam, hogy ahány megoldás, annyi együttható érték. Ezeket kell az alkalmazáshoz illeszteni. Nem tudok róla és talán nincs is szabvány erre. A módszer azonos, a kivitelezés eltérhet, de a végeredmény ugyanaz, ha jól állítod be.
A hozzászólás módosítva: Jan 7, 2014
(#) kit6263 hozzászólása Jan 7, 2014 /
 
Nem akarlak zaklatni, de még ez is homály:

ITerm+= (ki * error);
if(ITerm > outMax) ITerm= outMax;
else if(ITerm < outMin) ITerm= outMin;

Ha a hiba negativ vagyis feljebb vagyok mint a setpoint, akkor iTerm csökken és ha kicsit negatívvá vállik, ami ugye még alacsonyabbra veszi a kimenetet. Ezt itt lekorlátozza, de miért kell mikor később a kimenetnél is határol.

if(output > outMax) output = outMax;
else if(output < outMin) output = outMin;

Ezek szerint az I hatás nem érvényesül ha feljebb vagyok !
Ez nem csökkenti a szabályozás sebességét ?
Jól értelmezem, ha csak a PI-t nézem ?
Ez olyan mintha adott sebességen felérnék a hegy tetejére, nyomom a gázt, jön a lejtő és nem figyelem azt hogy milyen meredek a lejtő, csak azt hogy mennyivel létem túl a sebességet. Józan ész szerint ha lejtő nagy akkor nagyobb fékezés kell.
Mindenesetre bevezetek egy itermMax és egy itermMin értéket ami esetleg eltérhet az outMax, outMin -től.

Remélem nem gond, hogy ennyit kérdezek....egyébként köszönöm mindenki türelmét !
(#) watt válasza kit6263 hozzászólására (») Jan 7, 2014 /
 
Persze, hogy nem gond...
Az Y_I összetevőt azért éremes korlátozni, mert vannak bizonyos állapotok, amikor valami ok miatt nem tud a PV(CV) beállni. Ilyen lehet például, amikor kinyitod a sütő ajtaját. Ilyen esetben a hiba nagy, ezért az Y_I rohamosan halmozódna, ami akkora értékhez vezethetne rövid idő alatt, ami nagyon nehezen találna vissza a szükséges értékre, miután az ajtó becsukódik.
Az Y_I értékét úgy kell korlátozni, hogy a maximális Y értéknél nagyobb értéket nem tároljon be, mert minek! Így az Y_I gyorsan be tud állni a folyamat normalizálódása után.
Az Y értékét más okból korátozzuk. pl. túl nagyra sikeredett a fűtőbetét, vagy tudjuk, hogy 30%-nál kisebb érték teszemazt leállítaná a ventilátor forgását, ami a motornak nem tenne túl jót. Az Y_Imax csak idomul az Ymax-hoz, de más az ok a korlátozásra, mint láthatod.
A lejtőt pedig a D taggal kellene lekezelni, az figyeli ugyebár a sebességet, a többi csak az eltérés irányát és nagyságát(P), illetve az eltérés időtartama alatt korrigál a hiba arányában (I).
A hozzászólás módosítva: Jan 7, 2014
(#) kit6263 hozzászólása Jan 7, 2014 /
 
Az I taggal van bajom...túl sok hibát gyűjt össze és túllövésbe vezet. Most beraktam az ITerm korlátozást, ami különböző lehet lehet mint az output és lehet negatív, ha minuszba megy akkor az a kimenetet az Output limit úgyis 0-ra teszi. Arra gondoltam, hogy az I értékeket nem folyamatosan összegzem, hanem egy gyűrűs modjuk 8 elemű bufferba rakom folyamatosan. És a számitáskor ezt az utolsó nyolc adatot adom össze.
Sebesség nem gond.
Ez ugyan nyolc lebegőpontos összeadás és egy osztás , de nem tűnik gondnak. PIC k80-as proci 16Mhz-en 1 msec alatt csinálja meg a teljes lebegőpontos PID-et és felhózhatom akár 64Mz-re is.
És ez végül jobb lesz mert ADC érték az egész.
(#) watt válasza kit6263 hozzászólására (») Jan 7, 2014 /
 
Erre semmi szükség (és semmi köze a PID-hez). A D paramétert kell jól beállítani, hogy ne legyen túl gyors a felfutás, ne lőjjön túl. A maximális felfűtési sebességet, ahol nincs túllövés úgy is az eszköz határozza meg. Ha nem akarsz túllövést a felfűtéskor, akkor idomulnod kell a fizikához! Ha megengedett, akkor gyorsabban beáll kis túllövés mellett és utána már szépen tarthatja a kívánt hőfokot. Másik megoldás D nélkül(PI), hogy programozottan emeled az SP-t. Ilyenkor a túllövés is kicsi, bár itt is csak akkor, ha a felfűtési sebesség lassabb, mint amit az eszköz túllövés nélkül képes megoldani. A hőfokot alapvetően a P-nek kell tartania, azt kell jól meghatározni. Kritikus esetekben több PID tagot lehet használni, hőfoktartományoktól függően, de ezt beállítani nem kis mutavány! Az I tag csak akkor kell, hogy beavatkozzon, ha a megváltozott terhelés miatt más "munkapont" szükséges. Nem szabad, hogy az I cibálja az Y jelet!
A hozzászólás módosítva: Jan 7, 2014
Következő: »»   5 / 6
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem