Hallo liebe Gemeinde,
ich habe folgendes Problem:
Ich habe eine B2 Brücke mit Phasenaschnitt und betreibe daran eine
Gleichstrommaschine.
Ziel ist es über das Poti nicht den Phasenanschnittswinkel, sondern den
maximalen Strom vorzugeben.
Mein Problem ist, dass die Maschine zwar auf das Poti reagiert und auch
mit dem Strom hochläuft, doch nicht auf dem Wert verweilt, sondern nach
Erreichen eines Winkels von ca. 100 Grad wieder langsam auf null
Umdrehungen herunter läuft.
Hier ein Auszug aus meinem Quellcode:
volatileintLAMBDA=4000;//Initialisierungswert für Leitdauer 36°
7
8
floatImax=0;
9
intId_neu=0,Id_alt=0;
10
intALPHA_ohneL=17900;
11
12
intq=0;
13
intaa=0;
und die Variablen für den Regler:
1
floatnew_u_ist=0;//Stellgröße die der Regler ausgibt
2
floatxd=0;//Regler abweichung aktuell
3
floatxd_1=0;//Reglerabweichung zum zeitpunkt -1
4
floatT_AB=0.0036;//Abtastzeit Beobachter + delta i + Algo PI
5
floatT_Ri=0.05;//Streckenzeitkonstante
6
floatk_Ri=0.7;//La/Ra
7
intu_ohneL=0;
8
floatu_mitL;
Ich folge dann mal Ihrem Rat und ändere alle integer Werte der Ströme in
float um.
"Imax" habe ich gerade gesehen, ist ja auch als float deklariert.
Sonst irgendwelche Auffälligkeiten?
Vielen Dank für die Hilfe.
Chris schrieb:> Ich folge dann mal Ihrem Rat und ändere alle integer Werte der Ströme in> float um.Das hab ich nicht gesagt!
Was ich gesagt habe, das ist das hier
1
xd=(Imax-Id_neu)/1000;// teilen durch 1000 wegen integer Werte der Ströme
2
xd_1=(Imax-Id_alt)/1000;
Integer Ergebnisse entstehen.
Das xd und xd_1 als float definiert sind, ist zwar nett, interessiert
aber niemanden, am allerwenigsten den Compiler.
FAQ: Datentypen in Operationen
D.h es interessiert nur insofern, damit ich die Absicht erkennen kann,
die hier dahinter steckt. Dem Compiler ist das aber wurscht, was die
Absicht war. Der orientiert sich nach dem was dort steht. Ein
1
floatresult;
2
intj=5;
3
4
result=j/8;
liefert eine glatte 0 in result und keineswegs 0.625
Okay, also vielen Dank. Seit der Anpassung fährt die Maschine schon Mal
nicht mehr komplett auf null herunter.
Jedoch gibts es große Schwankungen in der Drehzahl.
Liegt es rein an den Reglerparametern oder macht es auch Sinn die vom
Poti eingelesenen Werte zu mitteln?
Karl Heinz schrieb:> Was ich gesagt habe, das ist das hier>> xd = (Imax - Id_neu)/1000; // teilen durch 1000 wegen integer Werte ...> xd_1 = (Imax - Id_alt)/1000;>> Integer Ergebnisse entstehen.>> Das xd und xd_1 als float definiert sind, ist zwar nett, interessiert> aber niemanden, am allerwenigsten den Compiler.
In diesem Fall aber schon, da Imax als float definiert ist.
Eric B. schrieb:> Karl Heinz schrieb:>> Was ich gesagt habe, das ist das hier>>>> xd = (Imax - Id_neu)/1000; // teilen durch 1000 wegen integer Werte ...>> xd_1 = (Imax - Id_alt)/1000;>>>> Integer Ergebnisse entstehen.>>>> Das xd und xd_1 als float definiert sind, ist zwar nett, interessiert>> aber niemanden, am allerwenigsten den Compiler.>> In diesem Fall aber schon, da Imax als float definiert ist.
?
Wo hättest du das gesehen?
1
floatPI_ohneL(intId_neu,intId_alt,intImax)
2
{
3
xd=(Imax-Id_neu)/1000;// teilen durch 1000 wegen integer Werte der Ströme
Karl Heinz schrieb:> Imax, Id_neu, Id_alt sind alles int.
Id_neu und Id_alt ja, aber Imax nicht:
Chris schrieb:> float Imax = 0;> int Id_neu=0 , Id_alt = 0;
Sorry, ich hab nur die vermutlich globale Imax gesehen, aber da ist ja
noch diese Funktion, wo Imax nochmal vorkommt (lokal).
Chris schrieb:> float PI_ohneL(int Id_neu, int Id_alt, int Imax)
Benutze jetzt überall float und habe die Teilung durch 1000 gestrichen.
Das Problem sind nun diese Schwingungen der Drehzahl. Drehzahl wird
nicht konstant gehalten.
VZ1 Filterung der Poti Werte hat auch nichts gebracht.
Mark schrieb:> Jedoch gibts es große Schwankungen in der Drehzahl.
Wenn ein Regler schwingt, ist das normalerweise ein Hinweis darauf, dass
die Regelparameter nicht stimmen.
> Liegt es rein an den Reglerparametern oder macht es auch Sinn die vom> Poti eingelesenen Werte zu mitteln?
Ganz ehrlich?
Was meiner Meinung nach extrem Sinn machen würde, das ist eine
Möglichkeit zu finden, wie du als Entwickler dir im laufenden Betrieb
dir die Zahlenwerte für new_u_ist bzw. ALPHA_ohneL sichtbar machen
kannst.
Das beobachten der zeitlichen Entwicklung verrät einem schon einiges.
4ms ist natürlich nicht viel, aber wenn man zb jeden 10-ten Wert
ausgibt, sollte auch das schon einiges verraten.
sieht komisch aus.
Dir ist bewusst, dass new_u_ist seinen Wert erst dann nicht mehr ändert,
wenn Id_alt den Wert von IMax erreicht hat?
'Seinen Wert nicht mehr ändert' bedeutet aber nicht, dass new_u_ist dann
den Wert 0 hätte. WEnn new_u_ist aber nicht 0 ist, dann verringert sich
hier
Die Regelung in Integern laufen zu lassen waere besser. Offensichtlich
gibt es noch ein regelungstechnisches Problem. Also muessen Variablem in
Echtzeit zugaenglich gemacht werden. Was ist die Zeitkonstante des
Vorgangs ?
Falls langsam, die Variable(n) ueber das UART rauslassen.
Falls schnell, einen Tracebuffer definieren, die Variable(n) alle DeltaT
reinschreiben und nachher per UART auslesen.
Irgendwas stimmt hier noch nicht:
Chris schrieb:> Ziel ist es über das Poti nicht den Phasenanschnittswinkel, sondern den> maximalen Strom vorzugeben.Chris schrieb:> Das Problem sind nun diese Schwingungen der Drehzahl. Drehzahl wird> nicht konstant gehalten.
Wenn du auf den Strom regelst kannst du nicht erwarten dass die Drehzahl
konstant bleibt.
Redest du von einer Reihenschluss oder einer Nebenschlussmaschine.
Denn du kannst erst mal nicht generell von einem festen Zusammenhang
zwischen Strom und Drehzahl ausgehen.
Jetzt Nicht schrieb:> Was ist die Zeitkonstante des> Vorgangs ?
Zeitkonstante beträgt 20ms.
Problem ist, dass es sich um eine fertige, mit Stopplack versehene,
Platine
handelt, mit winzigem uC. Da irgendwelche Kabel für die USART
Schnittstelle ranzubekommen wird schwierig.
Udo Schmitt schrieb:> Redest du von einer Reihenschluss oder einer Nebenschlussmaschine.> Denn du kannst erst mal nicht generell von einem festen Zusammenhang> zwischen Strom und Drehzahl ausgehen.
Fremderregt.
Udo Schmitt schrieb:> Chris schrieb:>> Ziel ist es über das Poti nicht den Phasenanschnittswinkel, sondern den>> maximalen Strom vorzugeben.>> Chris schrieb:>> Das Problem sind nun diese Schwingungen der Drehzahl. Drehzahl wird>> nicht konstant gehalten.>> Wenn du auf den Strom regelst kannst du nicht erwarten dass die Drehzahl> konstant bleibt.
Das stimmt natürlich. Da ist lediglich die Ankerspannung proportinal zur
Drehzahl. Da habe ich mich falsch ausgedrückt.
Was ich meine, wenn ich über das Poti 3 Ampere vorgebe, die GM im
Leerlauf 1 A zieht, und ich konstant belaste, dann sollte sich über die
Regelung ein bestimmter ALPHA einstellen. Und zwar so, dass im Anker der
GM 3 Ampere fließen. Doch der ALPHA schwankt so sehr, dass der Strom
auch zwischen 2 und 4 A schwankt und dem zur Folge auch die
Ankerspannung/Drehzahl.
Oder auch wenn ich im Leerlauf etwa 1 A vorgebe, jagt die Maschine mit
2,5 A hoch und in der nächsten Sekunde ist der Strom wieder fast null
und die Maschine bleibt stehen und das wiederholt sich immer.
Karl Heinz schrieb:> Die Reglergleichung new_u_ist = (new_u_ist + k_Ri * (xd - xd_1) + k_Ri> * T_AB / T_Ri * xd_1) ;> sieht komisch aus.>> Dir ist bewusst, dass new_u_ist seinen Wert erst dann nicht mehr ändert,> wenn Id_alt den Wert von IMax erreicht hat?> 'Seinen Wert nicht mehr ändert' bedeutet aber nicht, dass new_u_ist dann> den Wert 0 hätte. WEnn new_u_ist aber nicht 0 ist, dann verringert sich> hier ALPHA_ohneL = ALPHA_ohneL - (PI_ohneL(Id_neu, Id_alt, Imax));> das Alpha laufend.
Wenn der Strom im Motor Id_neu (oder kann ja auch ruhig Id_alt sein?)
den Wert von Imax (über Poti vorgegeben) erreicht, soll sich die
Stellgröße new_u_ist auch nicht mehr ändern.
Der feste Wert soll dann einem bestimmten Winkel ALPHA zur folge haben.
Chris schrieb:> Karl Heinz schrieb:>> Die Reglergleichung new_u_ist = (new_u_ist + k_Ri * (xd - xd_1) + k_Ri>> * T_AB / T_Ri * xd_1) ;>> sieht komisch aus.>>>> Dir ist bewusst, dass new_u_ist seinen Wert erst dann nicht mehr ändert,>> wenn Id_alt den Wert von IMax erreicht hat?>> 'Seinen Wert nicht mehr ändert' bedeutet aber nicht, dass new_u_ist dann>> den Wert 0 hätte. WEnn new_u_ist aber nicht 0 ist, dann verringert sich>> hier ALPHA_ohneL = ALPHA_ohneL - (PI_ohneL(Id_neu, Id_alt, Imax));>> das Alpha laufend.>> Wenn der Strom im Motor Id_neu (oder kann ja auch ruhig Id_alt sein?)> den Wert von Imax (über Poti vorgegeben) erreicht, soll sich die> Stellgröße new_u_ist auch nicht mehr ändern.> Der feste Wert soll dann einem bestimmten Winkel ALPHA zur folge haben.
Hmm..
So berechne ich meinen Zündwinkel:
Chris schrieb:> Wenn der Strom im Motor Id_neu (oder kann ja auch ruhig Id_alt sein?)> den Wert von Imax (über Poti vorgegeben) erreicht, soll sich die> Stellgröße new_u_ist auch nicht mehr ändern.> Der feste Wert soll dann einem bestimmten Winkel ALPHA zur folge haben.
Das ist aber nicht das was du programmiert hast.
Wenn new_u_ist einen Wert ungleich 0 hat (fest ist), dann verändert sich
das Alpha.
Dein Alpha verändert sich nur dann nicht mehr, wenn new_u_ist irgendwann
mal 0 wird.
Danke Karl Heinz. Auch an alle anderen wohlwollenden Helfer.
Die beiden Sachen - float/int Gemisch und die Aufintegration - haben
schon ein Mal das Schwingen beseitigt.
Jetzt fährt der Alpha nur nicht bis zum minimalem Wert runter, wenn das
Poti auf Null steht..
Ich strenge meine grauen Zellen mal selber noch etwas an.. :D
Für Anregungen bin ich trotzdem immer gerne zu haben :))
Also den Grund kenne ich bislang immer noch nicht.
Dachte eigentlich brauche ich den "Quatsch" ja (jetzt noch) nicht. Sage
einfach:
1
Alpha=Alpha-(Imax*1000-Id_neu*1000)/1000//evtl *10 wegen kleinen Ändeungen
Aber ist genau das selbe Problem. Alpha geht einfach nicht auf den
minimalen Wert herunter.
Alpha berechnet 1,5A, vom Poti vorgegeben null, Ergebnis aber nicht das
gewünschte.
Weiß jemand Rat?
Chris schrieb:> Also den Grund kenne ich bislang immer noch nicht.> Dachte eigentlich brauche ich den "Quatsch" ja (jetzt noch) nicht. Sage> einfach:>>
1
>Alpha=Alpha-(Imax*1000-Id_neu*1000)/1000//evtl *10 wegen kleinen
2
>Ändeungen
3
>
>> Aber ist genau das selbe Problem. Alpha geht einfach nicht auf den> minimalen Wert herunter.
Dann würde ich mir halt mal den Wert von Id_neu genauer ansehen.
Offenbar ist das Ergebnis von
1
Imax*1000-Id_neu*1000
dann schon 0 bzw. so klein, dass es praktisch 0 wird und keine relevante
Änderung mehr in Alpha hervorruft.
Hast du jetzt eigentlich auf Floating Point umgestellt?
> Weiß jemand Rat?
Ich hab mich hier im Forum schon tausendemale immer gleich geäussert:
Wer ein komplexes dynamisches System zu implementieren versucht, ohne
sich eine Möglichkeit zu verschaffen, sich Werte ansehen zu können (und
sei es nur, indem er provisorisch eine UART oder ein SPI LCD an
irgendwelche Pins ankabelt), der ist in meinen Augen ein Dummk..f, der
es nicht besser verdient hat. Die Attitüde "das wird schon auf Anhieb
funktionieren" ist zwar die Idealvorstellung, aber der Regelfall ist nun
mal "Es funktioniert nicht out of the box". Genau das ist einer der
wesentlichen Unterschiede, die einen Entwickler mit Erfahrung von einem
Neuling abhebt. Der E.m.E plant von vorneherein Debug-Möglichkeiten mit
ein.
Karl Heinz schrieb:> Dann würde ich mir halt mal den Wert von Id_neu genauer ansehen.> Offenbar ist das Ergebnis von Imax*1000-Id_neu*1000> dann schon 0 bzw. so klein, dass es praktisch 0 wird und keine relevante> Änderung mehr in Alpha hervorruft.> Hast du jetzt eigentlich auf Floating Point umgestellt?
Ja der berechnete Strom ist zwar klein, aber eher 0,5 A statt wahren 1
A.
Und weil alles auf float umdeklariert ist, müsste ja trotzdem eine
Änderung registriert werden.
Chris schrieb:> Karl Heinz schrieb:>> Dann würde ich mir halt mal den Wert von Id_neu genauer ansehen.>> Offenbar ist das Ergebnis von Imax*1000-Id_neu*1000>> dann schon 0 bzw. so klein, dass es praktisch 0 wird und keine relevante>> Änderung mehr in Alpha hervorruft.>> Hast du jetzt eigentlich auf Floating Point umgestellt?>> Ja der berechnete Strom ist zwar klein, aber eher 0,5 A statt wahren 1> A.> Und weil alles auf float umdeklariert ist, müsste ja trotzdem eine> Änderung registriert werden.
müsste?
hätti - wari
(Hätt ich mehr Rennen gewonnen - wäre ich Weltmeister geworden. Gerhard
Berger, österr. F1-Rennfahrer)
Mit 'müsste' kann man nicht debuggen. Entweder es tut das oder es tut
das nicht.
Na IRGENDEINEN Pin wirst du doch wohl erreichen können, der nichts mit
dem Poti und den beiden Ausgängen zu tun hat. LED, Taster, was auch
immer. Software-UART und fertig. Stell dich mal nicht so an...
Chris schrieb:> Ja führt wohl kein Weg dran vorbei.> Wird nur echt schwierig beim ATmega2560 an die Pins zwei Kabel> ranzulöten..
Wenn man bedenkt, dass du mittlerweile schon 2 Tage am Problem
knabberst, ohne zu einer abschliessenden Lösung gekommen zu sein, sind
selbst 2 Stunden unter der Lupe mit dem feinen Lötkolben und Fädeldraht
fummeln quasi ein Schnäppchen.