Forum: Mikrocontroller und Digitale Elektronik Sinus erzeugen mit Mikrocontroller


von Heinz peter P. (poschi8)


Lesenswert?

Hallo,

ich würde gerne mit einem Mikrocontroller ein Sinus Signal erzeugen.
Folgendes muss dabei gewährleistet sein:
Amplitude von 0-12V einstellbar
Frequenz mindestens zwischen 50Hz und 60Hz einstellbar.

Grundsätzlich sollte das über PWM und eine Verstärkung ja möglich sein.

Ich möchte das Signal aber lieber direkt von einem Baustein bekommen 
(externer DAC) und nicht verstärken, da der Sinus nochmal 
hochtransformiert wird, und ich durch das verstärken und transformieren 
zu ungenau werde.

Hat jemeand Erfahrung mit externen DACs?
Welchen Baustein kann ich dafür einsetzen und wie muss ich diesen 
beschalten?
Ich denke mal I2C würde sich anbieten für den Mikrocontroller?

Danke für eure Hilfe!

LG,
poschi8

von PittyJ (Gast)


Lesenswert?

Wie genau soll der Sinus sein?
Wenn du einen DAC benutzt, dann mußt du ja zu genau definierten Zeiten 
die Stützstellen einstellen.
Bei 20 Stützstellen einer Welle sind das schon 1000 Änderungen pro 
Sekunde. Dann sollte dann auch schon per Interrupt ablaufen. Wenn man 
dann noch I2C Bausteine nimmt, dann kann das schon ungenau werden, weil 
eine Einstellung bei 100 KHZ Bustakt schon fast 200us braucht. 
(jedenfalls bei meinem MCP4728)

von Achim S. (Gast)


Lesenswert?

"50 bis 60 Hz" und "hochtransformiert" klingt ein wenig danach, als 
würdest du etwas Leistung benötigen. Welche Ströme bzw. Leistungen 
erwartest du denn am Eingang deines Trafos? DACs sind im Normalfall 
nicht dafür gemacht, signifikant Leistung zu treiben.

Heinz peter P. schrieb:
> Ich denke mal I2C würde sich anbieten für den Mikrocontroller?

oder SPI oder paralleles Interface. Je nachdem, was dein (uns 
unbekannter) Mikrocontroller so alles mitbringt und wie viele Pins er 
frei hat.

PittyJ schrieb:
> weil
> eine Einstellung bei 100 KHZ Bustakt schon fast 200us braucht.

was für 1000 Samples pro Sekunde immer noch viel schneller ist als 
benötigt.

von Heinz peter P. (poschi8)


Lesenswert?

PittyJ schrieb:
> Wie genau soll der Sinus sein?

Naja, es muss jetzt nicht das "perfekte" Signal sein, es dürfen schon 
kleinere Stufen drinnen sein, aber es sollte doch als Sinus erkennbar 
sein.

LG,
poschi8

von DH1AKF W. (wolfgang_kiefer) Benutzerseite


Lesenswert?

Hallo Poschi8,

mit einem PSoC4 oder 5LP z.B. brauchst Du keinen externen DAC- Baustein.
Hier hatte ich vor einiger Zeit mal etwas zum Thema veröffentlicht:

Beitrag "Sinusgenerator mit PSoC 4"

von Erew (Gast)


Lesenswert?

ATMega/ATTiny (Sinustabelle mit 256 Werten)
 |
 V
PWM (256 * f [50 - 60 Hz] updates)
 |
 V
Filter (Low-Pass)
 |
 V
OPAmp (Puffer ...)
 |
 v
Endstufe (... Leistungsteil)

von SCKL (Gast)


Lesenswert?

Schon mal über einen AD9850 oder AD9851 mit Nachbrenner (z.B. TDA2003) 
nachgedacht?

Den AD9850/1 kannst du z.B. mit einem Arduino oder einem SAD504 
ansteuern.

von Ingo L. (corrtexx)


Lesenswert?

R2R Netzwerk? Wenn dir 8Bit Auflösung reichen kann das jeder AVR. Falls 
du 16Bit Auflösung anstrebst würde ich zu einem 32Bit Controller greifen 
oder einem 8 Bitter mit Latch dahinter.

