Forum: Projekte & Code 3 Phasen 0-80Hz Sinusgenerator


von Karl Z. (griffin27)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab mich die letzte Zeit mit der erzeugung von 3-Phasen 
Wechselspannung beschäftigt. Das ganze sollte möglichst effizient von 
statten gehen.

Zielhardware ist ein ARM7 von Atmel (AT91SAM7A3).

Eine Lookuptable für die Sinusberechnung schien mir im Vergleich zur 
Taylorreihenentwicklung nicht viel einfacher.

Daher war mein erster Versuch die Taylorreihenentwicklung. Vorerst 
rechnete ich mit float.
Damit schaffte ich bei 48MHz Systemtakt eine Zykluszeit von gut 230us. 
Das war mir viel zu langsam, da ich eine Samplerate von 10kHz angepeilt 
hatte.

Somit implementierte ich die Berechnungen mit fixed point (Format: 
1.15.16).
Damit verringerte sich die Zykluszeit auf 122us.

Heut kam mir die Idee, eine Differentialgleichung, die eine harmonische 
Lösung hat, nummerisch zu Lösen --> astreine sinuouide Schwingung durch 
rekursive Berechnung zu jedem Zeitschritt.
Ich zog die DGL x_2punkt + x = 0 heran.
Ein wenig mit Octave herumprobiert und den Code auf das notwendigste 
heruntergebrochen. Damit ist nun eine Zykluszeit von 17.3us möglich - 
und das ohne Kompileroptimierung (arm-elf-gcc).

So wie der Code nun ist, kann eine Frequenz von 0-80Hz eingestellt 
werden.
Durch Anpassen der Multiplikationen von omega*T kann der Bereich 
natürlich erweitert werden. Es muss halt darauf geachtet werden, dass es 
zu keinem Überlauf bei der Multiplikation kommt.

Bei der letzten Variante hat man auch den Vorteil, dass die Frequenz zu 
jedem beliebigen Zeitpunkt geändert werden kann, ohne Sprünge in dem 
Kurvenverlauf hervorzurufen.

lg, Karl

von Max (Gast)


Lesenswert?

Hallo Karl,

1.
Mit einem C-Programm ein Sinustabelle erstellen.
Siehe Tabgen.cpp

2.
Erzeugte Sinustabelle in das yC einkopieren.

3.
Im Interrupt auf die Tabelle zugreifen.
Mit mehr Stellen z.B. I16 pro Interupt incrementieren als für den 
Tabellenzugriff nötig ist. dadurch erhält man eine feine 
Frequenzauflösung.

4. PWM Register setzen.
Das geht sogar mit Mega8. 2 Vergleichregister vom Timer 1 und eines von 
Timer 2

von Max (Gast)


Angehängte Dateien:

Lesenswert?

Ergänzung:
C_Source im Anhang
________________________________

Sinustabelle

___________________________________

