Ich muss in der Lage sein, zwei Töne gleichzeitig zu spielen, und ich habe das Arduino Uni mit einem kleinen 8-Ohm-Piezo-Lautsprecher. Ist das möglich?
Beispielcode
#define c 3830 // 261 Hz
int tone1 = 10; // digital pin10
int tone2 = 9 // digital pin9
void setup() {
pinMode(tone1, OUTPUT); // pin as output
pinMode(tone2, OUTPUT); // pin as output
}
void loop() {
playTone(1000,500,700)
}
void playTone(long duration, int freq, int freq2) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(tone1,HIGH);
digitalWrite(tone2,HIGH);
delayMicroseconds(period / 2);
digitalWrite(tone1,LOW);
digitalWrite(tone2,LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
Sollte machbar sein. Haben Sie eine Sinus-Nachschlagetabelle. Berechnen Sie die Phasendifferenz zwischen aufeinanderfolgenden Abtastwerten für beide Signale bei der verwendeten Abtastfrequenz. Fügen Sie bei einem Timer-Tick (bei Ihrer Abtastfrequenz) diese Phasen zu Zweiphasen-Akkumulatoren hinzu, suchen Sie ihre Werte in der Sinustabelle, addieren Sie sie und stellen Sie einen PWM-Ausgang auf diesen Wert ein.
Verwenden Sie einen Tiefpassfilter, um eine analoge Spannung aus der PWM zu filtern.
Angenommen, Sie möchten ein 2-kHz-Signal mit einem 3-kHz-Signal und Ihre Abtastfrequenz beträgt 10 kHz. Ihre Sinustabelle hat für jedes Grad einen Wert. Ihr 2-kHz-Signal wird pro Abtastung um 72° schreiten, Ihr 3-kHz-Signal um 108°. Für das erste Signal lesen Sie also 72 Werte weiter in der Sinustabelle, für das andere gehen Sie bei jedem Sample 108 Werte weiter.
Dies funktioniert auch beim Mischen von mehr als zwei Signalen.
Die Hauptunterschiede zu Telaclavos Lösung bestehen darin, dass seine Signale Rechteckwellen sind, während meine Sinuswellen sind, je nachdem, was Sie bevorzugen. Meine Lösung ist CPU-intensiver, während seine mehr E / A und externe Komponenten (Spannungsaddierer) verwendet.
Wenn die maximale Anzahl von Tönen, die Sie gleichzeitig spielen müssen, nur zwei (oder sogar drei oder vier) beträgt, würde ich zwei Ausgangspins verwenden, die für die Lieferung von PWM konfiguriert sind, und ihre Beiträge extern hinzufügen, entweder mit zwei Widerständen (falls Sie dies nicht tun) braucht nicht viel Lautstärke) oder mit einem Operationsverstärker als Addierer.
Wenn Sie ein einzelnes PWM-Signal verwenden, um die Summe der beiden Töne nachzubilden, benötigen Sie CPU-Aufmerksamkeit für jedes Sample Ihres Gesamtsignals. Der ATmega328 hat kein DMA.
Mit den zwei Pins belasten Sie die CPU nicht. Tatsächlich braucht die CPU während der Zeitintervalle, in denen sich keine der beiden Frequenzen ändert, nichts zu tun.
Ein weiterer Vorteil ist, dass Sie jede der Frequenzen in Echtzeit ändern können. Sie brauchen keine Nachschlagetabelle für jede Kombination möglicher Frequenzen.
h00j
stevenvh
h00j
Superkatze