Forum: PC-Programmierung DGL unter Matlab


von Hermann N. (hermann_n)


Angehängte Dateien:

Lesenswert?

Guten Morgen Liebe Mikrocontrollermitglieder,

ich bitte um eure Hilfe.
Meine Problem ist folgendes:

ich habe eine Datenblatt einer Batterie mit SOC, Temp, Zeit und 
dementsprechend zugehörige Interne Widerstand der Batterie.

Ich möchte untzer Matlab eine DGL herstellen, die mir erlaubt die 
Innenwiderstand der Batterie zu berechnen asl Funktion von SOC, Temp und 
Zeit Rin = f(SOC, Tem, t).

Könnt ihr mir bitte helfen? Datenblatt beigefügt.

Dankeschön im voraus.

: Bearbeitet durch User
von S. E. (crayse)


Lesenswert?

Meinst du mit "DGL" Differentialgleichung?
Falls ja, verstehe ich nicht, was du meinst.

Wenn ich das mal ignoriere, würde ich dich so verstehen, dass du die 
Tabellenwerte aus dem Datenblatt gerne interpolieren möchtest, um den 
Innenwiderstand auch an nicht tabellierten Stellen bestimmen zu können?
Falls das so ist, dann empfehle ich dir in MATLAB mal "doc interp3" 
einzugeben.

von Hermann N. (hermann_n)


Lesenswert?

Hallo crayse und danlke für deine Rückmeldung.

Ja ich meine mit "DGL" Differentialgleichung. Ich möchte einen Bock 
("Block-Widerstand für eine Simulation") unter Simulink einbauen, der 
mir bei Eingabe der Temperatur und SOC den zugehörige Widerstand über 
die Zeit gibt, wie es in der Tabelle steht, also die Möglichkeit Rin als 
Rin = f(SOC, Tem, t) darstellen zu können.


Habe ich das Problem so ein bisschen besser erklärt?

Vielen Dank

von Joe G. (feinmechaniker) Benutzerseite


Lesenswert?

Hermann N. schrieb:
> also die Möglichkeit Rin als
> Rin = f(SOC, Tem, t) darstellen zu können.

Und warum sollte das die Lösung einer Dgl. sein?

: Bearbeitet durch User
von S. E. (crayse)


Lesenswert?

Ja, das verstehe ich wie gesagt auch nicht ganz. Wo genau kommt da die 
Differentialgleichung ins Spiel?

Wahrscheinlich verstehe ich auch die Tabelle nicht, vielleicht kannst du 
mir da nochmal helfen. Aber so wie ich das sehe, ist doch der 
Innenwiderstand mit der Angabe von SOC, T und t schon voll bestimmt 
(zumindest für die in der Tabelle angegebenen Werte). Welche DGL müsste 
da deiner Meinung nach gelöst werden?

Meinst du damit vielleicht, dass du den Innenwiderstand dann in der 
Lösung einer DGL verwenden willst?

von Hermann N. (hermann_n)


Lesenswert?

Hallo crayse - Joel G,

Vielleicht habe ich der falsche Ausdruck gemacht. Aber klar möchte ich 
gern Rin als Rin=f(SOC, Temp, t) in einer Gleichung zusammen definieren, 
so dass ich Rin bei bestimmten SOC und Temperatur über die Zeit 
bestimmen kann. Also bei Sumlink einen Block bauen mit SOC, Temp und 
Zeit als Eingangsparameter und Rin als Output.

Habe ich ein bisschen besser klar gemacht?

VG

von Hermann N. (hermann_n)


Lesenswert?

@ S. E.


> Meinst du damit vielleicht, dass du den Innenwiderstand dann in der
> Lösung einer DGL verwenden willst?

Ja das habe ich das so gesehen, diese DGL würde ich dann nutzen um Rin 
als Output zu bestimmen, wenn SOC, Temp und Zeit t als Input des Blockes 
verwenden wurden.

VG

von S. E. (crayse)


Lesenswert?

Hä?
Ich glaube wir reden immernoch aneinander vorbei.
Wenn du wirklich eine DGL lösen willst, wäre es wohl am einfachsten, 
wenn du diese mal explizit hinschreibst, vielleicht kann ich dir dann 
besser helfen, ...
In der müssen ja irgendwelche Ableitungen (wahrscheinlich nach der Zeit) 
vorkommen?