von SCKL (Gast)


Angehängte Dateien:

Lesenswert?

Hier ein fertiges Projekt mit R2R Netzwerk:

AVR DDS V2.0 signal generator
http://www.scienceprog.com/avr-dds-signal-generator-v20/
http://www.radiolocman.com/shem/schematics.html?di=69926

Kann Sinus, Rechteck, Dreieck, Sägezahn, Sägezahn reverse - von 0Hz bis 
ca. 60kHz.

von Heinz peter P. (poschi8)


Lesenswert?

Erew schrieb:
> ATMega/ATTiny (Sinustabelle mit 256 Werten)
>  |
>  V
> PWM (256 * f [50 - 60 Hz] updates)
>  |
>  V
> Filter (Low-Pass)
>  |
>  V
> OPAmp (Puffer ...)
>  |
>  v
> Endstufe (... Leistungsteil)
Das wäre meine Ursprüngliche Idee gewesen, aber da habe ich wieder deine 
Verstärkung, da ich mit der PWM ja nur 0-3.3V schaffe.
Als Enstufe häte isch sowas hier: 
http://www.amateurfunkbasteln.de/nfamps/nfamps.html (Die 2. Schaltung)

SCKL schrieb:
> Schon mal über einen AD9850 oder AD9851 mit Nachbrenner (z.B. TDA2003)
> nachgedacht?
Ja den habe ich auch schon gesehen, ich habe aber Probleme damit den 
Baustein zu verstehen bzw. weiß ich nicht wie ich diesen richtig 
beschalten muss.

Ingo L. schrieb:
> R2R Netzwerk? Wenn dir 8Bit Auflösung reichen kann das jeder AVR.
Ja mit der Auflösung würde ich schon klar kommen, aber wie würde das im 
Detail aussehen mit so einem R2R Netzwerk, und wie sieht das Signal am 
Ende aus?

Danke für die zahlreichen Antworten :))

LG,
poschi8

von Heinz peter P. (poschi8)


Lesenswert?

SCKL schrieb:
> Hier ein fertiges Projekt mit R2R Netzwerk:
>
> AVR DDS V2.0 signal generator

Danke das ist schon mal so etwas ähnliches, jedoch muss ich es schaffen 
das ich die Amplitude über die Software einstelle.
Das passiert hier ja über ein Poti wenn ich das richtig verstanden habe, 
oder?

LG,
poschi8

von Jörg (Gast)


Lesenswert?

Heinz peter P. schrieb:
>
>  jedoch muss ich es schaffen
> das ich die Amplitude über die Software einstelle.

Dazu brauchst Du 2 DACs. Mit dem einen stellst Du die Amplitude ein, der 
zweite ist der DAC für das Signal.

Schau Dir mal die SPI-DACs von Microchip an:

http://ww1.microchip.com/downloads/en/DeviceDoc/22250A.pdf

an. Esgeht dabei um die Familie. Wenn Du eine genügend stabile Referenz 
hinkriegst, kannst Du den Dual-DAc mit externer VREF nehmen.

Wenn nicht, mach ein Päärchen aus MCP4801 für die Amplitude und MCP4901 
für das Signal. Mit dem Ausgang des 4801 steuerst Du die Amplitude des 
4901.

Leider musst Du den Ausgang immer noch mit einem OP-Amp (konstant) 
verstärken, um auf die 12V zu kommen, da VREF max. VCC sein darf.

von Heinz peter P. (poschi8)


Lesenswert?

Ok alles klar, das verstehe ich.
Danke für deine Erklärung.

Aber in diesem Fall kann ich dann doch einfach die PWM machen und so 
beschalten:

ATMega/ATTiny (Sinustabelle mit 256 Werten)
 |
  V
 PWM (256 * f [50 - 60 Hz] updates)
  |
  V
 Filter (Low-Pass)
  |
  V
 Endstufe (... Leistungsteil)
Als Endstufe würde ich dann eine Schaltung mit dem TDA2030 bauen.

Denn Verstärken muss ich ja sowieso also ist es egal, oder nicht?

LG,
poschi8

von Jörg (Gast)


Lesenswert?

