Hallo liebes Team,
ich habe ein Problem. Ich habe einen Servomotor und dafür eine
Steuerelektronik entworfen. In dem Servomotor ist ein Resolver verbaut.
Jetzt habe ich meine Steuerelektronik für eine Resolverperiode so
Programmiert das bei einer Periode des Resolvers einmal das Drehfeld
herum läuft. Jetzt kommt das Problem. Meine Maschine ist eine 6pol
Maschine aber der Resolver hat nur 2pole. Also habe ich für jede
Resolverperiode 3 Maschinenperioden! Jetzt stehe ich vor einer Mauer und
weiß nicht wie ich aus einer Resolverperiode so eben mal 3 mache!!! Hat
jemand eine Idee oder so etwas schon einmal gemacht?
Danke
Gruß TNTBC
Eine konkrete Lösung für Dich habe ich nicht, aber ich würde mal nach
dem Stichwort PLL suchen.
http://www.elektronik-kompendium.de/public/schaerer/pll4046.htm
Benötigst Du so etwas nicht sowieso für eine Drehzahlregelung?..oder wie
synchronisierst Du die beiden Drehfelder?
TNTBC schrieb:> Jetzt stehe ich vor einer Mauer und> weiß nicht wie ich aus einer Resolverperiode so eben mal 3 mache!!!
Winkel_elektrich = (Winkel_resolver * 3) % 360
Dein Resolver ist für deinen Motor ungünstig.
Volker
Hallo Ralf,
Ralf schrieb:> Benötigst Du so etwas nicht sowieso für eine Drehzahlregelung?..oder wie> synchronisierst Du die beiden Drehfelder?
Die Synchronisation erfolgt über das Resolversignal, da ich weiß in
welchen Sektor des 6 Quadrantenstellers ich mich befinde! und die
Berechnung der Tastverhältnisse gehen über ualpha und ubeta. Eine PLL
gibt mir ja nur die Frequenz des Jeweiligen Trägersignals aus. Das hilft
mir aber nicht weiter da ich dabei nicht weiß wie ich die Maschine jetzt
anzusteuern habe! Das weitere Problem der PLL ist, dass die Maschine
einmal gedreht haben muss um eine gültige Frequenz zu haben.
Ich habe eine Idee wie man es machen könnte wenn ich Sie rechnerische
bewiesen haben werde ich sie mal Posten aber dennoch sammelt weitere
Ideen
Danke dir Ralf
Gruß TNTBC
Hallo Volker
Volker Zabe schrieb:> Winkel_elektrich = (Winkel_resolver * 3) % 360
Die Variante kenne ich, allerdings müsste ich mir dann den Sinus und
Cosinus des Winkels neu errechnen und der Sinus und Cosinus des
Resolvers wären unbrauchbar! Oder?
Volker Zabe schrieb:> Dein Resolver ist für deinen Motor ungünstig.
Japp, nur ist er fest verbaut von Werksseite aus!!!
Gruß TNTBC
TNTBC schrieb:> Die Variante kenne ich, allerdings müsste ich mir dann den Sinus und> Cosinus des Winkels neu errechnen und der Sinus und Cosinus des> Resolvers wären unbrauchbar! Oder?
Ja!
Aber wie willst Du aus einem Sin/Cos-Signal 18(=3*6) Umschaltpunkte
generieren, ohne über den Winkel zu gehen?
Volker
Volker Zabe schrieb:> Aber wie willst Du aus einem Sin/Cos-Signal 18(=3*6) Umschaltpunkte> generieren, ohne über den Winkel zu gehen?
Genau vor dem Problem stehe ich gerade. Ich will aber kein Arctan
berechnen. Die Entscheidung der 6 Sektoren ging bis jetzt ganz gut ohne!
Wenn es jedoch eine schnelle Möglichkeit gibt den Arctan zu berechnen
dann werde ich darauf eingehen müssen!!
Gruß TNTBC
TNTBC schrieb:> Die Entscheidung der 6 Sektoren ging bis jetzt ganz gut ohne!
Das interessiert mich jetzt aber brennend. Wie hast du aus den 8
Segmenten des Sin/Cos-Signal (die man durch einfaches Vergleichen
erhält) die 6 Umschaltpunkte generiert?
> Wenn es jedoch eine schnelle Möglichkeit gibt den Arctan zu berechnen> dann werde ich darauf eingehen müssen!
Ja gibt es. Alles in Integer. Du teilst das Sin/Cos-Signal in 8
Segmenten (wie oben beschrieben) auf, der Quotient bildet dann ein Index
in einer Tabelle. Interpolieren brauchst du noch nicht einmal.
Anbei ein Beispiel für ein 3-Phasiges System.
Ist auch noch eine Wurzelberechnung drinnen.
Volker
Volker Zabe schrieb:> Das interessiert mich jetzt aber brennend. Wie hast du aus den 8> Segmenten des Sin/Cos-Signal (die man durch einfaches Vergleichen> erhält) die 6 Umschaltpunkte generiert?
Ich habe es aus einer Vorlesung von Prof. Hambrecht der Beuthochschule
Berlin. Ich habe ihn angefragt sobald er seine Zustimmung gibt werde ich
die Methode posten.
Volker Zabe schrieb:> Ja gibt es. Alles in Integer. Du teilst das Sin/Cos-Signal in 8> Segmenten (wie oben beschrieben) auf, der Quotient bildet dann ein Index> in einer Tabelle. Interpolieren brauchst du noch nicht einmal.
Die Frage ist, wenn ich jetzt zwei int16_t werte habe die um Null sind
und ich gebe es in deine Funktion ein, funktioniert diese dann auch? Und
was ist mit Werten über 30°. Ich bin ehrlich ich verstehe nicht was du
in der arctan Funktion machst!!! Kannst du das mal beschreiben?
Danke Gruß
TNTbc
TNTBC schrieb:> Kannst du das mal beschreiben?
Die Funktionen kannst du so nicht verwenden. Sie sind für ein
Drei-Phasen-System (120°- Versatz) gedacht.
- Du musst die Tabelle neu berechnen.
- Kannst die Interpolation vernachlässigen [ atan30() ].
(Du brauchst eine Auflösung von ca 10°, ich brauchte 0,01°)
Bei dir könnte es wahrscheinlich reichen, wenn du den Sinus im
ersten
Segment als linear ansiehst.
- Die Aufteilung der Segmente neu schreiben (360° -> 90°)[ Cal_Winkel()
].
Es ging ums Prinzip, wie man Winkelfunktionen mit Integer-Werten
berechnen kann. Dies sollte keine Vorgefertigte / Null-Denke Lösung
sein!
Drei-Phasen kann man (durch einfaches Vergleichen(siehe Cal_Winkel())
auf 12 Segmente aufteilen -> 30°. Das geht bei dir nicht.
Volker
Ok ich gebe es zu ich bin zu tum für den Code!!!!
Ich verstehe die Tabelle und den Ansatz nicht. Kannst du mir eine Seite
oder irgendetwas geben um es besser zu verstehen??
Gruß TNTBC
Hallo,
damit ich die Sache hier richtig beende!
hier meine Lösung für den atan2. Danke an die Seite
http://www.dsprelated.com/showmessage/10922/1.php
Die Einheit benötigt laut Simulator:2388clk
Im definitionbereich 0 <= alpha < 180;
1
int16_ti_atan2(int16_ty,int16_tx)
2
{
3
int16_tresult=0;
4
int16_ty2;
5
6
if((x|y)==0)
7
return0;/* give up */
8
9
if(y<0)/* if we point downward */
10
{
11
result+=-180;
12
y=-y;
13
x=-x;
14
}
15
if(x<0)/* if we point left */
16
{
17
result+=90;
18
y2=y;
19
y=-x;
20
x=y2;
21
}
22
if(y>x)/* 45 degrees or beyond */
23
{
24
result+=45;
25
y2=y;
26
y-=x;
27
x+=y2;
28
}
29
if(2*y>x)/* 26.565 degrees */
30
{
31
result+=26.565;
32
y2=y;
33
y=2*y-x;
34
x=2*x+y2;
35
}
36
if(4*y>x)/* 14.036 degrees */
37
{
38
result+=14.036;
39
y2=y;
40
y=4*y-x;
41
x=4*x+y2;
42
}
43
if(8*y>x)/* 7.125 degrees */
44
{
45
result+=7.125;
46
y2=y;
47
y=8*y-x;
48
x=8*x+y2;
49
}
50
51
/* linear interpolation of the remaining 64-ant */
TNTBC schrieb:> Kannst du mir eine Seite> oder irgendetwas geben um es besser zu verstehen?
Im Prinzip macht mein Code das Gleiche wie deiner. Aber viel feiner
(mehr Nachkommastellen), die du aber nicht brauchst und auf 3-Phasen
ausgelegt.
Durch die implizite Skalierung (Stichwort: Festpunkt-Arithmetik) ist der
Code schlechter Nachtvollzierbar. Aber ich Versuchs mal:
Würde man den COS-Wert durch den SIN-Wert im Bereich 0-45° teilen ergäbe
das ein Wertebereich von 0-1. Dies ist in Integer nicht darstellbar.
Deshalb verschiebe ich den Bereich um 16 Bit (*0x10000).
Jetzt habe ich den Wertebereich von 0 bis 65535.
Jetzt muss ich den Wertebereich auf meine Stützstellen in der Tabelle
aufteilen. Ich dividiere durch 5041 (65536/13), so erhalte ich ein
Index von 0 bis 12. Eine höhere Anzahl an Stützstellen ergaben keine
höhere Genauigkeit.
Damit hole ich mir den Stützstellenwert aus der Tabelle. Die
Interpolation zwischen den Stützstellen ist etwas ungewöhnlich, Der
Faktor ist nicht die Steigung zwischen den Stützstellen, sondern die
Steigung von Null durch die Stützstelle. Erspart einige Rechnungen zur
Laufzeit.
Die Werte in der Tabelle sind so berechnet, das sie mir meinen Winkel in
0.01° mal 0x10000 ergeben. Das ergibt eine große Anzahl von
Nachkommastellen bei den Rechnungen und damit einen kleinen
Rundungsfehler. Des halb teile ich zum Schluss noch durch 0x10000.
Ich hoffe es ist damit etwas klarer. Volker
Nachtrag:
Hallo TNTBC,
deine gepostete Funktion rechnet im Bereich 22,2 bis 26.5° bis zu -9,5°
Falsch. Auch liefert sie nie das Ergebnis 1°.
TNTBC schrieb:> result += 26.565;
Du addierst eine double zu einem int16_t.
Welchen Sinn macht das denn? Schaltest du immer die Compiler-Warnung ab?
Annsonsten (wenn der Fehler gefunden wurde) eine nette kleine
arctan-Funktion mit einem Fehler von +/- 1°.
Volker
Hat mir ja keine Ruhe gelassen. Habe den Fehler gefunden und noch paar
Kleinigkeiten geändert.
Der Vergleich mit 8*y>x hat mehr Fehler produziert, als Genauigkeit
gebracht.
Eine Fixpoint Nachkommastelle und eine richtige Rundung brachten den
Rest.
Der maximale Fehler liegt jetzt bei - 0,6° / +0,7°.
Im Anhang meine Testfunktion.
1
#define FP 2
2
3
shorti_atan2(shortsinw,shortcosw)
4
{
5
shortresult=0;
6
shorttemp;
7
8
if((cosw|sinw)==0)
9
{
10
return0;/* give up */
11
}
12
13
if(sinw<0)/* 180 - 360 */
14
{
15
result=180*FP;
16
sinw=-sinw;
17
cosw=-cosw;
18
}
19
if(cosw<0)/* 90 - 180 */
20
{
21
result+=90*FP;
22
temp=sinw;
23
sinw=-cosw;
24
cosw=temp;
25
}
26
if(sinw>cosw)/* 45 - 90 */
27
{
28
result+=45*FP;
29
temp=sinw;
30
sinw-=cosw;
31
cosw+=temp;
32
}
33
if(2*sinw>cosw)/* 26.565 degrees - 45 */
34
{
35
result+=(short)(26.565*FP);
36
temp=sinw;
37
sinw=2*sinw-cosw;
38
cosw=2*cosw+temp;
39
}
40
if(4*sinw>cosw)/* 14.036 degrees - 26.565 */
41
{
42
result+=(short)(14.036*FP);
43
temp=sinw;
44
sinw=4*sinw-cosw;
45
cosw=4*cosw+temp;
46
}
47
48
/* linear interpolation of the remaining 64-ant */