Sinus erzeugen mit Mikrocontroller

OP #4955311
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
Gast #4955338
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)
Gast #4955340
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.
OP #4955378
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
Gast #4955406
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.
OP #4955433
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
Gast #4955464
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?
Gast #4955500
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.
OP #4955508
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
Persönliche Seite #4955524
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.
Persönliche Seite #4955603
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.
Gast #4955808
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.
Persönliche Seite #4955829
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"
Gast #4955845
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.
Persönliche Seite #4955852
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 ;-)
Gast #4958037
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
(Firma: www.harerod.de) Persönliche Seite #4958067
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren