Ein Sinus Signal wird mit dem DA Wandler erzeugt und ausgegeben.
Dazu werden als erstes die Sinus Stützwerte berechnet. Für schnelle Frequenzen müssen wir wenig Stützwerte verwenden. Wenn die Frequenz niedriger wird, können mehr Stützwerte genommen werden.
Bei dem 4-Bit DA-Wandler sind 16 Ausgangsspannungen einstellbar, von 0 bis 15 Binär.
Das entspricht einer Spannung von 0 bis 4,7V.
Für die Sinus Funktion wird ein byte Feld beschrieben mit den einzelnen Ausgangszuständen des DA-Wandlers für die Anzahl der gewünschten Stützwerte. Dann sieht diese Funktion so aus:
// Globale Variablen: int stuetzwerte=28; byte sin28[28]; void setup() { calcSinTab(stuetzwerte); ... } void calcSinTab(int anzahl) { // Sinus Werte Tabelle berechen // für anzahl Werte (max. 28) // und im byte Feld sin28[28] speichern // siehe hierzu DA-Wandler // http://shelvin.de/ein-r2r-4-bit-digital-analog-wandler-wird-aufgebaut/ // // Matthias Busse 30.5.2014 Version 1.0 double wert; float grad; int i=0, iwert, awert; for(grad=0;grad<360;grad+=(360.0/(float)anzahl)) { wert=sin(grad*PI/180); // Bogenmaß Wertebereich -1 ... +1 wert=wert+1.00; // nur positive Zahlen 0 ... +2 wert=wert*7.50; // 2 wird binär 15 : 0 ... 15 iwert = round(wert); awert=0; // DA Wandler Werte berechnen if(iwert&B00000001) awert |= B00100000; if(iwert&B00000010) awert |= B00010000; if(iwert&B00000100) awert |= B00001000; if(iwert&B00001000) awert |= B00000100; sin28[i]=awert; // DA Wertetabelle füllen i++; } }
Mit der Timer Funktion werden dann die Werte nacheinander ausgegeben. Dazu wird erst einmal der Timer initialisiert.
#include < TimerOne.h> //Globale Variablen: int stuetzwerte=28; float f=1000; // Frequenz void setup() { mikrosekunden=round(1000000.0/f/(float)stuetzwerte); Timer1.initialize(mikrosekunden); Timer1.attachInterrupt(sinusTimerOut); ... }
Dann kann die Timer Funktion ausgeführt werden mit der Ausgabe und dem Hochzählen des Sinus-Werte-Felds.
// Globale Variable: byte zaehler=0; void sinusTimerOut() { // Sinus Werte über den Timer ausgeben // // Matthias Busse 30.5.2014 Version 1.0 PORTB=sin28[zaehler]; zaehler++; if (zaehler >= stuetzwerte) { zaehler=0; } }
Je mehr Stützwerte man bei der Sinus Ausgabe verwendet, desto mehr verschiedene analog Spannungen / DA-Werte werden ausgegeben. Die Tabelle dazu.
Die Bilder auf dem Oszilloskop für unterschiedlich viele Stützwerte bei einer Frequenz von 1 kHz:
Auf den Bildern erkennt man deutlich die Verbesserung des Sinus Signals bei Zunahme der Stützwerte.
Ab 48 Stützwerten sind alle 16 möglichen Ausgangsspannungen vorhanden.
100 Stützwerte bringen nur noch eine leichte Verbesserung der Symmetrie.
von Matthias Busse
Ich weiß die Fragen zu einem so alten Beitrag sind meist nervig. Aber ich versuche gerade ein einstellbares Sinus Signal zu erzeugen. 0-1V und 50Hz bis 1,2kHz. Allerdings verstehe ich irgendwie nicht wie ich jetzt das Programm zusammenschustern muss damit es läuft. Hab ein paar Dinge versucht aber so wirklich passieren tut da nichts an meinem Arduino. Und ja das R2R Netzwerk hab ich wie in dem anderen beitrag aufgebaut. Außerdem denken sie das es nötig ist einen Impedanzwandler einzusetzen wenn man mit dem Oszi misst (aufgrund des hohen Eingansgwiderstandes)