Ik wil een poging doen om een PID temperatuur regelaar te maken met een PIC.
Als PIC gebruik ik nu een PIC16F876A (maar dat kan/mag een ander type worden, bijvoorbeeld de 18F).
De temperatuur wordt gemeten door een thermokoppel (0...1024 grad.).
Deze temperatuur wordt weergegeven op een LCD display.
Via een Solid-state relais wordt een verwarming aangestuurd.
Ik ben natuurlijk al druk aan het zoeken.
Hulp/info is zeer welkom...
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Maak em traaaag, je verwarmingselement kan toch niet mee. Een PWM cyclus van 5 minuten is snel genoeg.
De D-actie heb je trouwens niet nodig, gewoon PI is voldoende (afhankelijk van het verschil tussen gewenste en gemeten temp aanpassen, eventueel als je er dicht bij bent em nog veel trager laten aanpassen, klaar).
Langzaam wordt met de gebruikte test opstelling geen succes.
Het is een verwarmings element (175 watt) in een klein Aluminium blokje, met daarop de thermokoppel.
Dus een snelle verwarming.
[Bericht gewijzigd door MMSoft op ]
Dat is ook de bedoeling.
Ik dacht dat een PID regeling altijd zelf lerend is.
[Bericht gewijzigd door MMSoft op ]
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Op 22 september 2006 17:45:26 schreef MMSoft:
Dat is ook de bedoeling.
Ik dacht dat een PID regeling altijd zelf lerend is.
PID is een teruggekoppeld systeem, waarbij je je proces (verwarmingselement op klein blokje blijkbaar) zo aanpast dat het sneller en nauwkeuriger werkt. Door de opzet is een fout in het proces (door verloop van weerstanden, andere omgevingstemperatuur,...) geen probleem, maar zelflerend is hij niet.
Op een warme dag zal ie bijvoorbeeld minder fel moeten opwarmen dan een koude dag, dat kun je doen door je PID niet op het nippertje van zijn kunnen te zetten (zodat ie het snelst opwarmt), want dan zal bij iets te grote variatie het systeem beginnen oscilleren en dergerlijke. Als je em zelflerend maakt, moet ie niet alleen teruggekoppeld zijn (dus de temperatuur meten), maar ook nog rekening houden met wat hij daartoe heeft moeten doen. Door em zelflerend te maken zal ie zo zelf de ideale instelling bepalen, moet je dus niet wat snelheid afgeven om em stabiel te houden.
Ik dacht dat bij zelflerendheid vaak "fuzzy logic" werd gebruikt, bij het kiezen van de juiste versnelling van een automatische versnellingsbak wordt dit gebruikt. Je kan niet gewoon zeggen "tussen toerental X en Y in 2e versnelling", hij moet rekening houden met hoe warm de motor is (meer of minder kracht geleverd), is het bergop/bergaf, ben je aan het versnellen of vertragen, is de auto volgeladen met een aanhangwagen, of leeg,...
Tip: in jou geval zou ik de regeling "assymetrisch" maken, waarmee ik wil zeggen dat ie een voorkeur moet hebben om frisser te zijn dan de gewenste temperatuur, want het opwarmen kan erg snel gebeuren (is gemakkelijk té warm), maar het afkoelen zal heel wat trager zijn (in vaktermen: geen overshoot).
Op 22 september 2006 18:17:41 schreef Videomodulator:
...Ik dacht dat bij zelflerendheid vaak "fuzzy logic" werd gebruikt...
klopt. Soms alleen door in de uitgangswaarde in te grijpen, soms door de PID waardes aan te passen en soms beiden.
Fuzzy logic is vooral erg Japans.
Op 22 september 2006 17:12:22 schreef MMSoft:
Ik ben natuurlijk al druk aan het zoeken.
Hulp/info is zeer welkom...
Zou je iets specifieker kunnen zijn:
Wil je hulp/info over hoe je dit elektrisch aan elkaar moet bakken?
Of wil je hulp/info over hoe je dit het beste kunt regelen (wat ik gok)?
-> dan is het belangrijk dat je meer info geeft over je regel-probleem(blokje in dit geval):
- Hoe ziet het eruit, (gewoon maten dus en misschien foto): nodig om een model op te stellen en/of na te gaan welke strategie geschikt is.
- Wat is je doel ermee wat heb je ermee voor ogen: zo snel mogelijk, zo nauwkeurig mogelijke of misschien zo energie bewust mogelijk, welk temperatuur bereik.
[Bericht gewijzigd door JoVi op ]
De opzet is het leren programmeren van een PI(D) regeling.
De testopstelling is alleen voor het testen van de PI(D) regeling.
Het is de bedoeling dat deze regeling later ook gebruikt kan worden voor een 'langzaam' proces.
Edit:
Hierbij een stuk code uit een PIC programma dat ik op internet heb gevonden.
SOLLW EQU 0x47 ;Sollwert
STELLG EQU 0x48 ;Stellgroesse
ABW EQU 0x49 ;Regelabweichung, aktuell
ZEIT EQU 0x4A ;Faktor fuer Abtastzeit (Basiszeit 0,1 s)
ZAEHL1 EQU 0x4C ;
OGRW EQU 0x4D ;Oberer Grenzwert
UGRW EQU 0x4E ;Unterer Grenzwert
AHI EQU 0x53 ;Faktor A, high
ALO EQU 0x54 ;Faktor A, low
BLO EQU 0x55 ;Faktor B
EEPROM EQU 0x59 ;fuer Datentransfer zum/vom EEPROM
DATEIN EQU 0x5A ;wird ins EEPROM gelesen
UHI EQU 0x5E ;Zwischenspeicher f. STELLG
UMI EQU 0x5F ; "
ULO EQU 0x60 ; "
ABW0 EQU 0x63 ;zugeh. Abweichung
ABW1 EQU 0x66 ;zugeh. Abweichung, vorige Messung
ABW2 EQU 0x69 ;zugeh. Abweichung, vorvorige Messung
regel clrf ABW0
clrf ABW1
clrf ABW2
regel1 movlw 0D8 ; RTCC fuer 10 ms Grundzeit initialisieren
movwf RTCC
movlw 0A
movwf ZAEHL1 ; ZAEHL1 mit 10d laden fuer 100 ms
movf ZEIT,w
movwf EEPROM ; hier als Zwischenspeicher fuer ZEIT benutzbar
mess ;call start1 ;Start des RTCC-Zeitgebers durch Laden des OPTION-Registers
clrf UHI
clrf UMI
clrf ULO
movf ABW1,w ; Registerinhalte verschieben
movwf ABW2
movf ABW0,w
movwf ABW1
;call adw ; adw aufrufen
;movf ADRES,w ; Istwert nach w
subwf OGRW,w ; Ueberschreiten des oberen Grenzwertes testen
;btfss STAT,C
goto alarm2
;movf ADRES,w
subwf UGRW,w ; Unterschreiten des unteren Grenzwertes testen
;btfsc STAT,C
goto alarm3
;movf ADRES,w
subwf SOLLW,w ; Regelabweichung bilden
movwf ABW ; dies ist die Regelabweichung
; nun wird ABW getestet, ob positiv oder negativ und auf Ueber- bzw. Unterschreiten
; von +127 bzw. -127d (7-Bit-Zahl mit Vorzeichen)
;btfsc STAT,C ; ABW positiv?
goto test1 ; ja:
btfsc ABW,7 ; nein: Bit 7 auf 0 testen
goto weit1 ; Bit 7 nicht 0: o.k.
movlw 80
movwf ABW ; Grenzwert -127d fuer ABW einsetzen
goto weit1
test1 btfss ABW,7 ; bei pos. ABW Bit 7 auf 1 testen
goto weit1 ; Bit 7 = 0: o.k.
movlw 7F
movwf ABW ; Grenzwert +127d fuer ABW einsetzen
weit1 movf ABW,w
movwf ABW0 ; aktuellen Wert in ABW0 einsetzen
movlw 03
movwf DATEIN ; hier fuer den Zweck als Schleifenzaehler frei
movlw 30 ; Startwert f. indirekte Adressierung laden
movwf FSR ; (1 ueber hoechster RAM-Adresse 2F)
wdh19 decf FSR,f
;movf IND,w ; ABW0, ABW1 bzw. ABW2
movwf BLO ; nach BLO
decf FSR,f
;movf IND,w ; Q0LO, Q1LO bzw. Q2LO
movwf ALO ; nach ALO
decf FSR,f
;movf IND,w ; Q0HI, Q1HI bzw. Q2HI
movwf AHI ; nach AHI
;call mult0 ; Multiplikation ausfuehren
;call add ; Addition ausfuehren
decfsz DATEIN,f
goto wdh19
; aus (UHI, UMI, ULO) durch Addition von (STELLG) zu UMI die neue Stellgroesse ableiten
movf STELLG,w
addwf UMI,f
;btfsc STAT,C ; Uebertrag?
incf UHI,f ; ja: UHI inkrementieren
; Das Ergebnis dieser Operation ist die neue Stellgroesse
btfsc UHI,7 ; Ergebnis negativ?
goto setz0 ; ja: STELLG = 0
movf UHI,f ; nein:
;btfss STAT,Z ; (UHI) > 0 ?
goto setzff ; ja: STELLG = FF
nop ; nein: also (UHI) = 0
btfss ULO,7 ; (ULO) = 0,5?
goto weit2 ; nein: weiter
incf UMI,f ; ja; UMI aufrunden
;btfsc STAT,Z ; Uebertrag?
goto setzff ; ja: STELLG = FF
weit2 movf UMI,w ; nein: (UMI) nach STELLG laden
movwf STELLG
goto ausg
setz0 clrf STELLG
goto ausg
setzff movlw 0FF
movwf STELLG
; Ergebnisse: Istwert und neue Stellgroesse ausgeben
ausg nop
movf STELLG,w
movwf PORTB ; Anfangs-Stellgroesse an Port B ausgeben
;call latch
;call istwert ; Istwert anzeigen (Port B = Ausgang)
;call stellgr ; Stellgroesse anzeigen (Port B = Ausgang)
wdh20 movf RTCC,w ; innere Abfragezeitschleife: Wartezeit = 10 ms
;btfss STAT,Z
goto wdh20
clrwdt
movlw 0D8 ; 10 ms um
movwf RTCC
decfsz ZAEHL1,f
goto wdh20
movlw 0A ; 100 ms um
movwf ZAEHL1
decfsz EEPROM,f
goto wdh20
movf ZEIT,w ; Ende Abtastzeit, abh. von (ZEIT)
movwf EEPROM ; Eingabe in ZEIT uebernehmen
goto mess ; naechste Messung
alarm2 clrf STELLG ; Stellgroesse = 0
movf STELLG,w ; und ausgeben
movwf PORTB
;call latch
goto alarm4
alarm3 movlw 0FF ; Stellgroesse = FFh
movwf STELLG
movf STELLG,w ; und ausgeben
movwf PORTB
;call latch
alarm4 ;call alarm
goto regel1 ; Solange, bis keine Ueber- bzw. Unterschreitung mehr
org 3FF
;goto start
end
Wie kan hier iets over vertellen ?
[Bericht gewijzigd door MMSoft op ]
Op 22 september 2006 19:23:27 schreef MMSoft:
Wie kan hier iets over vertellen ?
Met die lap code kan ik je niet helpen.
Ik begrijp dat je e.a wilt leren over PID-regelen, en dit wilt implementeren in een microcontroller.
Eigenlijk zijn er twee hindernissen te nemen:
1) eerst PID-regelaar ontwerp: constantes en o.a de sampletijd van deze regelaar, zijn afhankelijke van je proces.
-identificatie van het proces.
(-Regelaar ontwerp in continu domein)
-Regelaar ontwerp in tijd discreet domein
2) implementatie van de regelaar in whatever voor taal en geschikte hardware. De regelaar is nu gewoon een formule-tje geworden, dat je vertelt hoe je output voor een volgend sample berekend moet worden.
Je bent nu eigenlijk bij 2 begonnen, waardoor je je contsantes zult moeten trail and error.
Als je wilt weten hoe je het moet implementeren:
google("implementation pid");
http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=vi…
Op 22 september 2006 19:23:27 schreef MMSoft:
De opzet is het leren programmeren van een PI(D) regeling.Wie kan hier iets over vertellen ?
Besteed eens een middag (of meer) aan de volgende pagina: http://www.embedded.com/2000/0010/0010feat3.htm
Ik heb het een en ander gelezen, en begin een idee te krijgen hoe het werkt.
Hoe kan ik nu het beste beginnen ?
Ik denk eraan om met een tijd gestuurde interrupt (1 sec) de (nog te maken) PID routine op te roepen...
Blijkbaar heb je het nog niet helemaal begrepen.
Uit de analyse van je systeem volgt de minimaal benodigde sampletijd. Niemand zal hier kunnen beargumenteren of het een sampletijd van 1 sec geschikt is voor de door jou gekozen toepassing, omdat wij niet weten:
1) Wat je wil, kwantitatief.
2) Wat je systeem is.
Bijv. je blokje is 1x1x1 cm, het materiaal is aluminium:
Nu kan je de warmtecapaciteit bepalen, bereken wat de thermische weerstand naar de omgeveving is en zo kan je een idee krijgen van de tijdconstantes in je systeem.
Hiermee kan je dan een inschatting maken voor je sampletijd.
Daarnaast zul je een periodetijd voor je PWM moeten kiezen, deze keuze kan je ook op bovenstaande tijdconstantes baseren. Wat mij betreft dus eerst de analyse van je systeem, daarna implementatie.
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
@JoVi: overdrijven is ook een kunst. Ik heb nog een regelbare geschakelde voeding (0-25.5V/2A), draaiend op 8kHz (veel te weinig), uit de losse hand in een PIC geprogrammeerd (die ook nog allerhande communicatie afhandelde). Puur op trial-and-error gebaseerd, het was mijn eerste ervaring met µC's. Dus ook zonder enige berekening is het mogelijk om een systeem af te regelen naar specificatie's. Ik beweer zeker niet dat het perfect was, maar het was goedkoop, en het werkte goed genoeg.
@TS: De periodetijd wordt hoofdzakelijk bepaald door het gebruik van een solid-state relay. Deze zal héél waarschijnlijk voorzien zijn van een nuldetectie, en dus minimaal een halve sinus doorlaten. Aangezien netspanning 50Hz is, heb je 100 nuldoorgangen in een seconde, een PIC is 8bits en zal dus het gemakkelijkst werken met een bereik van 0-255. De kortste PWM periode is dus 2.55 seconden, dan zal je echter een kleine variatie houden op de instelling (ene keer zal ie vb 100/255 halve sinussen doorlaten, de volgende keer 101/255, de keer erna 99/255, hij kan wat heen en weer gaan), maar dat is te verwaarlozen.
Regeltechniek is overigens een techniek die bol staat van de aannames en vereenvoudigingen, niets is volledig tot in de puntjes te karakteriseren. Je buikgevoel kan een goeie indicatie zijn van tastbare, eenvoudige processen (zoals wat TS wil maken), ik zou persoonlijk met gerust hart de "trail-and-error"methode willen aanraden: maak de PWM met periodetijd van 2.55 seconden, zorg dat je in die 2.55 seconden een 10tal keer de temperatuur hebt gemeten en er een gemiddelde van hebt gemaakt, pas de duty-cycle van de PWM aan naargelang het verschil tussen gewenste en gemeten waarde (hoe dichter bij gewenste waarde, hoe kleiner de stappen waarmee je de duty-cycle aanpast, eventueel ook hoe trager je de PWM aanpast).
Eenmaal je zoiets hebt gemaakt, probeer het dan uit. Hou bij wat ie exact doet (evt op LCD schermpje de PWM instelling en gemeten temp weergeven), en pas de code aan volgens wat je uitkomt. Na wat experimenten kan je relatief gemakkelijk een goeie instelling bekomen.
... maak de PWM met periodetijd van 2.55 seconden, zorg dat je in die 2.55 seconden een 10tal keer de temperatuur hebt gemeten en er een gemiddelde van hebt gemaakt, pas de duty-cycle van de PWM aan naargelang het verschil tussen gewenste en gemeten waarde (hoe dichter bij gewenste waarde, hoe kleiner de stappen waarmee je de duty-cycle aanpast, eventueel ook hoe trager je de PWM aanpast).
Dat is een mooi begin.
Ik heb al enkele keren een PWM signaal gebruikt, maar nog nooit gekeken naar de periodetijd van dit signaal.
Hoe kan ik deze precies instellen op 2.55 seconden ?
(PIC16F876A)
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Op 24 september 2006 20:48:53 schreef MMSoft:
[...]
Dat is een mooi begin.
Ik heb al enkele keren een PWM signaal gebruikt, maar nog nooit gekeken naar de periodetijd van dit signaal.
Hoe kan ik deze precies instellen op 2.55 seconden ?
(PIC16F876A)
Kijken naar de frequentie van het kristal dat je gebruikt, delen door 4, prescalers op TMR0 instellen, zodat je elke 0.01s een interrupt hebt. Binnenin je interrupt maak je gewoon een variabele elke keer eentje hoger (tis een byte groot, dus automagisch zal ie na 255 weer op 0 vallen), vergelijk de gewenste duty-cycle met de waarde van die variabele, lager = PWMuitgang uit, hoger = PWMuitgang aan.
In de gewone code kan je dan al doen wat je wil, dus wat temperatuur bekijken, en duty-cycle aanpassen.
Duidelijk, moet ik een basic voorbeeldje geven of snap je em?
De kristal freq. is 4 Mhz.
Ik denk dat ik het begrijp, mocht je vrij makelijk een voorbeeldje kunnen maken, dan graag (zodat ik met een goede basis begin).
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
4MHz klok, dus 1µs per instructie (factor 4 verschil). TMR0 laat je als timer lopen (gekoppeld aan de instructieklok dus), en geef je een bepaalde prescaler. Ff rekenen:
elke 10ms een interrupt, dat is elke 10000 instructie's. 10000/255=39, dus een grotere prescaler dan 1:39 gebruiken, 1:64 is de dichtste waarde.
10000/64=156.25, dus TMR0 in de interrupt instellen op 255-156=99 (interrupt komt als TMR0 van 255 naar nul gaat, we willen dat dat 156 TMR0tikken duurt).
Dus ff resumeren:
-TMR0 als timer instellen (aan instructieklok)
-TMR0 interrupts inschakelen
-prescaler van TMR0 op 1:64
-in de interrupt TMR0 preloaden met 99
-we krijgen elke 0.01s een interrupt, daarin maak je je PWM op de gekende manier.
-ik ben te lui om die instellingen voor je op te zoeken, zelf ff checken dus. En het kan gerust zijn dat ik fouten heb gemaakt, reken gerust alles nog ff na.
Hier is nog eens hoe de interrupt er uit zou moeten zien, in Basic:
'interrupt routine
TMR0 = 99
var = var + 1 'Tellertje voor PWM
If var = 0 Then
PWMuit = 0
End if
If var = DutyCycle Then
PWMuit = 1
End if
INTCON.T0IF = 0 'enable new TMR0 interrupts
'einde van de interrupt routine....dus TMR0 in de interrupt instellen op 255-156=99 (interrupt komt als TMR0 van 255 naar nul gaat, we willen dat dat 156 TMR0tikken duurt)...
Voor de Timer gebruik ik TMR2
0,01 Sec. = 100 Hz
;CLK/4 = 1.000.000 Hz
;Prescaler 1:16 = 62.500 Hz
;PR2 value 125 = 500 Hz
;Postscaler 1:5 = 100 Hz
Als ik 'PR2' de waarde D'124' geef dan heb ik een freq. van 100 Hz.
Maak ik de waarde Hoger, dan wordt de freq. Lager.
Maak ik de waarde Lager, dan wordt de Freq. Hoger.
Daarom heb ik het idee dat de PR2 waarde Aftelt, i.p.v. Optelt.
[Bericht gewijzigd door MMSoft op ]
Op 24 september 2006 18:06:42 schreef Videomodulator:
@JoVi: overdrijven is ook een kunst.
+
Verhaal over voeding...
Sorry, maar dat ik probeer deze beste man netjes te helpen, zodat hij ook nog iets qua regeltechniek opsteekt. Een PID controller is immers niets anders dan een dan een simpele update regel. Deze hier gewoon neerplanten is niet echt spannend lijkt me. Helaas denken veel mensen dat regeltechniek een beetje prullen is.
Op 24 september 2006 18:06:42 schreef Videomodulator:
Regeltechniek is overigens een techniek die bol staat van de aannames en vereenvoudigingen, niets is volledig tot in de puntjes te karakteriseren. Je buikgevoel kan een goeie indicatie zijn van tastbare, eenvoudige processen (zoals wat TS wil maken), ik zou persoonlijk met gerust hart de "trail-and-error"methode willen aanraden: [\quote]
Inderdaad, maar je moet je aannames op baseren toch? Foute aannames kunnen fataal zijn. Ik vind het helemaal niet erg dat iemand trail on error wil proberen. Iedereen zijn eigen manier van werken natuurlijk.
Ok, ontopic dan maar.
Het lijkt me in geen geval handig om je samplefrequentie gelijk aan je pwm frequentie te hebben, hier verwacht ik
toch wel een orde verschil in...
Daarnaast is de samplefrequentie natuurlijk afhankelijk van je systeem. De kans is groot dat door de dynamica (eigenschappen van het blokje) van het proces je verhaal over sinusdoorgang e.d niet ter zake is omdat je op een verkeerde tijdschaal zit te kijken.
De trail-and-error methode, wordt daar mee bedoeld:
Dat je iets uitstuurt, en als dat niet juist is, je de uitstuur waarde met 1 corrigeert.
Mocht het dan nog niet goed zijn, dan nogmaals de uitstuur waarde met 1 corrigeren, net zo lang dat het wel goed is ?
Op 25 september 2006 20:15:09 schreef MMSoft:
De trail-and-error methode, wordt daar mee bedoeld:
Dat je iets uitstuurt, en als dat niet juist is, je de uitstuur waarde met 1 corrigeert.
Mocht het dan nog niet goed zijn, dan nogmaals de uitstuur waarde met 1 corrigeren, net zo lang dat het wel goed is ?
Haha, grappig dat je dat je dit opmerkt.
In dit geval gaat (helaas) over de ontwerpmethode. Je kan ervoor kiezen eerst e.a. op een papiertje uit te werken, of meteen beginnen met bouwen en/of proggen.
trail-on-error algorithme:
Kies_startoplossing;
while(probeer_je_systeem_uit()!=TEVREDEN){
versleutel_iets_aan_je_opstelling();
}
blij();
Er is alleen kans dat het even duurt voordat je uit de loop komt. Tevens moet je opnieuw loopen als je systeem veranderd en kan je bij ingewikkeldere systemen niet makkelijk zeggen of je oplossing de beste oplossing is.
In dit geval zal je best wel iets aan de gang krijgen.
Trouwens, het is in dit geval wel leuk om te kijken wat er gebeurt als je dit systeem regelt door op twee drempelwaardes je heater aan en uit te schakelen (zoals een bimetaaltje doet).
[Bericht gewijzigd door JoVi op ]
Op 25 september 2006 20:15:09 schreef MMSoft:
De trail-and-error methode, wordt daar mee bedoeld:
Dat je iets uitstuurt, en als dat niet juist is, je de uitstuur waarde met 1 corrigeert.
Mocht het dan nog niet goed zijn, dan nogmaals de uitstuur waarde met 1 corrigeren, net zo lang dat het wel goed is ?
Ik heb mijn eerste regeling klaar, die volgens dat principe werkt.
Als PWM functie gebruik ik de 2.55 Seconden periodeduur.
Dit is een begin, nu op naar een 'echte (PID)' regeling...
