Forum: Mikrocontroller und Digitale Elektronik DAC pfc 8591 mit Arduino Uno veränderbare Sinus Frequenzen


von Jonas A. (jonas2098)


Lesenswert?

Hallo Leute , ich würde mir gerne einen kleinen Funktionsgenerator mit 
einem Arduino Uno und einem pfc 8591 bauen , nur leider weiß ich nicht 
wie ich die Frequenzen verändern kann.    Ich habe schon ein paar Tests 
gemacht aber ... ich bekam immer nur eine Frequenz von 13,9 Hz bis 15 Hz 
heraus ohne zu wissen wie ich diese variieren konnte bzw. die Frequenz 
höher stellen konnte.
Ich weiß jetzt nicht so viel von DACs und würde gerne wissen ob 
irgendwer eine Idee hat wie ich die Frequenz höher stellen kann.

Hier der Programmcode:


#include <Wire.h>


#define PCF8591 (0x90 >> 1) // I2C bus address

uint8_t sine_wave[256] = {
0x6e,0x71,0x74,0x77,0x7b,0x7e,0x81,0x84,
0x87,0x8a,0x8d,0x90,0x93,0x96,0x99,0x9c,
0x9f,0xa1,0xa4,0xa7,0xa9,0xac,0xaf,0xb1,
0xb4,0xb6,0xb8,0xbb,0xbd,0xbf,0xc1,0xc3,
0xc5,0xc7,0xc9,0xcb,0xcc,0xce,0xcf,0xd1,
0xd2,0xd3,0xd5,0xd6,0xd7,0xd8,0xd8,0xd9,
0xda,0xda,0xdb,0xdb,0xdc,0xdc,0xdc,0xdc,
0xdc,0xdc,0xdc,0xdb,0xdb,0xda,0xda,0xd9,
0xd8,0xd8,0xd7,0xd6,0xd5,0xd3,0xd2,0xd1,
0xcf,0xce,0xcc,0xcb,0xc9,0xc7,0xc5,0xc3,
0xc1,0xbf,0xbd,0xbb,0xb8,0xb6,0xb4,0xb1,
0xaf,0xac,0xa9,0xa7,0xa4,0xa1,0x9f,0x9c,
0x99,0x96,0x93,0x90,0x8d,0x8a,0x87,0x84,
0x81,0x7e,0x7b,0x77,0x74,0x71,0x6e,0x6b,
0x68,0x65,0x61,0x5e,0x5b,0x58,0x55,0x52,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3d,0x3b,
0x38,0x35,0x33,0x30,0x2d,0x2b,0x28,0x26,
0x24,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,
0x13,0x11,0x10,0xe,0xd,0xb,0xa,0x9,
0x7,0x6,0x5,0x4,0x4,0x3,0x2,0x2,
0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1,0x1,0x2,0x2,0x3,0x4,0x4,
0x5,0x6,0x7,0x9,0xa,0xb,0xd,0xe,
0x10,0x11,0x13,0x15,0x17,0x19,0x1b,0x1d,
0x1f,0x21,0x24,0x26,0x28,0x2b,0x2d,0x30,
0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,
0x49,0x4c,0x4f,0x52,0x55,0x58,0x5b,0x5e,
0x61,0x65,0x68,0x6b,0x6e,};
void setup()
{
 Wire.begin();
}
void loop()
{
 for (int i=0; i<220; i++)
 {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
 Wire.write(sine_wave[i]); // value to send to DAC
 Wire.endTransmission(); // end tranmission
 }
}

von Εrnst B. (ernst)


Lesenswert?

Einfach indem du deine Tabelle langsamer abläufst.

Also in die "for"-Schleife ein delay einbauen, schon wird die Frequenz 
niedriger.

Variables delay->variable Frequenz.


Höher wird die Frequenz nur, wenn du den Ablauf abkürzt. also z.B. eine 
kleinere Sinustabelle mit weniger Einträgen verwendest.

: Bearbeitet durch User
von Jonas A. (jonas2098)


Lesenswert?

Danke sehr Ernst B. , das habe ich mir schon fast gedacht. Aber wenn ich 
weniger Werte nehme dann wird auch die Sinuswelle von der Qualität her 
schlechter. Gibt es vllt nicht irgendeine Möglichkeit das der Arduino 
die Werte einfach schneller ausgibt oder so ? Vllt wenn man den internen 
Timer verändert ?

von Joachim B. (jar)


Lesenswert?

Jonas A. schrieb:
> Aber wenn ich
> weniger Werte nehme dann wird auch die Sinuswelle von der Qualität her
> schlechter.

ja

Jonas A. schrieb:
> Gibt es vllt nicht irgendeine Möglichkeit das der Arduino
> die Werte einfach schneller ausgibt oder so ?

nö

denn im Datenblatt vom PCF8591 steht
f SCL clock frequency 100kHz

man könnte versuchen SCL zu erhöhen, die meisten meiner Chips machen 
400kHz
  Wire.begin();
  Wire.setClock(400000L);

das würde das Tempo vervierfachen,
Jonas A. schrieb:
> ich bekam immer nur eine Frequenz von 13,9 Hz bis 15 Hz

