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

Schreibe einen Kommentar

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