Unabhängig davon suchst du ja anscheinend nach einer Implementierung der 
Funktion f(SOC,T,t), oder?
Soll diese so sein, dass sie z.B. folgende Werte zurückgibt:

f(SOC=10%,T=25°C,t=2s)=1,43 mOhm
oder auch:
f(SOC=40%,T=-30°C,t=10s)=15,8 mOhm

Falls ja, kannst du das wiegesagt mit interp3 machen. Natürlich nur für 
Werte die im Wertebereich der Tabelle liegen bzw. zwischen diesen. Für 
eine Extrapolation außerhalb des Bereichs wirds deutlich komplizierter 
...

von Hermann N. (hermann_n)


Lesenswert?

Hallo Crayse,
ich konnte dank dir und deinen Tipps mein obiges Problem lösen. Nun 
brauche ich bitte wieder deine Hilfe,falls du mir noch gern helfen 
würde.


Es soll folgende Gleichung für die Bestimmung der maximalen bzw. 
minimalen zugelassenen Lade- Entladestrom einer Lithium-ion Zelle gelöst 
werden.

also I_Batt ist gesucht. OCV ist der Leerlaufspannung (Open Circuit 
Voltage) und ist von SOC (State of charge [0 bis 1 in Prozent] wobei 
0=0% und 1=100%) abhängig. Rin ist der Innenwiderstand und ist auch von 
SOC abhängig. detla_E ist ide Änderung der Spannung in Bezug auf die 
Temperatur und wir durch einem Polynom der Forme
 bestimmt (die Gleichung oder das Polynom habe ich auch schon unter 
Matlab implementiert) .
Ich möchte also für SOC =0:0.1:1 den jeweiligen zugehörigen maximal 
Strom mit dem Newton Verfahren bestimmen (approxmieren), und die Werte 
von OCV und R_in werden aus einem lookup Table dementsprechend 
SOC=0:0.1:1 abgelesen.
Hast du oder jemand bitte eine Idee wie ich anfangen oder das 
implementieren kann?

Für SOC=0 dann (OCV und R_in aus lookup Tables)
für T= 25°C z.B. dann DeltaE(T) aus Polynom
I_Batt durch Newton-Verfahren bestimmen, wenn I_Batt für SOC= 0 gefunden 
ist dann nächste SOC=0.1 uws.

Ein einfaches Newton-Verfahren Implementierung ist gar kein Problem.

Vielen Dank im Voraus.

von S. E. (crayse)


Lesenswert?

Hermann N. schrieb:
> Es soll folgende Gleichung für die Bestimmung der maximalen bzw.
> minimalen zugelassenen Lade- Entladestrom einer Lithium-ion Zelle gelöst
> werden.

Mh, ich muss nochmal nachhaken. Du schreibst nicht, was du für
 einsetzt. Ich vermute mal einen festen Wert unter den die 
Zellenspannung nicht sinken soll. Wenn das wirklich ein fester Wert ist, 
kannst du die Gleichung doch einfach nach
 auflösen, oder?
Also:
Wenn du da dann einfach die Werte für einen festen SOC einsetzt müsstest 
du doch direkt aufs Ergebnis kommen oder nicht?

Falls es komplizierter wird, kann man natürlich die Gleichung auch durch 
Nullstellensuche lösen. Matlab hat da wie immer schon Sachen eingebaut 
(etwa die Routine fzero). Selbst implementieren macht da imho keinen 
großen Sinn.

von Hans K. (gamp)


Lesenswert?

Wir haben das damals in der Uni auch sowas mit Matlab gemacht. Wenn du 
DGLs mit mehr als einer Ableitung lösen möchtest, so musst du das System 
erst in Zustandsgleichungen überführen. Dann kannst du das mit einem 
finite Differenzenverfahren lösen. Die Begriffe sollten einigermaßen 
Google-bar sein.

Es ich das eben schnell und übersichtlich machen wollen würde und mir 
auch Simulink zur Verfügung steht, würde ich das eben schnell 
zusammenklicken.