#define N 768
flash char sintab[] ={  127, 127, 128, 129, 130, 131, 132, 133, 134, 
135,
 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
 156, 157, 158, 159, 159, 160, 161, 162, 163, 164,
 165, 166, 167, 168, 169, 170, 171, 172, 172, 173,
 174, 175, 176, 177, 178, 179, 180, 180, 181, 182,
 183, 184, 185, 186, 186, 187, 188, 189, 190, 191,
 192, 192, 193, 194, 195, 196, 196, 197, 198, 199,
 200, 200, 201, 202, 203, 203, 204, 205, 206, 206,
 207, 208, 209, 209, 210, 211, 211, 212, 213, 213,
 214, 215, 215, 216, 217, 217, 218, 219, 219, 220,
 220, 221, 222, 222, 223, 223, 224, 225, 225, 226,
 226, 227, 227, 228, 228, 229, 229, 230, 230, 231,
 231, 232, 232, 233, 233, 234, 234, 235, 235, 235,
 236, 236, 237, 237, 237, 238, 238, 238, 239, 239,
 239, 240, 240, 240, 241, 241, 241, 242, 242, 242,
 242, 243, 243, 243, 243, 244, 244, 244, 244, 244,
 245, 245, 245, 245, 245, 245, 245, 246, 246, 246,
 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
 246, 246, 247, 246, 246, 246, 246, 246, 246, 246,
 246, 246, 246, 246, 246, 246, 246, 246, 245, 245,
 245, 245, 245, 245, 245, 244, 244, 244, 244, 244,
 243, 243, 243, 243, 242, 242, 242, 242, 241, 241,
 241, 240, 240, 240, 239, 239, 239, 238, 238, 238,
 237, 237, 237, 236, 236, 235, 235, 235, 234, 234,
 233, 233, 232, 232, 231, 231, 230, 230, 229, 229,
 228, 228, 227, 227, 226, 226, 225, 225, 224, 223,
 223, 222, 222, 221, 220, 220, 219, 219, 218, 217,
 217, 216, 215, 215, 214, 213, 213, 212, 211, 211,
 210, 209, 209, 208, 207, 206, 206, 205, 204, 203,
 203, 202, 201, 200, 200, 199, 198, 197, 196, 196,
 195, 194, 193, 192, 192, 191, 190, 189, 188, 187,
 186, 186, 185, 184, 183, 182, 181, 180, 180, 179,
 178, 177, 176, 175, 174, 173, 172, 172, 171, 170,
 169, 168, 167, 166, 165, 164, 163, 162, 161, 160,
 159, 159, 158, 157, 156, 155, 154, 153, 152, 151,
 150, 149, 148, 147, 146, 145, 144, 143, 142, 141,
 140, 139, 138, 137, 136, 135, 134, 133, 132, 131,
 130, 129, 128, 127, 127, 126, 125, 124, 123, 122,
 121, 120, 119, 118, 117, 116, 115, 114, 113, 112,
 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
 101, 100, 99, 98, 97, 96, 95, 94, 94, 93,
 92, 91, 90, 89, 88, 87, 86, 85, 84, 83,
 82, 81, 81, 80, 79, 78, 77, 76, 75, 74,
 73, 73, 72, 71, 70, 69, 68, 67, 67, 66,
 65, 64, 63, 62, 61, 61, 60, 59, 58, 57,
 57, 56, 55, 54, 53, 53, 52, 51, 50, 50,
 49, 48, 47, 47, 46, 45, 44, 44, 43, 42,
 42, 41, 40, 40, 39, 38, 38, 37, 36, 36,
 35, 34, 34, 33, 33, 32, 31, 31, 30, 30,
 29, 28, 28, 27, 27, 26, 26, 25, 25, 24,
 24, 23, 23, 22, 22, 21, 21, 20, 20, 19,
 19, 18, 18, 18, 17, 17, 16, 16, 16, 15,
 15, 15, 14, 14, 14, 13, 13, 13, 12, 12,
 12, 11, 11, 11, 11, 10, 10, 10, 10, 9,
 9, 9, 9, 9, 8, 8, 8, 8, 8, 8,
 8, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 7, 7, 8, 8, 8, 8, 8, 8, 8, 9,
 9, 9, 9, 9, 10, 10, 10, 10, 11, 11,
 11, 11, 12, 12, 12, 13, 13, 13, 14, 14,
 14, 15, 15, 15, 16, 16, 16, 17, 17, 18,
 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
 28, 28, 29, 30, 30, 31, 31, 32, 33, 33,
 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
 40, 41, 42, 42, 43, 44, 44, 45, 46, 47,
 47, 48, 49, 50, 50, 51, 52, 53, 53, 54,
 55, 56, 57, 57, 58, 59, 60, 61, 61, 62,
 63, 64, 65, 66, 66, 67, 68, 69, 70, 71,
 72, 73, 73, 74, 75, 76, 77, 78, 79, 80,
 81, 81, 82, 83, 84, 85, 86, 87, 88, 89,
 90, 91, 92, 93, 94, 94, 95, 96, 97, 98,
 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
 119, 120, 121, 122, 123, 124, 125, 126};

von Karl Z. (griffin27)


Lesenswert?

Ist der Generator länger im Betrieb, so driften die Phasenlagen der 3 
Spannungen. Ich hatte eine Drift von bis zu 61°/h gemessen, was völlig 
inakzeptabel ist.

Dies kann nur aufgrund von Rechenfehlern der Fall sein.
Daher werde ich noch einen "Phasenregler" implementieren....

