Forum: Mikrocontroller und Digitale Elektronik DAC Geschwindigkeit über µC zu langsam


von Benjamin (Gast)


Lesenswert?

Hallo Leute, ich habe folgendes Problem:

Ich verwende den DAC eines ARDUINO DUEs, um mir jede halbe ms 
abwechselnd ein Spannungswert auszugeben.


Der DA-Wandler kann aber nur jede ms (!!!) den Wert ändern, d.h. wenn 
wir aus dem DA-Wandler zwei Spannungen ausgegeben haben möchten, dann 
dauert das mind. 1ms.


Hier mein Code:
1
void loop() {
2
3
  analogWriteResolution(12);
4
  
5
  analogWrite(DAC0,650);
6
  delay(1); // warte 1ms
7
  analogWrite(DAC1,2000);
8
  delay(1); // warte 1ms
9
}
Das Funktioniert soweit einwandfrei. Setzte ich aber die delay auch nur 
10µs unter der ms, schon ist der DAC dazu nicht in der Lage mehr, die 
entsprechende Spannung richtig auszuben.

Das ist für einen DA-Wandler aber viiiiiiiel zu langsam. Kann man das 
irgendwo einstellen?

Was ich habe is noch das Datenblatt, S.1355:

http://www.atmel.com/Images/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf

Nur leider arbeite ich grad mich in diese Materie ein, daher weiß ich 
das net recht genau, wo ich das nachlesen kann.

Entschuldigt, wenn das eine dumme einfache Frage ist, jedoch häng ich 
dran.

Meiner Meinung nach müsste das doch gehen, da der DAC eig. für 
Audio-Anwendungen in diesem Board gedacht ist.
Jeder Dac liegt doch eig. im µs-Bereich.

: Bearbeitet durch User
von Benjamin (Gast)


Lesenswert?

Das Bord ist der Arduino DUE, irgendwie wurde das nicht richtig 
geschrieben.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Benjamin schrieb:
> Meiner Meinung nach müsste das doch gehen, da der DAC eig. für
> Audio-Anwendungen in diesem Board gedacht ist.

Das hängt beim SAM3 aber auch von der Masterclock ab. Wenn die zu 
langsam ist, dauerts halt (DACCLK = MCLK/2). Wie die Arduino Library die 
Clock einstellt, musst du also herausfinden. Die Kiste braucht 25 Takte, 
um dann den DAC Ausgang zu setzen.
Für Audio mit 12 bit? Naja, schön ist anders.

: Bearbeitet durch User
von Mitlesa (Gast)


Lesenswert?

Ich nehme an zu beziehst dich auf einen Arduino.

In desssen "Betriebssystem" ist die zeitliche Aflösung der
delay()-Funktion warscheinlich auf 1ms begrenzt. Wenn du
also delay(0.1) aufrufst wird das in einer Delay-Zeit von
wenigen Mikrosekunden enden - gerade das was der Aufruf und
der Rücksprung verbraucht.

Ich bin mir nicht sicher ob im Arduino-Kontext die Standard-
Aufrufe _delay_ms(....) und _delay_us(...) mmöglich sind, aber
einen Versuch ist ja es Wert .....

Ansonsten musst du lernen und dir deine eigene hochauflösende
Timer-Lösung bauen, was kein Ding der Unmöglichkeit ist.