Empfehlen kann ich auch Open-Modelica und VHDL-AMS. Dafür gibt es 
entsprechend viel Freeware, und die Einarbeitungszeit ist meiner Meinung 
nach etwas geringer als für Matlab.

von Hermann N. (hermann_n)


Lesenswert?

S. E. schrieb:

Guten Morgen Cayse,

> Du schreibst nicht, was du für
>
 einsetzt. Ich vermute mal einen festen Wert
> unter den die Zellenspannung nicht sinken soll.
  ja genau es ist die absolute minimale Spannung (Grenzspannung) und ist 
bzw. muss ein fester Wert sein (ich habe in meinem Beispiel z.B. den 
Wert 2.5 eingesezt)

> Wenn das wirklich ein
> fester Wert ist, kannst du die Gleichung doch einfach nach
>
 auflösen, oder?
> Also:
>
> Wenn du da dann einfach die Werte für einen festen SOC einsetzt müsstest
> du doch direkt aufs Ergebnis kommen oder nicht?

ich habe das auch so versucht


> Falls es komplizierter wird, kann man natürlich die Gleichung auch durch
> Nullstellensuche lösen.

da habe ich mit dem folgenden kleinen Programm versucht, ist aber nur 
für ein fester SOC. Ich würde gern für SOC=0:0.1:1, da eigentlich der 
OCV und Rin beide SOC abhängig sind. und da kommt noch dazu die delta_E, 
was Temperatur abhängig ist (hier habe ich den Wert für 25°C benutzt)

clc;
clear all;
close all;

%%%%%%%%%%%% Test Newtonsches Iterationsverfahren %%%%%%%%%%%%

format long

OCV=3.64;         % Open Circuit Voltage %%
Rin=2.14e-3;      % Innenwiderstand      %% für SOC=30%, also 0.3
delta_E= -0.3722; % Änderung der Spannung mit der Temperatur für 25°C
U_Grenz_Min=2.5;  % fester Wert für U_Grenz_Min


I_Batt = 0; % Startwert
ab=1; tol=5*1.0e-3; % 1. Abbruch-Wert und Abbruch-Toleranz
Imax=200; I=1; % max. Iterationen, 1. Iter.-Schritt
while abs(ab) > tol && I < Imax
I_Batt0=I_Batt; % Datensicherung
I_Batt =I_Batt0 -(OCV - Rin*I_Batt - U_Grenz_Min + delta_E )/(-Rin)
ab=I_Batt-I_Batt0; I=I+1; % Lösungsänderung, Iter.-Schritte
end

von Hermann N. (hermann_n)


Lesenswert?

Johannes S. schrieb:

Guten Morgen Johannes,

> Wir haben das damals in der Uni auch sowas mit Matlab gemacht. Wenn du
> DGLs mit mehr als einer Ableitung lösen möchtest, so musst du das System
> erst in Zustandsgleichungen überführen. Dann kannst du das mit einem
> finite Differenzenverfahren lösen. Die Begriffe sollten einigermaßen
> Google-bar sein.
>
> Es ich das eben schnell und übersichtlich machen wollen würde und mir
> auch Simulink zur Verfügung steht, würde ich das eben schnell
> zusammenklicken.
>
> Empfehlen kann ich auch Open-Modelica und VHDL-AMS. Dafür gibt es
> entsprechend viel Freeware, und die Einarbeitungszeit ist meiner Meinung
> nach etwas geringer als für Matlab.

danke für deine Rückmeldung, ich werde mir mal deinen Vorschlag 
angucken.

Vielen Dank

von S. E. (crayse)


Lesenswert?

Hermann N. schrieb:
>> Wenn du da dann einfach die Werte für einen festen SOC einsetzt müsstest
>> du doch direkt aufs Ergebnis kommen oder nicht?
>
> ich habe das auch so versucht

Und was genau hat daran nicht funktioniert?
Warum sollte man numerisch nach Nullstellen suchen, wenn man die 
Gleichung analytisch auflösen kann? Das verstehe ich nicht.
Ich denke du kannst einfach folgendes verwenden:

OCV=3.64;         % Open Circuit Voltage %%
Rin=2.14e-3;      % Innenwiderstand      %% für SOC=30%, also 0.3
delta_E= -0.3722; % Änderung der Spannung mit der Temperatur für 25°C
U_Grenz_Min=2.5;  % fester Wert für U_Grenz_Min

I_Batt=(OCV-U_Grenz_Min+delta_E)/Rin

Fertig!
Wenn ich damit falsch liegen sollte, dann schreib doch mal, warum das in 
deinen Augen nicht geht.

Oder ist dein eigentliches Problem, das jetzt nicht nur für einen festen 
Wert sondern für verschiedene Werte von SOC auszurechnen?
In diesem Fall könnte man z.B. Funktionen Rin, delta_E und OCV machen, 
die in Abhängigkeit von SOC (und evtl. T) die passenden Werte 
zurückgeben und dann sowas wie

numT=10;
Tvec=linspace(10,40,numT);
numSOC=10;
SOCvec=linspace(0,1,numSOC);

for iT=1:numT
  for iSOC=1:numSOC
    I_Batt=OCV(SOCvec(iSOC),Tvec(iT))-U_Grenz_Min+delta_E(SOCvec(iSOC),Tvec( 
iT)))/Rin(SOCvec(iSOC),Tvec(iT))

  end
end

mit passenden Funktionen OCV(SOC,T),delta_E(SOC,T) und Rin(SOC,T) ...


So wie ich das bis jetzt sehe, hat das alles (noch?) gar nichts mit DGLs 
zu tun, oder?

von Hermann N. (hermann_n)


Lesenswert?

S. E. schrieb:

> So wie ich das bis jetzt sehe, hat das alles (noch?) gar nichts mit DGLs
> zu tun, oder?

Ja genau mit DGLs hat das ganze nichts mehr zu tun, darauf bin ich auch 
gar nicht mehr zurückgekommen. Ich probiere jetzt erstmal deinen 
Vorschlag und danach gebe ich dir ne Rückmeldung.

Vielen Dank nochmal für deine Hilfe

VG

von Jan S. (supergood)


Lesenswert?

Wenn du die Werte, wie oben in der Tabelle zu sehen, schon gegeben hast, 
dann kannst du diese doch einfach in eine Matrix eintragen und in 
Simulink mithilfe des lookuptable Blocks zu deinen Eingangswerten den 
entsprechenden Ausgang bekommen!? Warum so kompliziert?
Zwischen den verschiedenen Werten kannst du ja auch noch interpolieren 
wenn du das gerne möchtest.

von Hermann N. (hermann_n)


Lesenswert?

S. E. schrieb:

Hallo Crayse,

> Oder ist dein eigentliches Problem, das jetzt nicht nur für einen festen
> Wert sondern für verschiedene Werte von SOC auszurechnen?
> In diesem Fall könnte man z.B. Funktionen Rin, delta_E und OCV machen,
> die in Abhängigkeit von SOC (und evtl. T) die passenden Werte
> zurückgeben und dann sowas wie
>
> numT=10;
> Tvec=linspace(10,40,numT);
> numSOC=10;
> SOCvec=linspace(0,1,numSOC);
>
> for iT=1:numT
>   for iSOC=1:numSOC
>     I_Batt=OCV(SOCvec(iSOC),Tvec(iT))-U_Grenz_Min+delta_E(SOCvec(iSOC),Tvec( 
iT)))/Rin(SOCvec(iSOC),Tvec(iT))
>
>   end
> end
>
> mit passenden Funktionen OCV(SOC,T),delta_E(SOC,T) und Rin(SOC,T) ...


ich habe mit folgendem Beispiel versucht die OCV zu berechnen, und ich 
bekomme folgende Fehlermeldung: Error using ==>mpower, Matrix must be 
square. Kannst du mir bitte sagen, was nun nicht stimmt?

numSOC=10;
SOCvec=linspace(0,1,numSOC);
for iSOCvec=1:numSOC
 OCV = -1.1465.*(SOCvec)^4 +3.1013.*(SOCvec)^3 -2.3857.*(SOCvec)^2 
+1.1115.*(SOCvec) +3.4042
end