Wie gesagt, das mit der Lookup Table gefällt mir einfach nicht wirklich. 
Das stetige Ändern der Frequenz ist mit der Tabelle auch wieder ein 
Rechenaufwand.

Achja, ich hatte vergessen zu erwähnen, dass der Sinus-Generator mit 
einer Samplerate von 8.192kHz läuft.

lg, Karl

von Benedikt K. (benedikt)


Lesenswert?

Karl Zeilhofer wrote:
> Das stetige Ändern der Frequenz ist mit der Tabelle auch wieder ein
> Rechenaufwand.

Wenn man es richtig macht nicht:
Eine feste Sinustabelle im Flash, z.B. 256 Werte groß und dann nach dem 
DDS Prinzip auslesen. Da schafft ein AVR rund >1MS/s.
Die Frequenzänderungen ist dann lediglich eine Änderung des Wertes der 
in jedem Takt zum Akkumulator addiert wird.

von appleman (Gast)


Lesenswert?

Man müsste die DGL so modifzieren, dass es nicht 3 unabhängige sind 
sondern ein Gleichungssystem, dass gleich alle 3 Phasen auf einmal 
erreichnet. Außerdem müsste man irgend einen nichtlinearen Dämfungsterm 
einbauen, der dafür sorgt, dass sich die Sache stabilisiert.

Die Frage ist nur, wie findet man so ein System? Normalerweise lernt man 
wie man gegebene DGL löst, denn umgekehrten Weg geht keiner.

mfg appleman

von Karl Z. (griffin27)


Lesenswert?

Danke für deine Anregung, Appleman.
Klingt vernünftig. Aber ob ich solch ein DGL-System finde?

Hab mir nun DDS mal genauer aungeschaut. Sieht eigentlich auch recht 
interessant aus. Mal schauen, was es wird und vielen Dank auf jeden mal 
euch allen.

von Thomas S. (Gast)


Lesenswert?

Hab sowas schon mal für ne Anwendung gemacht. DDS und die 3 Phasen mit 
dem festen Versatz aus der Tabelle lesen. Dann passt es immer und nix 
kann driften. Wenn die Phasen einstellbar sein sollen, eben 3 x DDS.

Gruß Thomas

von Christian B. (casandro)


Lesenswert?

appleman wrote:

> Die Frage ist nur, wie findet man so ein System? Normalerweise lernt man
> wie man gegebene DGL löst, denn umgekehrten Weg geht keiner.

Ähm, im Prinzip relativ einfach. Du würdest zunächst eine DGL brauchen, 
welche Dir Deinen Sinus macht. x''-x=0 oder so was ist das.

x' ist im Prinzip eine Verschiebung Deines Signales um +90°. x ist Dein 
Signal. Wenn Du nun beide mit bestimmten Faktoren addierst, so kannst Du 
jeden Phasenwinkel erreichen. (zumindest beim reinen Sinus)

DDS ist aber viel vernünftiger.

von Karl Z. (griffin27)


Lesenswert?

Christian, danke für deinen Hinweis!
Ich weiß nicht, warum mir das nicht selbst eingefallen ist.

Hab das gestern umgesetzt und nun ist alles prima.

Ich finde den Code recht genial, weil er extrem schnell ist, und 
gleichzeitig sehr wenig Speicher braucht.

Die Amplitude bleibt, über einige Stunden getestet, völlig stabil.
Die Rechenfehler scheinen sich zu kompensieren.

Warum DDS für diese Anwendung viel vernünftiger sein sollte, verstehe 
ich nicht. Für mich ist das doch die perfekte Lösung.

lg, Karl

von Benedikt K. (benedikt)


Lesenswert?

Karl Zeilhofer wrote:

> Warum DDS für diese Anwendung viel vernünftiger sein sollte, verstehe
> ich nicht. Für mich ist das doch die perfekte Lösung.

Auf einem ARM dürfte es egal sein. Wenn genug Rechenpower zur Verfügung 
steht, ist deine Lösung definitiv sehr interessant, da man damit 
bestimmt auch noch andere Sachen machen kann.
DDS hat halt den Vorteil, dass es nahezu keine Rechenleistung braucht:
In jedem Schritt ist nur eine Addition und ein Tabellenauslesen 
erforderlich. Das kann jeder noch so dumme µC.

