www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sinus - Cosinusgenerator, low frequency


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich suche schon seit Tagen im Internet, finde aber einfach nichts 
passendes. Ich brauche einen Sinus - Cosinus Generator mit 0,5 bis 2 
Hertz.
Ausser der Idee einen uC mit 2 D/A Wandlern zu nehmen ist mir nichts 
weiter eingefallen.

Autor: Andreas Thanheiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servas.
Mir fällt da spontan ein einfacher RC-Oszillator (Wien-Brücke) ein, der 
das Sinus-Signal macht. Daran anschließend einen Integrator fürs 
Cosinus-Signal.

/
| sin(x) dx = -cos(x) + C
/

Die Integrator-Schaltung mit Operationsverstärker is eh invertierend, 
also würds wieder passen.
Ob sich allerdings mit ner Wien-Brücke Frequenzen um 1Hz rum realisieren 
lassen weiß ich nicht.

Andreas

Autor: Christoph Kessler (db1uq) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt eine Schaltung mit mehreren OPs und Phasenschiebern, zum 
Beispiel hier auf Seite 11::
http://www.home.fh-karlsruhe.de/~kero0001/sinus/sinosz4.pdf

(der Prof heißt nur zufällig auch so, ist nicht mit mir verwandt)

Man könnte dazu vielleicht auch ein integriertes "state variable filter" 
wie den UAF42 von BurrBrown/ TI verwenden, indem man es passend 
rückkoppelt.
http://focus.ti.com/lit/ds/symlink/uaf42.pdf

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<<Ausser der Idee einen uC mit 2 D/A Wandlern zu nehmen ist mir nichts
weiter eingefallen.>>

Einen besseren Einfall konntest Du nicht haben :-)
Die DA-Wandler kannst Du bei so niedrigen Frequenzen bequem mit PWM 
realisieren.

Autor: Alf Sch (alfsch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..oder 2 träger frequenzen auf nen mischer = lf out.
ich rate mal: genauigkeit, klirr, phasenwinkel...??

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt keine grossartigen Anforderungen an die Genauigkeit usw. 
Lediglich die Phasenlage der beiden Signale muss stimmen. Das ganze soll 
ein Signalgeber zur Entwicklung eines Messgeraetes geben. Wobei 
Messgeraet hier nicht wortwoertlich zu nehmen ist.
Der eigentliche Sensor sitzt irgendwo an einer Maschine, die waehrend 
der Entwicklung zwar zur Verfuegung steht, aber die Arbeitsbedingungen 
sind da natuerlich nicht optimal (Laut, kalt, weit weg)
Ich denke das einfachste ist ich nehme einen ATMega8, doppel 10bit D/A, 
generiere einen Sinus-lookup table, und gut ist.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@peter

ich würde auch einen uC nehmen. ob man als d/a wandler nun nen pwm oder 
r2r oder sonstwas nimmt ist eigentlich egal.
wenns nicht allzu hohe anforderungen hat würde ich pwm nehmen.
die kosten dürften mit einem atTiny und ein wenig beschaltung (4-6 
kondensatoren, 2-3 widerstände, quarz) auch recht niedrig liegen.
ich denke das ganze analog aufbauen geht zwar auch, wobei ich da eher 
das problem der genauigkeit bzw. stabilität (temperatur) sehe, die man 
mit einem uC einfach umgehen kann.

gruß
rene

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Wenn Du 'nen Mega8 nehmen willst, benutze einfach die beiden PWM Kanäle 
vom Timer1 geht bis 16bit ;)
Dann noch einen Tiefpaß oder besser Bessel o.ä. an die Pins und gut is 
;)
Könntest z.B. nen MAX293 nehmen und den durch den PWM vom Timer2 
"kalibrieren", dann hast Du praktisch nur den Mega8 und einen MAX293 
ohne viel diskrete Bauteile.
Nur so zum Bleistift ;)

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls jemand ähnliches vorhat: das Zauberwort heißt DDS. Damit läßt sich 
sehr elegant jede beliebige Frequenz erzeugen.
Suche hier im Forum.
Bei www.ad.com gibt es sehr schöne Erklärungen zum Prinzip.
Bei kleinen Frequenzen <10kHz kann man das super-einfach in Software 
gießen:


#define TabSize 64
char SinTab[TabSize]=(128, 130, ...  hier die Sinuswerte eingeben );
long frequ=123456L;   //als Beispiel