: Bearbeitet durch User
von S. E. (crayse)


Lesenswert?

Du hast noch nicht oft MATLAB benutzt, oder?
Wenn du die elementweise Potenz von Vektoren nehmen willst, musst du .^ 
statt ^ verwenden. In deinem Fall, brauchst du dann auch gar keine 
for-Schleife.
Probiers mal hiermit:

numSOC=10;
SOCvec=linspace(0,1,numSOC);
OCV = -1.1465.*(SOCvec).^4 +3.1013.*(SOCvec).^3 -2.3857.*(SOCvec).^2
+1.1115.*(SOCvec) +3.4042

von Hermann N. (hermann_n)


Lesenswert?

S. E. schrieb:
> Du hast noch nicht oft MATLAB benutzt, oder?
> Wenn du die elementweise Potenz von Vektoren nehmen willst, musst du .^
> statt ^ verwenden. In deinem Fall, brauchst du dann auch gar keine
> for-Schleife.
> Probiers mal hiermit:
>
> numSOC=10;
> SOCvec=linspace(0,1,numSOC);
> OCV = -1.1465.*(SOCvec).^4 +3.1013.*(SOCvec).^3 -2.3857.*(SOCvec).^2
> +1.1115.*(SOCvec) +3.4042

Du hast recht Matlab habe ich leider nur seit kurzem angefangen.
Wenn ich dann keine for-Schleife brauche, wie werde ich dann die 
verschiedenen Werte für den Strom berechnen, wie du oben schon ein 
bisschen erklärt hast?

>Oder ist dein eigentliches Problem, das jetzt nicht nur für einen festen
>Wert sondern für verschiedene Werte von SOC auszurechnen?
>In diesem Fall könnte man z.B. Funktionen Rin, delta_E und OCV machen,
>die in Abhängigkeit von SOC (und evtl. T) die passenden Werte
>zurückgeben und dann sowas wie

>numT=10;
>Tvec=linspace(10,40,numT);
>numSOC=10;
>SOCvec=linspace(0,1,numSOC);

>for iT=1:numT
>  for iSOC=1:numSOC
>    I_Batt=OCV(SOCvec(iSOC),Tvec(iT))-U_Grenz_Min+delta_E(SOCvec>(iSOC),Tvec (
>iT)))/Rin(SOCvec(iSOC),Tvec(iT))

>  end
>end

>mit passenden Funktionen OCV(SOC,T),delta_E(SOC,T) und Rin(SOC,T) ...

Deine Beispile würde mir nur zur Berechnung der OCV als f(SOC) dienen 
oder?

von Hermann N. (hermann_n)


Lesenswert?

S. E. schrieb:
> Du hast noch nicht oft MATLAB benutzt, oder?
> Wenn du die elementweise Potenz von Vektoren nehmen willst, musst du .^
> statt ^ verwenden. In deinem Fall, brauchst du dann auch gar keine
> for-Schleife.
> Probiers mal hiermit:
>
> numSOC=10;
> SOCvec=linspace(0,1,numSOC);
> OCV = -1.1465.*(SOCvec).^4 +3.1013.*(SOCvec).^3 -2.3857.*(SOCvec).^2
> +1.1115.*(SOCvec) +3.4042

Folgendes habe ich probiert, ich bekomme aber immer nur einen Wert für
den Strom. Kannst du mir mal bitte wo der Fehler liegt?

Danke und VG,



clc;
clear all;
close all;

%%%%%%%%%%%% Newtonsches Iterationsverfahren zur Berechnung des
maximalen Stroms %%%%%%%%%%%%



delta_E= -0.3722; % Änderung der Spannung mit der Temperatur, hier für
25°C %%
U_Grenz_Min=2.5;  % fester Wert für U_Grenz_Min

numSOC=20;
SOC=linspace(0,1,numSOC);
%OCV = -1.1465.*(SOC).^4 +3.1013.*(SOC).^3 -2.3857.*(SOC).^2
+1.1115.*(SOC) +3.4042;
%Rin = -5.5186e-3.*(SOC).^4 +10.3749e-3.*(SOC).^3 -5.5877e-3.*(SOC).^2
+0.6510e-3.*(SOC) +1.8168e-3;