von Christian B. (casandro)


Lesenswert?

Karl Zeilhofer wrote:

> Warum DDS für diese Anwendung viel vernünftiger sein sollte, verstehe
> ich nicht. Für mich ist das doch die perfekte Lösung.

Da hast Du absolut stabile Amplituden und kannst die Frequenz und 
Amplitude sehr einfach einstellen. Du brauchst ja im Prinzip nur einen 
4-tel-Kreis speichern, der Rest ergibt sich durch die Symmetrie.

von Karl Z. (griffin27)


Lesenswert?

Christian Berger wrote:
> Da hast Du absolut stabile Amplituden und kannst die Frequenz und
> Amplitude sehr einfach einstellen.

Genau das gleiche erreiche ich mit meiner Lösung auch.
Dass die Amplitude stabil bleib würde sich vielleicht sogar mathematisch 
beweisen lassen, ich kanns halt (vermutlich ;-) ) nicht.

Ich frage micht, ob es nicht vielleicht eh schon einen Namen für diese 
Technik gibt. Ich bin ja vermutlich nicht der erste, der das so gemacht 
hat.

von Christian B. (casandro)


Lesenswert?

Karl Zeilhofer wrote:
> Christian Berger wrote:

> Genau das gleiche erreiche ich mit meiner Lösung auch.
> Dass die Amplitude stabil bleib würde sich vielleicht sogar mathematisch
> beweisen lassen, ich kanns halt (vermutlich ;-) ) nicht.

In der Theorie bleibt die Amplitude perfekt stabil. Das ergibt sich 
einfach durch die Schleifenverstärkung bei der Resonanzfrequenz. Nur was 
die Quantisierung da macht kann nicht wirklich gut allgemein 
vorhersagen. Zusätzlich musst Du für die Änderung der Frequenz 
mindestens an 2 Parametern drehen, wenn die Amplitude gleich bleiben 
soll.

Bei DDS hast Du immer garantierte gleichbleibende Amplituden, und Du 
hast nur einen Punkt an dem Du drehen musst. Nebenbei kannst Du 
gleichzeitig auch noch phasenverschobene Signale bekommen, ohne dass Du 
da groß rumrechnen musst.

Wenn Du es schaffst, am Ausgang für jede Frequenz eine Amplitude von 1/2 
Vollausschlag stabil mit 3 Phasen herzustellen, dann merkst du warum DDS 
einfacher ist.

> Ich frage micht, ob es nicht vielleicht eh schon einen Namen für diese
> Technik gibt. Ich bin ja vermutlich nicht der erste, der das so gemacht
> hat.

Im Prinzip ist das so, wie einfache analoge Oszillatoren für Sinus mit 
Audiobereich funktioniert haben. Da hast Du im Prinzip immer einen 
Verstärker. Dieser Verstärker wird nun so rückgekoppelt, dass die 
Rückkopplungsschleife und er (also die aufgeschnittene Schleife) (nur) 
bei der Resonanzfrequenz eine Verstärkung von genau 1 aufweist. Ist die 
Verstärkung nur minimal größer als 1, so wird die Amplitude schnell 
größer und der Verstärker übersteuert. Ist die Amplitude kleiner, so 
endet die Schwingung bald. Damit das irgendwie praktikabel ist, hat man 
dafür ein nicht-lineares Element drin, welches die Amplitude begrenzt. 
Entweder relativ hart mit Dioden, oder sehr weich mit einer Glühlampe. 
Mit Glühlampen bekommt man sehr geringe Klirrfaktoren hin.

von Benedikt K. (benedikt)


Lesenswert?

Christian Berger wrote:

> Bei DDS hast Du immer garantierte gleichbleibende Amplituden, und Du
> hast nur einen Punkt an dem Du drehen musst. Nebenbei kannst Du
> gleichzeitig auch noch phasenverschobene Signale bekommen, ohne dass Du
> da groß rumrechnen musst.

Genau. Man muss nur einen zusätzlichen Wert auf den Tabellenpointer 
addieren + den eventuell auftretenden Überlauf korrigieren.