void PWM-ISR(void){  //Interrupt-Routine
  union DDS(long LONG, char BYTE[4]);
    //BYTE[3] sind die obersten 8 Bits (maschinenabhängig)
  DDS.LONG+=frequ;

  //mit Modulo (alternativ bei Vielfachen von 2  mit &(TabSize-1) )
  // auf die Tabellengröße beschränken
  PWM-REG1=SinTab[ DDS.BYTE[3]            % TabSize];
  //Cos-Wert um 90° versetzt
  PWM-REG2=SinTab[(DDS.BYTE[3]+TabSize/4) % TabSize];
  }

Das funktioniert so:
DDS.LONG ist ein 32-Bit-Zähler, der wird imaginär in zwei Hälften 
geteilt:
in z.B.
 16 Vorkomma- und 16 Nachkomma-Bits  oder
  8 Vorkomma- und 24 Nachkomma-Bits.

Die Vorkomma-Bits ergeben einen Index in die Sinus-Tabelle.

Wenn frequ nun z.B. 2^NachkommaBits ist, ergibt die Addition
  DDS.LONG+=frequ;
jedes Mal genau einen Überlauf in die VorkommaBits, d.h. bei jedem 
PWM-Cycle wird genau der nächste Tabelleneintrag ausgegeben.
Das wiederum bedeutet, dass nach TabSize Cyclen die Tabelle einmal 
ausgegeben wird, also genau eine Schwingung.
Folglich ist deren Frequenz PWMfrequenz / TabSize.

Ist nun frequ z.B. 2^(Nachkommabits-1) = (2^Nachkommabits) / 2
dann dauert das ganze doppelt so lange, weil erst zwei Additionen 
stattfinden müssen, bis es einen Übertrag in die VorkommaBits gibt.
Also wird die Ausgangs-Frequenz auch nur halb so hoch sein.

Allgemein gesagt:
AusgangsFrequenz = PWMfrequenz / TabSize * frequ / 2^NachkommaBits


Für die Routine kann man die PWM-ISR verwenden, muss man nicht.
Genausogut ist jede andere periodisch mit ausreichend hoher Frequenz 
aufgerufene Routine.


Man kann dem Rechner noch ein wenig Arbeit ersparen, indem man die 
Tabelle 1,25 mal so lange macht (das erste Viertel nochmal wiederholt) 
und sich dafür die 2. Modulo-Berechnung erübrigt.

  PWM-REG1 = SinTab[char index = DDS.BYTE[3] % TabSize];
  //Cos-Wert um 90° versetzt
  PWM-REG2 = SinTab[index + TabSize/4 ];


oder indem man zwei Tabellen für Sin und Cos verwendet:
  PWM-REG1 = SinTab[char index = DDS.BYTE[3] % TabSize];
  PWM-REG2 = CosTab[index];


Bei einer 64-er Tabelle kann man auch 6 Vorkomma- und 28 NachkommaBits 
nehmen, dadurch kann man die Frequenz 4mal so genau einstellen.

  PWM-REG1 = SinTab[char index = DDS.BYTE[3] >> 2];
  PWM-REG2 = CosTab[index];


Jetzt kommt's noch dicker: Wie kann ich die Frequenz linear wobbeln?
geht wieder ganz einfach:
  long delta=wobbel;

  DDS.LONG+=frequ+=delta;  //eine Super-Konstruktion
  if(frequ>= obere){delta=-wobbel;}
  else
  if(frequ<=untere){delta= wobbel;}


Finde ich einfach genial.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter seine ursprüngliche Idee unterscheidet sich gar nicht so sehr von 
DDS. Nur er will die Tabelle mit variabler Tahtrate durchgehen und DDS 
geht mit konstantem Takt und variabler Schrittweite durch die Tabelle.

Autor: Thomas S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Unterschied liegt in erster Linie in der Auflösung der 
Ausgangsfrequenz mit dem Nachteil der Nebenwellen. Kommt halt immer auf 
die Anforderung an. Der weitere Vorteil vom DDS ist die gute 
Phasenauflösung bei mehreren Kanälen. Unterschiede im Analogteil lassen 
sich so sehr gut ausblenden.

Thomas

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> das Zauberwort heißt DDS

Was heißt denn die Abkürzung ausgeschrieben?

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
digital direct synthesis

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> digital direct synthesis

Danke - mit dem Stichwort ist Google wesentlich auskunftsfreudiger, als 
mit der Abkürzung.

Autor: Sigint 112 (sigint)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was interesanntes zum Thema DDS: 
http://www.myplace.nu/avr/minidds/index.htm

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.