also bis 60Hz gehen

du sendest eh nur 220 von 256 hast also schon dein Signal verschlechtert

Jonas A. schrieb:
> for (int i=0; i<220; i++)

also alle Werte ausgeben oder nur jeden 10
also bis 150Hz gehen

Abhilfe:
SPI DAC

von Joachim B. (jar)


Lesenswert?

hast du das mal versucht?
1
void setup()
2
{
3
   Wire.begin();
4
}
5
void loop()
6
{
7
   Wire.beginTransmission(PCF8591); // wake up PCF8591
8
   Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
9
   for (int i=0; i<255; i++)
10
      Wire.write(sine_wave[i]); // value to send to DAC
11
   Wire.endTransmission(); // end tranmission
12
}

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?


von Jonas A. (jonas2098)


Lesenswert?

Lieber Joachim B. vielen Dank für ihre Hinweise. Ich sende absichtlich 
nur 220 von 256 Wert ... . Wenn ich 256 Werte nehme schneidet mir der 
PCF8591 die restlichen Werte einfach ab ... als ich alle 256 Werte 
genommen habe die möglich sind hat mir der  PCF8591  mir die obere 
Sinushalbwelle abgeschnitten ... d.h. so ca. alle Werte über 220 macht 
der DAC bei mir nicht und einen Sinus bei dem die obere Welle so 
unsauber ist das man es kaum nicht mehr als Sinus erkennen kann wollte 
ich nicht. Ich werde mal probieren die f SCL clock Frequenz auf 400kHz 
zu setzen.
Und noch eine Frage ich hab im Datenblatt vom PCF8591 schon nachgeguckt 
aber hab es nicht gefunden ... wie viel  Ausgangsstrom liefert denn der 
Analog Out beim PCF8591 ?

von Joachim B. (jar)


Lesenswert?

Jonas A. schrieb:
> aber hab es nicht gefunden ... wie viel  Ausgangsstrom liefert denn der
> Analog Out beim PCF8591 ?

bis Seite 16 nicht gelesen?
Iout ist doch klar zu finden.

aber egal, das hier mal versucht?
Beitrag "Re: DAC pfc 8591 mit Arduino Uno veränderbare Sinus Frequenzen"

nun wird es bald Zeit deinen Schaltplan und Aufbau zu zeigen, vielleicht 
fehlen ja noch Kondensatoren oder Filter für die DAC Versorgung.

: Bearbeitet durch User
von Jonas A. (jonas2098)


Lesenswert?

Lieber Joachim B. ich habe gerade das ausprobiert was sie mir sagten "f 
SCL clock frequency 400kHz " . Es hat super funktioniert jetzt bekomme 
ich schon eine Sinusfrequenz von 42,372 Hz . Vielen Dank :)
Noch höher wird wohl die Frequenz nicht gehen. Aber ich bin vollkommen 
zufrieden damit.  Sie haben mir sehr geholfen.

von Joachim B. (jar)


Lesenswert?

Jonas A. schrieb:
> Es hat super funktioniert jetzt bekomme
> ich schon eine Sinusfrequenz von 42,372 Hz . Vielen Dank :)
> Noch höher wird wohl die Frequenz nicht gehen

1. freut mich
2. funktioniert das nicht? (ich denke es ist nicht immer nötig i2c zu 
beginnen und zu beenden sowie den jedesmal aufzuwecken
1
void setup()
2
{
3
   Wire.begin();
4
}
5
void loop()
6
{
7
   Wire.beginTransmission(PCF8591); // wake up PCF8591
8
   Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
9
   for (int i=0; i<255; i++)
10
      Wire.write(sine_wave[i]); // value to send to DAC
11
   Wire.endTransmission(); // end tranmission
12
}

: Bearbeitet durch User
von Maxim B. (max182)


Lesenswert?

Jonas A. schrieb:
> for (int i=0; i<220; i++)
>  {
>  Wire.beginTransmission(PCF8591); // wake up PCF8591
>  Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
>  Wire.write(sine_wave[i]); // value to send to DAC
>  Wire.endTransmission(); // end tranmission
>  }

Hier ist komisch: Sinusfrequenz wird von I2C-Geschwindigkeit bestimmt! 
Ist das so gedacht?

wenn nicht: lese mal zu Thema DDS.

von Joachim B. (jar)


Lesenswert?

Maxim B. schrieb:
> Hier ist komisch: Sinusfrequenz wird von I2C-Geschwindigkeit bestimmt!

hatte ich schon mal angemerkt:
@Beitrag "Re: DAC pfc 8591 mit Arduino Uno veränderbare Sinus Frequenzen"

Joachim B. schrieb:
> void setup()
> {
>    Wire.begin();
> }
> void loop()
> {
>    Wire.beginTransmission(PCF8591); // wake up PCF8591
>    Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
>    for (int i=0; i<219; i++) // Korrektur wegen kurzer Tabelle
>       Wire.write(sine_wave[i]); // value to send to DAC
>    Wire.endTransmission(); // end tranmission
> }

der TO hat ja keine 256 Werte

: Bearbeitet durch User
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.