Wenn ich richtig gerechnet habe, dann benötigt die Software rund 5800 
Takte für die Berechnungen. Mittels DDS dürfte das ganze mindestens um 
den Faktor 10 schneller sein.

Hier mal ein Teilcode aus einer Software zur Ansteuerung eines 3 Phasen 
Motors mittels DDS:
sine ist eine 256 Byte große Sinustabelle (aus Gründen der Einfachheit, 
die ersten 64 Werte würden auch reichen, wenn man die entsprechend 
spiegelt):
1
static unsigned short phaseacc;
2
unsigned char phase;
3
4
phaseacc+=freq;
5
phase=phaseacc/256;
6
7
PWM0=powerset*(signed char)sine[phase]/16;
8
phase+=85;
9
PWM1=powerset*(signed char)sine[phase]/16;
10
phase+=85;
11
PWM2=powerset*(signed char)sine[phase]/16;

von Christian B. (casandro)


Lesenswert?

Benedikt K. wrote:

> sine ist eine 256 Byte große Sinustabelle (aus Gründen der Einfachheit,
> die ersten 64 Werte würden auch reichen, wenn man die entsprechend
> spiegelt):

Du brauchst, um die volle Auflösung nutzen zu können mindestens n*pi 
Amplitudenstufen als Größe für Deine Sinustabelle.

Wenn Dein A/D-Wandler beispielsweise 8 Bit hat und somit 256 Stufen 
macht (128 auf jeder Seite von 0), so brauchst Du 256*pi<=804 Werte in 
Deiner Tabelle, sonst springt Dein Wert. Natürlich wird man dann eine 
1024-er Tabelle verwenden, die Du Durch Spiegelung auf 256 Werte 
reduziert speichern kannst.

Willst Du Speicherplatz sparen, beispielsweise wenn Du einen 16-Bit 
Wandler hast, so kannst Du die Tabelle auch durch einen Polynomialterm 
ersetzen.

von Karl Z. (griffin27)


Lesenswert?

Christian,
die analogen Oszillatoren sind mir wohl bekannt.
Beim analogen hat man ja immer irgendwelche Temperaturabhängigkeiten.
Beim digitalen eben nicht.
1
// calculate L1_0 = cos(omega*t + phi) recursive
2
// it is the numeric solution of the differential equation
3
// x''(t) + x(t) = 0
4
// initialized with L1_0=0 and L1_1=1
5
L1_1 = L1_1 - (FMUL(L1_0, FMUL(T,omega,0,0)>>16,1,0)>>15);
6
L1_0 = L1_0 + (FMUL(L1_1, FMUL(T,omega,0,0)>>16,1,0)>>15);
7
8
// L2_0 = -0.5*L1_0 - sqrt(3)/2*L1_1;
9
// L3_0 = -0.5*L1_0 - - sqrt(3)/2*L1_1;
10
L2_0 = -(L1_0>>1) - (FMUL((int32_t)(0.8660254*DENUM),L1_1,1,1)>>14);
11
L3_0 = -(L1_0>>1) + (FMUL((int32_t)(0.8660254*DENUM),L1_1,1,1)>>14);

Benedikt, diese 4 Zeilen benötigen keine 5800 Takte. Ich weiß nicht, wie 
du auf diese Zahl gekommen bist. Hab jetzt mit dem Oszi nachgemessen, 
und es sind nur 105 Takte.
1
L1=FMUL(gain,L1_0,1,1)>>14;
2
L2=FMUL(gain,L2_0,1,1)>>14;
3
L3=FMUL(gain,L3_0,1,1)>>14;

Die Multiplikation mit dem Gain benötigt nochmals 49 Takte.
In Summe also 154 Takte, oder anders gesagt 3.33us bei 48MHz.

FMUL ist in meinem Fall ein Fixed-Point-Multiplikations-Makro.

Ich muss zugeben, dass DDS wahrscheinlich noch ein Stückchen schneller 
ist. Aber ein Faktor 10 wirds wohl nicht werden.

lg, Karl

von Christian B. (casandro)


Lesenswert?

Karl Zeilhofer wrote:
> Christian,
> die analogen Oszillatoren sind mir wohl bekannt.
> Beim analogen hat man ja immer irgendwelche Temperaturabhängigkeiten.
> Beim digitalen eben nicht.

