Ein Sinus Signal mit dem R2R DA-Wandler am Arduino Uno ausgeben.

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.

DA-Wandler Stuetzwerte

Die Bilder auf dem Oszilloskop für unterschiedlich viele Stützwerte bei einer Frequenz von 1 kHz:

10 Stützwerte

Sinus 10 Stützwerte

16 Stützwerte

Sinus 16 Stützwerte

Sinus 22 Stützwerte

Sinus 22 Stützwerte

Sinus 28 Stützwerte

Sinus 28 Stützwerte

Sinus 48 Stützwerte

Sinus 48 Stützwerte

Sinus 100 Stützwerte

Sinus 100 Stützwerte

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

Ein Gedanke zu „Ein Sinus Signal mit dem R2R DA-Wandler am Arduino Uno ausgeben.

  1. Fabian Noll

    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)

    Antworten

Schreibe einen Kommentar zu Fabian Noll Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.