I_Batt = 0; % Startwert
ab=1; tol=5*1.0e-3; % 1. Abbruch-Wert und Abbruch-Toleranz
imax=100; i=1; % max. Iterationen, 1. Iter.-Schritt

for iSOC=0:numSOC
    OCV = -1.1465.*(iSOC).^4 +3.1013.*(iSOC).^3 -2.3857.*(iSOC).^2
+1.1115.*(iSOC) +3.4042;
    Rin = -5.5186e-3.*(iSOC).^4 +10.3749e-3.*(iSOC).^3
-5.5877e-3.*(iSOC).^2 +0.6510e-3.*(iSOC) +1.8168e-3;
while abs(ab) > tol && i < imax
I_Batt0=I_Batt; % Datensicherung
I_Batt =I_Batt0 -(OCV - Rin*I_Batt - U_Grenz_Min + delta_E )/(-Rin)
ab=I_Batt-I_Batt0; i=i+1; % Lösungsänderung, Iter.-Schritte
end
end

I_Batt

von S. E. (crayse)


Lesenswert?

S. E. schrieb:
> numSOC=10;
> SOCvec=linspace(0,1,numSOC);
> OCV = -1.1465.*(SOCvec).^4 +3.1013.*(SOCvec).^3 -2.3857.*(SOCvec).^2
> +1.1115.*(SOCvec) +3.4042

Ja, dieses Beispiel berechnet tatsächlich nur OCV als Vektor für die 
entsprechenden Werte von SOC. Aber nur, weil du genau dieses Beispiel 
oben aufgebracht hast.

Du kannst auch alles direkt mit Vektoren (bzw. Matrizen, wenn du die 
beiden Parameter T und SOC) hast rechnen. Der Übersichtlichkeit halber 
und weil du dich ja anscheinend noch nicht so gut mit MATLAB auskennst, 
würde ich dir davon eher abraten.
Ich kann nur nochmal meinen Rat von oben wiederholen und folgenden 
Codeschnippsel anbieten:

numT=10;
Tvec=linspace(10,40,numT);
numSOC=10;
SOCvec=linspace(0,1,numSOC);

for iT=1:numT
  for iSOC=1:numSOC
    I_Batt=OCV(SOCvec(iSOC),Tvec(iT))-U_Grenz_Min+delta_E(SOCvec(iSOC),Tvec(
iT)))/Rin(SOCvec(iSOC),Tvec(iT))

  end
end

Das einzige, was für dich jetzt noch zu tun bleibt ist FUNKTIONEN zu 
definieren, die OCV, Rin und delta_E berechnen. Nachdem du jetzt mit dem 
Code für die Berechnung von OCV rausgerückt hast, kann ich dir dann 
sogar schonmal ein Beispiel geben, wie das aussehen könnte:

Erstell im gleichen Ordner wie dein Skript eine Datei namens OCV.m in 
der das folgende steht:
function ret = OCV(SOC,T)
  ret = -1.1465*SOC^4 +3.1013*SOC^3 -2.3857*SOC^2+1.1115*SOC +3.4042

Fertig! Wenn du jetzt in der MATLAB Konsole OCV(0.,0.) eingibst, 
müsstest du den entsprechenden Wert für OCV bei SOC=0. bekommen. Keine 
Vektoren, keine Matrizen, einfach nur Zahlen, also alles ganz easy. Hier 
kannst du jetzt wenn du willst noch die Temperaturabhängigkeit einbauen.
Das gleiche (also zwei weitere Dateien mit entsprechenden Funktionen und 
Dateinamen) machst du jetzt noch für Rin und für delta_E. Wenn du das 
hast, kannst du obigen Code einfach direkt laufen lassen. Sollte dir 
dann I_Batt für alle Werte ausgeben. Wenn du willst, kannst du die 
Ausgabe auch noch etwas verschönern (doc disp).

Kannst dich natürlich auch beratungsresistent zeigen und auf dem Newton 
Iterationsding beharren. Hab aber ehrlich gesagt keine Lust, da 
irgendwas für dich zu debuggen, weil ichs wie schon erwähnt hier 
vollkommen sinnlos finde.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.