DTMF-Decoder mit Arduino bauen – ganz ohne zusätzlichen IC
Komponenten und Materialien
- 1 × Arduino UNO
- 10 × LED (beliebig)
- 1 × Breadboard
- 20 × Jumper-Wires
Software und Online-Dienste
- Arduino IDE
Projektbeschreibung
Bei der Suche nach einem Semesterprojekt stieß ich auf einen DTMF-gesteuerten Roboter, der den CM8870-IC als DTMF-Decoder einsetzte. Die binären Daten wurden an einen Arduino übergeben, um Vorwärts-, Rückwärts-, Links- und Rechtsbewegungen auszuführen. Die Decoder-Funktion – der Kern des Projekts – erforderte jedoch einen externen IC, dessen Integration ich als schwierig empfand. Ich suchte nach Code oder einer Bibliothek, die den IC durch Software ersetzen könnte, fand aber keine zufriedenstellende Lösung.
Schließlich entdeckte ich eine Bibliothek, die auf dem Goertzel-Algorithmus basiert (Goertzel.h). Sie kann feststellen, ob eine bestimmte Frequenz in einem Tonsignal enthalten ist, indem sie die Anzahl der Impulse pro Zeiteinheit und deren Amplitudenbeitrag berechnet. Ich nutzte das Basisbeispiel als Grundlage und schrieb einen Code, der die dominanten DTMF-Frequenzen im Signal erkennt und diese in die entsprechende Ziffer decodiert, die während eines Anrufs gedrückt wurde.
Funktionsweise
Der Code überprüft alle acht DTMF-Frequenzen (vier niedrige und vier hohe) und identifiziert die gedrückte Taste anhand der Frequenzpaare. Die Erkennung erfolgt über den analogen Eingang A0. Ein 1 µF-Kondensator in Reihe filtert Tieffrequenzen und DC-Offset aus dem Audiosignal (z. B. von einer Klinkenbuchse oder einem AUX-Kabel).
Zehn LEDs an den digitalen Pins 2–11 zeigen die erkannten Ziffern 0–9 an. Pin 13 blinkt kurz bei jeder Erkennung. Sonderzeichen (*, #, A–D) werden über die serielle Schnittstelle ausgegeben.
Code
Die Bibliothek Goertzel.h muss vor dem Kompilieren installiert werden:
https://github.com/jacobrosenthal/Goertzel
/* DTMF-Decoder basierend auf dem Goertzel-Algorithmus
* Erkannt werden die 16 DTMF-Zeichen über Analogpin A0.
* Ausgabe: LEDs an Pin 2-11 für 0-9, seriell für *, #, A-D.
* Basiert auf Kevin Banks' Implementierung (embedded.com) und
* der Goertzel-Bibliothek von Jacob Rosenthal.
* Modifiziert von Mian Mohammad Shoaib.
*/
#include <Goertzel.h>
const int sensorPin = A0;
const int N = 100; // Abtastwerte pro Messung
const float threshold = 2000.0; // Mindestamplitude für Erkennung
const float sampling_freq = 8900.0; // Abtastrate (max. bei 16 MHz Arduino)
float x_frequencies[4] = {1209, 1336, 1477, 1633}; // hohe Frequenzen (Spalten)
float y_frequencies[4] = {697, 770, 852, 941}; // niedrige Frequenzen (Zeilen)
void setup() {
pinMode(13, OUTPUT); // Erkennungs-LED
for (int p = 2; p <= 12; p++) pinMode(p, OUTPUT); // Ziffern-LEDs
Serial.begin(9600);
}
bool detect_tone(float freq) {
Goertzel goertzel(freq, N, sampling_freq);
goertzel.sample(sensorPin);
float magnitude = goertzel.detect();
if (magnitude > threshold) {
digitalWrite(13, HIGH);
delay(250);
digitalWrite(13, LOW);
Serial.println(freq);
return true;
}
return false;
}
void print_number(int row, int col) {
int number = 0;
// DTMF-Matrix Zuordnung
if (row == 0) {
if (col == 0) number = 1;
else if (col == 1) number = 2;
else if (col == 2) number = 3;
else number = 10; // A
} else if (row == 1) {
if (col == 0) number = 4;
else if (col == 1) number = 5;
else if (col == 2) number = 6;
else number = 11; // B
} else if (row == 2) {
if (col == 0) number = 7;
else if (col == 1) number = 8;
else if (col == 2) number = 9;
else number = 12; // C
} else if (row == 3) {
if (col == 0) number = 14; // *
else if (col == 1) number = 0;
else if (col == 2) number = 15; // #
else number = 13; // D
}
if (number < 10) {
digitalWrite(number + 2, HIGH);
Serial.println(number);
} else {
char c = (number == 10) ? 'A' : (number == 11) ? 'B' : (number == 12) ? 'C' : (number == 13) ? 'D' : (number == 14) ? '*' : '#';
Serial.println(c);
}
delay(800);
for (int i = 2; i <= 12; i++) digitalWrite(i, LOW);
}
void loop() {
int col = -1, row = -1, i = 0;
// Spalte (hohe Frequenz) finden
while (col == -1) {
if (detect_tone(x_frequencies[i])) col = i;
i = (i + 1) % 4;
}
i = 0;
// Zeile (niedrige Frequenz) finden
while (row == -1) {
if (detect_tone(y_frequencies[i])) row = i;
i = (i + 1) % 4;
}
print_number(row, col);
}
Schaltplan
Die Schaltung verbindet 10 LEDs an den Pins 2–11 (jeweils mit Vorwiderstand) und eine LED an Pin 13. Das Audiosignal wird über einen 1 µF-Kondensator an A0 geführt. Die Masse des Audiosignals muss mit der Arduino-Masse verbunden sein.

Herstellungsprozess
- Monitor-Ambilight selbst bauen mit Arduino Nano & WS2812B LEDs
- Ultraschall-Schwebegerät mit Arduino bauen – Akustische Levitation Schritt für Schritt
- SERENA: Eigenes Arduino Mega 2560 Alarmsystem mit TFT-LCD-Touchscreen
- Intelligentes Voltmeter mit Arduino & Smartphone bauen – Einfaches DIY-Projekt
- Echtzeit-IoT-Herzfrequenzmonitor mit Arduino & MAX30100
- Morsecode-Kommunikation mit Lasermodul – Duales Arduino-Projekt
- Arduino UNO WiFi Webserver: LED per Browser steuern
- Intelligenter Parkplatzzähler: Echtzeit-Fahrzeugverfolgung mit Arduino, Processing & PHP
- Arduino-gesteuertes automatisiertes Chrome Dino-Spiel bauen
- Python 3 zu Arduino UNO: Einfache Steuerung & LED-Demo