Dafür hast Du da Quantisierungsrauschen was sehr unvorhersehbar ist.

> Ich muss zugeben, dass DDS wahrscheinlich noch ein Stückchen schneller
> ist. Aber ein Faktor 10 wirds wohl nicht werden.

Ich hab auf einem AtMega 16 mal eine FM-Synthese gemacht, da waren 2 
DDSen drin. Die hat pro Abtastwert so um die 20 Taktzyklen gebraucht. 
Somit bist Du bei ungefähr 10 Taktzyklen pro DDS. Das ist Faktor 10 mal 
schneller. Auf dem ARM geht das bestimmt sogar noch viel schneller, da 
der 32-Bit direkt verarbeiten kann.

> lg, Karl

von Karl Z. (griffin27)


Lesenswert?

> Dafür hast Du da Quantisierungsrauschen was sehr unvorhersehbar ist.
Richtig und des Rauschens Mittelwert ist 0 -> kein Offsetfehler wie zB 
im Analogen. Daher driftet vermutlich die Amplitude nicht.

Ich hab nun mit dem Multimeter (Fluke 189) den RMS-Wert gemessen, wobei 
selbst nach 20 Minuten absolut keine übergeordnete Drift feststellbar 
ist. Dabei habe ich eine auf 5 Kommastellen genaue Anzeige.

Maximum: 1420.1 mVeff
Minimum: 1414.0 mVeff
Average: 1418.0 mVeff

Minimum und Maximum stellen sich recht schnell ein. Ca. innerhalb von 3 
Minuten. Daraus kann man auf ein leichtes Schwanken (4.3 Promill) 
schließen, das vermutlich von den Rechenfehlern herrührt. Doch der 
übergeordnete Trend ist 0.


Für DDS mit einem 12 Bit DAC braucht man, um wirklich jeden DAC-Wert 
erreichen zu können (--> maximaler Signal-Rauschabstand), eine Tabelle 
mit 2^(12-1)*2*pi = 12868 Werten. Auf die nächste 2er Potenz aufgerundet 
kommt man also auf 16384 Werte. Das ergibt für short-Werte 32kByte, was 
nicht gerade wenig Speicher ist.


Summa summarum kann man sagen, dass DDS wirklich schnell ist, aber ab 
einer gewissen Genauigkeit sehr viel Speicher benötigt.
Mein Algorithmus ist hingegen immer noch sehr schnell, benötigt aber 
quasi keinen Speicher.

lg, Karl

von Christian B. (casandro)


Lesenswert?

Karl Zeilhofer wrote:
>> Dafür hast Du da Quantisierungsrauschen was sehr unvorhersehbar ist.
> Richtig und des Rauschens Mittelwert ist 0 -> kein Offsetfehler wie zB
> im Analogen. Daher driftet vermutlich die Amplitude nicht.

In Deiner momentanen Situation mag das stimmen, wenn jetzt aber irgendwo 
eine Nachkommastelle anders gerundet wird, beispielsweise wenn Dein 
Assembler eine Kommazahl plötzlich anders binär darstellt.

> Minimum und Maximum stellen sich recht schnell ein. Ca. innerhalb von 3
> Minuten. Daraus kann man auf ein leichtes Schwanken (4.3 Promill)
> schließen, das vermutlich von den Rechenfehlern herrührt. Doch der
> übergeordnete Trend ist 0.

OK, probier jetzt mal noch die Frequenz zu verändern.


> Für DDS mit einem 12 Bit DAC braucht man, um wirklich jeden DAC-Wert
> erreichen zu können (--> maximaler Signal-Rauschabstand), eine Tabelle
> mit 2^(12-1)*2*pi = 12868 Werten. Auf die nächste 2er Potenz aufgerundet
> kommt man also auf 16384 Werte. Das ergibt für short-Werte 32kByte, was
> nicht gerade wenig Speicher ist.

Ähm, wenn Du 2 Bytes pro Abtastwert verwendest. So hast Du zwar für den 
kompletten Sinus 32kByte, aber Du musst ja nur ein Viertel speichern, 
und somit 8kByte.

