Die tone()-Funktion

Es ist deutlich bequemer, Töne mit der integrierten tone()-Funktion zu erzeugen. Hier brauchen wir keine mehrzeiligen Konstruktionen mit digitalWrite, for-Schleifen oder delay. Sie hat aber auch einige Nachteile, wie wir später sehen werden.

Die tone()-Funktion benötigt zwei Argumente, kann aber bis zu drei erweitert werden.

###Bild von tone funktion

Das erste Argument ist für die Pinnummer bestimmt, gefolgt von der Frequenz und schließlich die Tondauer in Millisekunden. Als unsigned integer nimmt die Frequenz Werte zwischen 0 und 65.535 an – also nur positive Werte. Eine Initialisierung von tone() im setup() ist nicht erforderlich und kann direkt im Sketch verwendet werden.

//Beispiel 1
int piezoPin = 7;

void setup() 
{
  //leer
}

void loop() 
{
  tone(piezoPin, 100);
}

Lade den oberen Sketch (Beispiel 1) auf das Arduino. Spiele mit dem Frequenzwert ein wenig und hör dir an wie sie sich verhalten: trage z.B. folgende Werte ein, 100, 1000, 10.000 und 60.000. Du wirst merken, dass der Ton mit steigendem Wert höher wird. Ein Wort zur Tonwiedergabe: Das Arduino, wurde nicht als Synthesizer konzipiert. Die Repräsentation der Frequenzen entspricht nicht wirklich der Realität.

Der untere Sketch (Beispiel 2) demonstriert die Funktion der Tondauer (3. Argument). Sie bestimmt, wie lange die Frequenz abgespielt werden soll. Die Tondauer hat aber nur Auswirkungen, wenn der Sketch danach oder davor mit einer zweiten Aufgabe beschäftigt ist. Zu diesem Zweck habe ich eine for-Schleife eingebaut, die mit der tone()-Funktion nichts zu tun hat und auch sonst keine sinnvolle Arbeit übernimmt. Die for-Schleife zählt bis 1000 und sendet gleichzeitig die Werte an den seriellen Monitor. Wäre die for-Schleife nicht vorhanden, würde die Frequenz durchgehend wiedergegeben werden.

//Beispiel 2
int piezoPin = 7;

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  tone(piezoPin, 5000, 2500);

  for(int i=0; i<1000; i++)
  {
    Serial.println(i);
    delay(5);
    }
}

Die tone()-Funktion spielt eine Frequenz von 5000Hz pro Sekunde für eine Dauer von 2500 Millisekunden.

tone(piezoPin,5000,2500);

Das untere dritte Beispiel zeigt uns, dass auch eine einfache delay(1000) Funktion den gleichen Effekt ohne eine for()-Schleife hat. Es wird ein Impulse-Ton ausgegeben. Experimentiere auch hier und trage unterschiedliche Werte innerhalb der delay()-Funktion ein.

//Beispiel 3
int piezoPin = 7;

void setup() 
{
//leer
}

void loop() 
{
  tone(piezoPin, 5000, 2500);
  delay(1000);
}

Das untere vierte Beispiel zeigt ein scheinbares Problem. Obwohl die Tondauer in der tone()-funktion und im delay() auf 500ms gesetzt sind, gibt es keine Pause, sondern ein durchgehender Ton. Warum ist das so?

//Beispiel 4
int piezoPin = 7;

void setup() 
{
  //leer
}

void loop() 
{
  tone(piezoPin, 5000, 500);
  delay(500);
}

Das liegt daran, dass die tone()-Funktion einen der integrierten Arduino-Timer benutzt. Auch delay() greift auf diese Timer zu. Entgegen unserer Erwartung startet nicht zuerst die Dauer in der tone()-Funktion und danach delay(). Sie starten und enden gleichzeitig! Das ist der Grund, warum wir keine Pause hören.

Das bedeutet für uns, dass die Dauer in tone() größer sein sollte. Experimentiere auch hier mit den Werten. Gib zum Beispiel einen etwas höheren Wert für delay() ein: z.B. 550.

 

 

Limitationen von tone()

Gleichzeitiges Verwenden der tone()-Funktion und der analogWrite() Funktion am Pin 10 führt zu unerwarteten Ergebnissen. Es entstehen seltsame Piezo-Töne. Das liegt daran, dass die tone()-Funktion den gleichen Timer wie Pin 10 benutzt.

Des Weiteren kann die tone()-Funktion nicht gleichzeitig an zwei Pins funktionieren. Zwei Piezo gleichzeitig zu betreiben, ist nicht möglich. Du musst zunächst mit dem Befehl noTon(); sozusagen entkoppelt werden, um sie nacheinander zu benutzen. Auch wenn bei niedrigen Frequenzen Töne erzeugt werden, sind es nicht die realen Repräsentationen. Frequenzen unter 31Hz können nicht realitätsnah wiedergegeben werden.

 

 

Aufgaben

1. Aufgabe: tone() + analogWrite()

Teste das merkwürdige Verhalten beim gleichzeitigen Benutzen von tone() und analogWrite() am Pin 10. Schreibe ein Sketch, an dem an Pin 7 der Piezo und an Pin 4 eine LED steckt. Lass z.B. die LED blinken und hör dir an, wie der Ton ist. Tausche den Pin der LED (z.B. Pin 5) und teste das ganze nochmal.

 

2. Aufgabe: Mache deine eigenen Sounds

Im letzten Kapitel haben wir mit einfachen Mittel einen Sound für die Batterie (=fast leer) und eine Startsequenz erstellt. Mache das Gleiche mit der tone()-Funktion. Du kannst tone() und delay auch mehrmals hintereinander stapeln. Erstelle hierzu ein Test-Sketch, in dem du die Werte für Frequenz, Tondauer und delay() mit Potentiometern manipulierst und die Werte an den seriellen Monitor schickst. Notiere die besten Ergebnisse.