Irgendwo musst Du ja die Signalamplitude einstellen.

Das passiert bei meinem Vorschlag mit der Referenzspannung des 2. DAC.

Es geht natürlich auch mit spannungsgesteuerten Verstärkern (VCAs), da 
kannt Du dann ein mit PWM erzeugtes Signal steuern. Dazu könntest Du 
eine zweite PWM nehmen. Bauteil hierfür wäre ein LM13700. Aber ob das 
vom Aufwand einfacher ist?

von Achim S. (Gast)


Lesenswert?

Heinz peter P. schrieb:
> Denn Verstärken muss ich ja sowieso also ist es egal, oder nicht?

so ist es: du brauchst offensichtlich sowieso die Nachverstärkung, also 
ist es weitgehend egal ob dein DAC maximal 0-3,3V oder 0-12V kann: das 
ergibt jeweils nur eine andere Einstellung des Potis R7 in deiner 
verlinkten Schaltung.

Jörg schrieb:
> Irgendwo musst Du ja die Signalamplitude einstellen.

Warum nicht einfach den jeweiligen Digitalwert mit einem entsprechenden 
Versärkungsfaktor (in Software) skalieren, ehe er zum DAC geschickt 
wird?

Ob 8 Bit Auflösung dann noch aureichen müsste man schauen: es hängt 
davon ab, in welchen Bereichen die Verstärkung variiert werden soll und 
wie folgende Aussage genau zu interpretieren ist:

Heinz peter P. schrieb:
> Naja, es muss jetzt nicht das "perfekte" Signal sein, es dürfen schon
> kleinere Stufen drinnen sein, aber es sollte doch als Sinus erkennbar
> sein.

von Heinz peter P. (poschi8)


Lesenswert?

Also der Hintergrund des ganzen ist folgendes:

Ich möchte eine Wechselspannung zwischen 100V und 350V einstellen 
können.
Sollte eigentlich in 1V Schritten einstellbar sein.

Dazu wird das PWM Signal verstärkt und dann über einen Trafo 
hochtransformiert...

Und mit der PWM müsste ich schon die Amplitude einstellen können, den 
wenn ich mit einer Sinustabelle arbeite kann ich den Wert ja anpassen.
Wenn 255 3.3V entspricht, dann kann ich das ganze ja auch mal 0.5 
rechnen und müsste für alle Werte in der Tabelle die hälfte erhalten und 
hab somit die Amplitude verändert.
So hab ich mir das zumindest gedacht ;)

LG,
poschi8

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Und hier noch, wie ein Sinus-DDS aussehen kann:
1
const int sinewave_length=256;
2
const unsigned char sinewave_data[] PROGMEM = {
3
    0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
4
    0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
5
    0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
6
    0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
7
    0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
8
    0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
9
    0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
10
    0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
11
    0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
12
    0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
13
    0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
14
    0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
15
    0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
16
    0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
17
    0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
18
    0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};
19
    
20
    
21
volatile uint32_t akku_inkr=0x05bd26e9;
22
volatile uint32_t akku = 0x00000000;
23
24
#define GETINDEX(a) ((a & 0xff000000) >> 24)
25
26
27
ISR(TIM0_OVF_vect) {
28
    akku+=akku_inkr;
29
    OCR0A = pgm_read_byte(&sinewave_data[GETINDEX(akku)]);
30
}

Die Konstante akku_inkr musst du an deine Bedürfnisse anpassen ...

Bsp: Overflow-Timer-Interrupt (PWM selbst tacktet dann mit 10kHz*256 = 
2,56Mhz) läuft auf 10kHz und du möchtest 50Hz Sinus-Frequenz

f = (10kHz*akku_inkr)/256

akku_inkr = 50Hz * 256 / 10kHz = 1,28

Die 1,28 noch mit 2^24 multiplizieren und hex-Wandeln, Nachkommastellen 
abschneiden: akku_inkr = 0x0147AE14;

Ist jetzt für einen AVR, aber du hast ja nicht geschrieben, welchen µC 
du verwenden möchtest.

Am PWM-Output kannst du dann den Low-Pass-Filter und Verstärker  wie 
weiter oben einfach anschließen.