Willst Du noch mehr sparen, so kannst Du den Viertelsinus auch noch 
einfach binomial annähern. Da solltest Du mit wenigen Additionen und 
Multiplikationen das sehr genau erhalten.

> Summa summarum kann man sagen, dass DDS wirklich schnell ist, aber ab
> einer gewissen Genauigkeit sehr viel Speicher benötigt.
> Mein Algorithmus ist hingegen immer noch sehr schnell, benötigt aber
> quasi keinen Speicher.

Dafür ist er aber auch nicht genau. Selbst die Frequenz ist nicht 
unbedingt genau definiert.

> lg, Karl

von Benedikt K. (benedikt)


Lesenswert?

Karl Zeilhofer wrote:

> Für DDS mit einem 12 Bit DAC braucht man, um wirklich jeden DAC-Wert
> erreichen zu können (--> maximaler Signal-Rauschabstand), eine Tabelle
> mit 2^(12-1)*2*pi = 12868 Werten. Auf die nächste 2er Potenz aufgerundet
> kommt man also auf 16384 Werte. Das ergibt für short-Werte 32kByte, was
> nicht gerade wenig Speicher ist.

Ein 3-Phasen Sinus wird fast immer für eine Motoransteuerung gebraucht. 
Und dem ist es ziemlich egal, ob er 0,0001%, 1% oder gar 10% THD 
bekommt. Selbst mit 4bit DAC Auflösung wird der Motor vermutlich noch 
ziemlich rund laufen.

Ich denke es läuft darauf hinaus, dass ein DDS für einfache Sachen bei 
weitem ausreichend ist, auch mit kleinen Sinustabellen. Wenn es genauer 
werden soll, dann dürfte deine Lösung Vorteile bieten. Wobei man auch da 
mal analysieren müsste, wieviele Bits effektiv nutzbar sind.

von Karl Z. (griffin27)


Lesenswert?

Christian Berger wrote:
>> Minimum und Maximum stellen sich recht schnell ein. Ca. innerhalb von 3
>> Minuten. Daraus kann man auf ein leichtes Schwanken (4.3 Promill)
>> schließen, das vermutlich von den Rechenfehlern herrührt. Doch der
>> übergeordnete Trend ist 0.
>
> OK, probier jetzt mal noch die Frequenz zu verändern.

So, jetzt hast du mich erwischt!
Hab jetzt Potis an den ADC des Controllers angeschlossen, um Amplitude 
und Frequenz einzustellen.

Ändert man die Frequenz ändert sich auch die Amplitude ein wenig. Sie 
scheint sich mehr oder weniger linear mit der Frequenz direkt 
proportional zu ändern.

Hab nun als Frequenzbereich 10-80Hz. Über den ganzen Bereich ändert sich 
die Spannung von 1,00Veff (bei 10Hz) auf ca. 1.15Veff (bei 80Hz).
Ausgehend von 500mVeff ändert sich die Spannung sogar um satte +34%.


So wie es nun aussieht werde ich doch die DDS verwenden ;-)
Ich habe den Ansatz einfach sehr interessant gefunden und habe damit 
sicherlich einiges gelernt!

Vielen Dank euch allen für eure Mithilfe und Kommentare.

Schönen Abend noch,
Karl

von Christian B. (casandro)


Lesenswert?

Ja, Du kannst ja die Tabelle, wie bereits erwähntm vierteln.

von Karl Z. (griffin27)


Lesenswert?

Hab jetzt DDS mit einer Tabelle mit 1024 16-Bit Werten implementiert. 
Das Spiegeln hab ich mir erspart, da ich sowieso genug Speicher zur 
Verfügung habe.
Siehe da, gleiches Verhalten!

Es stellte sich heraus, dass der ADC, der die Potis einliest, zu schnell 
eingestellt war für die gegebene Quellimpedanz (47k Potis). Somit 
brachte eine Änderung des einen Kanals auch eine Änderung des anderen 
Kanals mit sich. - peinlicher Fehler samt Missinterpretation ;-)

Jetzt hab ich beide Methoden im Programm und kann, wenns mir gefällt 
zwischen den beiden wechseln. Werde aber vermutlich doch DDS nehmen, da 
es bei dieser nix unerwartetes geben kann.

lg, Karl

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.