von Mitlesa (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Für Audio mit 12 bit? Naja, schön ist anders.

Was würdest du denn sagen wenn man dir sagt dass in *.mp3
Dateien die Audio Daten oft auf noch weniger als 12 Bit
"komprimiert" werden?

von Benjamin (Gast)


Lesenswert?

Mitlesa schrieb:
> Ich bin mir nicht sicher ob im i4004-Kontext die Standard-
> Aufrufe _delay_ms(....) und _delay_us(...) mmöglich sind, aber
> einen Versuch ist ja es Wert .....

Der Versuch war es wert. Da lag der Fehler.
Wenn ich delayµs aufrufe, dann klappts ! Danke !

von Benjamin (Gast)


Lesenswert?

Wobei wenn ich wiederum beide DACs verwende, dann ist der zu langsam 
bzw. schafft es nicht.

von Falk B. (falk)


Lesenswert?

@ Benjamin (Gast)

>Wobei wenn ich wiederum beide DACs verwende, dann ist der zu langsam
>bzw. schafft es nicht.

Dann machst du was falsch. 1 kHz ist ein Witz für einen DAC.
Wie sieht den Programm JETZT aus?

Das Problem liegt wahrscheinlich in der Funktion analogWrite();

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mitlesa schrieb:
> Matthias Sch. schrieb:
>> Für Audio mit 12 bit? Naja, schön ist anders.
>
> Was würdest du denn sagen wenn man dir sagt dass in *.mp3
> Dateien die Audio Daten oft auf noch weniger als 12 Bit
> "komprimiert" werden?
Dann sage ich immer noch - schön ist anders. Verwechsle auch bitte nicht 
die komprimierten Daten mit dem, was am DAC wieder auftaucht.

von Benjamin (Gast)


Lesenswert?

Falk Brunner schrieb:
> Dann machst du was falsch. 1 kHz ist ein Witz für einen DAC.
> Wie sieht den Programm JETZT aus?
>
> Das Problem liegt wahrscheinlich in der Funktion analogWrite();

Mein Programm sieht wie folgt aus:
1
analogWriteResolution(12);
2
  
3
analogWrite(DAC0,100);
4
5
delayMicroseconds(500);
6
7
analogWrite(DAC0,0);
8
9
delayMicroseconds(500);
500 µs ist das absolute minimum was geht, dannach kann er das ganze 
nicht mehr in der angegebenen Zeit schaffen, d.h. wenn ich 250µs An/Aus 
eingebe, dann ist er 230µs an und 270µs aus.

Im Übrigen, wenn ich beide DAC-Ausgänge verwende, dann ist nach 1ms 
schon schluss. Mein Code sieht dann wie folgt aus:
1
analogWriteResolution(12);
2
  
3
analogWrite(DAC0,100);
4
analogWrite(DAC1,100);
5
6
delay(1);
7
8
analogWrite(DAC0,0);
9
analogWrite(DAC1,0);
10
11
delay(1); // 1 steht für 1ms
1ms bekommt der sauber hin.

Auch nur eine µs drunter führt schon zu Problemen.

auch wenn ich die Funktion delayMicroseconds verwende, dann können die 
Zeiten nicht mehr exakt eingehalten werden.

Genau deswegen wende ich mich an euch: Nämlich ich denke auch, dass das 
ein Witz ist mit 1kHz.....

: Bearbeitet durch User
von Ulrich F. (Gast)


Lesenswert?

aus der Gerüchteküche:
Der Vorgang ist viel fixer wenn du auf analogWrite() verzichtest und den 
DAC direkt manipulierst.
Und noch feiner, wenn DMA zum Einsatz kommt.
*alles (von mir) ungetestet*

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Benjamin schrieb:
> Genau deswegen wende ich mich an euch: Nämlich ich denke auch, dass das
> ein Witz ist mit 1kHz.....

Du hast dir aber schon mal MCLK und die davon abgeleitete DAC Clock 
angesehen? Das bestimmt die obere Grenze dessen, was der DAC verdauen 
kann, nämlich DACClock/25.
Der Nachteil bei der Arduino Lib ist oft der, das man nicht weiss, was 
die Jungs bei der Initialisierung anstellen. Schau dir die also mal an.

von Benjamin (Gast)


Lesenswert?

Das Problem ist aber, das ich leider nur die Arduino IDE verwende, bin 
nicht der fitteste darin, irgendwo etwas zu manipulieren.

Besteht keine Möglichkeit das irgendwie über die Arduino IDE zu ändern 
oder ähnliches?

von Karl H. (kbuchegg)


Lesenswert?

Benjamin schrieb:

> Besteht keine Möglichkeit das irgendwie über die Arduino IDE zu ändern
> oder ähnliches?

Natürlich. Hinter "analogWrite" steckt ja auch nichts anderes als C++ 
Code in irgendeiner Datei. Die kann man suchen und sich mal ansehen.

Ich schätze aber mal, da wirst du kein Glück haben. Denn analogWrite 
muss aus Komfortgründen eine ganze Menge mehr machen, was zwar für 
Lieschen Müller kein Problem darstellt (ganz im Gegenteil), wenn man 
aber die Hardware ausreizen will, dann ist das kontraproduktiv.
Witers schätze ich mal, du wirst nicht umhin kommen zu lernen, wie man 
den DAC direkt, also ohne Mithilfe der Arduino-Entwickler und deren 
analogXXX Funktionen programmiert.

Und ich hoffe auch, du hast gelernt, dass diese Rederei von wegen "Nimm 
einen Arduino, da braucht man nichts können" ganz einfach so nicht 
stimmt. Solange man keine speziellen Ansprüche hat, mag das gehen. Aber 
wehe, wenn man dann mal etwas braucht, was nicht in das vorgefertigte 
und von anderen vorgedachte Schema passt. Dann ist man aufgeschmissen.

von Peter D. (peda)


Lesenswert?

Benjamin schrieb:
> Besteht keine Möglichkeit das irgendwie über die Arduino IDE zu ändern
> oder ähnliches?

Ich kann nicht glauben, daß es zu der Arduino-Lib kein Manual geben 
soll, wo alle Parameter und Limits erläutert werden.

Ansonsten kann man die Lib auch einfach nicht benutzen und ins 
Datenblatt/Manual des MC schauen, um die Register direkt zu setzen.

Ganz ohne Lesen von Manuals wird man aber nicht weit kommen.

von Ulrich F. (Gast)


Lesenswert?

Nee..
Arduino ist auf dem Auge recht Blind.

Es gibt von Arduino eine Audio/DAC Lib. (die könnte man sich mal 
ansehen)
Und andere haben auch schnelle Ausgaben bis 44100 Werten pro Sekunde 
hin bekommen. Mit Assembleranteilen.

Natürlich geht das alles mit/in der Arduino IDE, wird aber nicht direkt 
durch vorgefertigte Dinge unterstützt.

Aber wie gesagt, ist nicht meine Baustelle und auch nur aus der 
Erinnerung geholt.

von Falk B. (falk)


Lesenswert?

@Benjamin (Gast)

>Mein Programm sieht wie folgt aus:

GANZ SICHER NICHT!

Lass den Mist mit dem hinschreiben von Fetzen aus dem Gedächtnis! Poste 
VOLLSTÄNDIGEN, ORIGINALEN Code als ANHANG! Siehe Netiquette!

>500 µs ist das absolute minimum was geht, dannach kann er das ganze
>nicht mehr in der angegebenen Zeit schaffen, d.h. wenn ich 250µs An/Aus
>eingebe, dann ist er 230µs an und 270µs aus.

>auch wenn ich die Funktion delayMicroseconds verwende, dann können die
>Zeiten nicht mehr exakt eingehalten werden.

Dafür sind die Funktion so auch nicht in der Lage. Ein WIRKLICH sauberes 
Timing erreicht man nur mit einem Timer-Interrupt. Das liegt aber 
jenseits der Arduinowelt.

von Ulrich F. (Gast)


Lesenswert?

Bei mir finden sich in 
C:\Programme\Arduino\hardware\arduino\sam\system\libsam
Die Ordner include und source.
Dort befindet sich der DAC spezifische Krams.
Das kann man sich auch mal ansehen.
Vielleicht ist damit was machbar.

von Jim M. (turboj)


Lesenswert?

Falk Brunner schrieb:
> Ein WIRKLICH sauberes
> Timing erreicht man nur mit einem Timer-Interrupt.

In dem Falle wüde ich eher Hardware-getriggertes DMA für den DAC 
verwenden.
Das verwendet einen Timer für den Trigger aber keinen Timer-Interrupt.

Das hat dann noch weniger Jitter, aber auch mehr Möglichkeiten für den 
Programmierer sich selbst ins Knie zu schiessen.

von Falk B. (falk)


Lesenswert?

@Jim Meba (turboj)

>In dem Falle wüde ich eher Hardware-getriggertes DMA für den DAC
>verwenden.
>Das verwendet einen Timer für den Trigger aber keinen Timer-Interrupt.

Ja, das ist noch besser, aber . . .

>Das hat dann noch weniger Jitter, aber auch mehr Möglichkeiten für den
>Programmierer sich selbst ins Knie zu schiessen.

Eben noch weiter weg von Arduino.

von Benjamin (Gast)


Lesenswert?

Falk Brunner schrieb:
> @Jim Meba (turboj)
>
>>In dem Falle wüde ich eher Hardware-getriggertes DMA für den DAC
>>verwenden.
>>Das verwendet einen Timer für den Trigger aber keinen Timer-Interrupt.
>
> Ja, das ist noch besser, aber . . .
>
>>Das hat dann noch weniger Jitter, aber auch mehr Möglichkeiten für den
>>Programmierer sich selbst ins Knie zu schiessen.
>
> Eben noch weiter weg von Arduino.

Liebe Leute, vielen Dank für eure Antwortn, es hat super geklappt, hab 
das über einen Timer realisiert...

von Falk B. (falk)


Lesenswert?

@ Benjamin (Gast)

>Liebe Leute, vielen Dank für eure Antwortn, es hat super geklappt, hab
>das über einen Timer realisiert...

Na dann poste mal deinen Quelltext.

von Benjamin (Gast)


Lesenswert?

Falk Brunner schrieb:
> Na dann poste mal deinen Quelltext.

Mehr als ein Blockschaltbild ist nicht drin, da ich das in Simulink über 
ne S-Function realisiert habe, wenn einer Interesse hat, dann gerne ....

von Neuer (Gast)


Lesenswert?

Ich hätte Interesse an der s Funktion des simulink blocks. Hast du das 
noch parat? Der DAC wird meines Wissens ja noch nicht unterstützt

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.