: Bearbeitet durch User
von Heinz peter P. (poschi8)


Lesenswert?

Alles klar, danke!

Ich werde einen Arduino nehmen und mich bei der Softare an diese Vorlage 
halten: https://www.arduino.cc/en/Tutorial/DueSimpleWaveformGenerator

Brauche ich den Tiefpass am Ende der PWM?
Bzw wozu ist der gedacht?
Nach welchen Kriterien muss ich diesen Dimensionieren?

LG,
poschi8

von ASM Superprofi (Gast)


Lesenswert?

Sicher hast du bei deinem einfachen Code auch berücksichtigt, was 
passiert, wenn du OCR0A von 130 auf 120 setzt, der Zähler aber schon bei 
125 ist?

von ASM Superprofi (Gast)


Lesenswert?

^^^ Das ging an Mampfi.

von Heinz peter P. (poschi8)


Lesenswert?

ASM Superprofi schrieb:
> Sicher hast du bei deinem einfachen Code auch berücksichtigt, was
> passiert, wenn du OCR0A von 130 auf 120 setzt, der Zähler aber schon bei
> 125 ist?

Das verstehe ich nicht?! xD

von Heinz peter P. (poschi8)


Lesenswert?

Aaaaah, habs mir schon gedacht ;)

von Mampf F. (mampf) Benutzerseite


Lesenswert?

ASM Superprofi schrieb:
> Sicher hast du bei deinem einfachen Code auch berücksichtigt, was
> passiert, wenn du OCR0A von 130 auf 120 setzt, der Zähler aber schon bei
> 125 ist?

Ah, ich verstehe, was du meinst ... Das kann nicht passieren, da beim 
Timer-Overflow der Counter 0 ist und dann der neue PWM Wert gesetzt 
wird. Der neue PWM-Wert wird erst beim nächsten Überlauf ins eigentliche 
OCR geladen. Man hat quasi 100µs Zeit, den OCR zu laden, ohne dass es 
hier Probleme gibt. Der landet zunächst ja in einem Shadow-Register. Es 
gibt halt ein Sample Zeitversatz, was aber nicht ins Gewicht fällt.

: Bearbeitet durch User
von ASM Superprofi (Gast)


Lesenswert?

Shadow Register? Sowas hat nur der xmega.

"However, changing TOP to a value close to BOTTOM when the counter is 
run-
ning with none or a low prescaler value must be done with care since the 
CTC mode does not have the double buffering feature. If the new value 
written to OCR0A is lower than the current value of TCNT0, the counter 
will miss the Compare Match. The counter will then have to count to its 
maximum value (0xFF) and wrap around starting at 0x00 before the Compare 
Match can
occur."

Wenn du aber bei 0 den Wert änderst, kann nichts passieren.
Man sollte diese Falle aber im Hinterkopf behalten.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

ASM Superprofi schrieb:
> Shadow Register? Sowas hat nur der xmega.

Du bist ja tatsächlich ein Superprofi ... seufz

Niemand verwendet CTC für PWM ... Lies dir das mal das Datenblatt durch 
;)

CTC (und der "normale" Modus) sind auch die einzigen Modis, in denen OCR 
sofort aktualisiert wird. Da gibts eine schöne Tabelle im Datenblatt.

Und ja, das gilt auch für die ATTinys!


> The OCR0x Registers are double buffered when using any of the Pulse
> Width Modulation (PWM) modes. For the normal and Clear Timer on Compare
> (CTC) modes of operation, the double buffering is disabled. The double
> buffering synchronizes the update of the OCR0x Compare Registers to
> either top or bottom of the counting sequence. The synchronization
> prevents the occurrence of odd-length, non-symmetrical PWM pulses,
> thereby making the output glitch-free.

Also wenn du schon Oberschläue verbreitest, dann bitte auch fachlich 
korrekt bleiben ;-)

*edit*: Ach, das weiß ich zufällig, weil ich in das OCR-Update-Problem 
erst selbst reingelaufen bin ???

Beitrag "[AVR] Update von OCR0A bei FastPWM ausgetrickst"

: Bearbeitet durch User
von ASM Superprofi (Gast)


Lesenswert?

Mampf F. schrieb:
> Niemand verwendet CTC für PWM

Niemand ausser eben echte Superprofis.

Erste Anwendung: Hohe Frequenzen. Selbst bei 8 MHz kommst du ohne CTC 
nur auf 31.25 kHz.

Zweite Anwendung: Hohe Batterielaufzeit. Reicht dir eine Auflösung von 
64 Schritten, kannst du den Takt deiner CPU auf 25% setzen und damit gut 
60-70% Strom sparen.

von ASM Superprofi (Gast)


Lesenswert?

Naja ich nutze halt meistens CTC. Deshalb ging ich davon aus, dass das 
alle so machen ;)

Man konnte aus deinem Code die Timerinitialisierung nicht rauslesen, 
oder ich habe es übersehen.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

ASM Superprofi schrieb:
> Erste Anwendung: Hohe Frequenzen. Selbst bei 8 MHz kommst du ohne CTC
> nur auf 31.25 kHz.
>
> Zweite Anwendung: Hohe Batterielaufzeit. Reicht dir eine Auflösung von
> 64 Schritten, kannst du den Takt deiner CPU auf 25% setzen und damit gut
> 60-70% Strom sparen.

Und aufgrund deiner Sonderfälle sagst du, mein PWM würde nicht 
funktionieren, obwohl du von schrägen Voraussetzungen ausgegangen bist?

Ich glaube, mit dir diskutiere ich nicht weiter ;-)

von nips (Gast)


Lesenswert?

einfach 12Euro STM32F4 Discovery board. Der µC hat einen 12bit DAC 
eingebaut. Für den Sinus muss der Prozessor dank DMA keinen Finger 
rühren.

Kleine Audio-Endstufe hinten drann und fertig.

von Georg (Gast)


Lesenswert?

Mampf F. schrieb:
> Und hier noch, wie ein Sinus-DDS aussehen kann:

Ist dir schon mal aufgefallen, dass man für die Werte eines Sinus 
garnicht die ganzen 360 Grad tabellieren muss? Die Werte wiederholen 
sich in jedem 90Grad-Quadranten, man braucht also nur eine Tabelle von 
0..90 Grad.

Georg

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Heinz peter P. schrieb:
> ich würde gerne mit einem Mikrocontroller ein Sinus Signal erzeugen.
> Folgendes muss dabei gewährleistet sein:
> Amplitude von 0-12V einstellbar
> Frequenz mindestens zwischen 50Hz und 60Hz einstellbar.

20 Beiträge später weiß immer noch niemand, welche Ausgangsleistung Dein 
Generator bringen soll. Auch die gewünschte Signalqualität ist 
unbekannt.


Aufgrund Deiner aktuellen Vorgaben, würde ich Dir so einen Baustein 
empfehlen:
https://www.amazon.de/Stromerzeuger-Notstromaggregat-Stromaggregat-Automatischer-%C3%96lmangelsicherung/dp/B00DPXFF68/ref=sr_1_4?ie=UTF8&qid=1490961861&sr=8-4&keywords=Notstromaggregat

Mit dem Mikrocontroller machst Du dann eine Frequenzregelung - ist halt 
ein Gefrickel und u.U. schlecht für die Lebensdauer, falls dauerhaft 
60Hz gewünscht werden.

Ansonsten: STM32-DISCO mit Nachbrenner, wie bereits jemand geschrieben 
hat.

Wenn Du Dich mit STM32F103R auskennst, hätte ich hier auch noch so einen 
Generator bzw. ein paar leere Platinen rumliegen. Wurde für die Messung 
von Motorinduktivitäten gebaut. Sollte zum Basteln reichen.

Eckdaten:
- STM32F103R
- 2x Endstufe OPA544
- jede Endstufe mit Strom-/Spannungsmessung
- RS232 / USB

Bei Bedarf PM.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Georg schrieb:
> man braucht also nur eine Tabelle von
> 0..90 Grad.

Jup, weiß ich :) Aus pragmatischen Gründen und weil ich nicht mit dem 
Platz sparen muss, hab ich trotzdem eine ganze Schwingung gespeichert :)

Optimieren, wo es notwendig ist ... Hier war es nicht nötig :)

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.