DTMF Decoder für mehrere Töne

Hallo zusammen,

ich möchte gerne einen DTMF Decoder für mehrere Töne bauen. Ein Ton ist ja kein Problem. Dazu hab ich schon die Library DTMF und auch ein MT8870 Modul Versucht. Leider scheitere ich schon im Ansatz eine ganze Tonfolge wie z.B. 5532# auszuwerten .

Hat mir diesbezüglich jemand vielleicht Hilfe oder Idee ?

Gruß Wolf

Wenn du den MT8870 schon kennst, ist das doch kein Problem mehr.

Der dekodiert doch und du must es nur richtig weiter verarbeiten.

Wo genau ist denn da dein Problem?

Das Problem ist nicht der Singleton. Das ist ja kein Problem den zu verarbeiten. Was ich brauche sind zur Steuerung eine ganze Tonfolge.

z.B.

5543* schaltet ein Relais EIN
5544* schaltet das wieder AUS

Gruß Wolf

DL2MWB:
Das Problem ist nicht der Singleton. Das ist ja kein Problem den zu verarbeiten. Was ich brauche sind zur Steuerung eine ganze Tonfolge.

z.B.

5543* schaltet ein Relais EIN
5544* schaltet das wieder AUS

Gruß Wolf

Du bekommst doch für jeden Ton eine BCD-Codierung raus, diese speicherst du bei Erhalten des StD-Signals und wartest auf die nächste Codierung und wieder speichern wenn StD anliegt usw.

Dann fügst du es zusammen.
BCD sagt dir doch etwas, oder ?

Dazu brauchst du 5 Pins am Arduino und wertest es per Sketch aus.

Edit:
Hier hast du eine hübsche Animation dazu bei Eingabe einer "5".
Beachte auch den Pin "StD".

Hallo ...

Ja BCD ist schon klar. Sieht man ja such sehr schön an den LEDs des MT8870. Ich scheitere "nur" an dem Gedanken wie ich das Speichere und zusammen füge. Der Zeichen nach ja in einen String.

Ich werde nochmal in mich gehen. Hi

Gruß Wolf

DL2MWB:
Hallo ...

Ja BCD ist schon klar. Sieht man ja such sehr schön an den LEDs des MT8870. Ich scheitere "nur" an dem Gedanken wie ich das Speichere und zusammen füge. Der Zeichen nach ja in einen String.

Ich werde nochmal in mich gehen. Hi

Gruß Wolf

Speichere es in ein Char Array, da kannst du die einzelnen Zeinen mittels "strcat" zusammensetzen.

Ok Danke erst mal.

Gruß Wolf

DL2MWB:
Ok Danke erst mal.

Gruß Wolf

Alles klar und gerne.

Also irgendwie will das alles nicht wie ich will . hi

Ich will den STQ zustand so abfragen das er nur einmal einen Status liefert.

Abgespeckt und Fehlerhaft so:

static boolean DTMFrx = true;

const int STQ = 3;  // Pin STQ vom DTMF Module zum Arduino (Pin3)

int stSTQ = 0;       // Variable fuer Status (HIGH/LOW) des STQ


void setup(){ 
  Serial.begin(9600);
  
  pinMode(STQ, INPUT);  // Pin als Input definieren
}

void loop(){
  stSTQ = digitalRead(STQ);   // Lese Status (HIGH/LOW) des Pins STQ ein
  
  if (stSTQ==HIGH)            // wenn stSTQ HIGH ist DANN ...
  {
    if(DTMFrx)
      {
        Serial.println("STQ ist HIGH");
        DTMFrx = false;     
      }
     DTMFrx = true;  
  }

 }

Auf was ich raus will sieht man sicher am DTMFrx = false .. Allerdings muss ich den ja wieder irgendwann als true setzen und somit ist das ganze für die Katz :slight_smile:

Gibt man also einen langen DTMF Ton drauf bleibt der STQ solange auf HIGH bis der Ton wieder abfällt und Serial gibt er natürlich ímmer endlos das selbe. Will ich aber nur einmal. Vermutlich denke ich wieder mal viel zu kompliziert.

Gruß Wolf

Die Animation zeigt dir doch, wie es funktionieren soll.

Du must auch die 4 Code-Pins einlesen und wenn dein "stSTQ" auf High springt, die Code-Pins in Variablen speichern. Danach die Daten zusammenführen.

Ich komm auf die Google Seite mit Bilder wenn ich die Animation anklicken will. Leider nicht zur Animation.

Die anderen Pins lese ich dann natürlich auch ein wie z.B. die Taste 1 mit:

// Taste [1]
if(stQ4==LOW && stQ3==LOW && stQ2==LOW && stQ1==HIGH )

Ich werde weiter mein Glück versuchen :slight_smile:

Wolf

Seltsam, bei mir springt er sofort zur Animation.

Dies hier ist im Browser die Animation.

Animation.jpg

Das Bild sehe ich schon in deinem ersten Link, aber warum auch immer ist das kein Animiertes Bild bei mir.

Ich hab die Abfrage nun mal so gemacht, aber das Problem bleibt ja bestehen:

const int Q1  = 7;  // Pin Q1 vom DTMF Module zum Arduino (Pin7)
const int Q2  = 6;  // Pin Q2 vom DTMF Module zum Arduino (Pin6)
const int Q3  = 5;  // Pin Q3 vom DTMF Module zum Arduino (Pin5)
const int Q4  = 4;  // Pin Q4 vom DTMF Module zum Arduino (Pin4)
const int STQ = 3;  // Pin STQ vom DTMF Module zum Arduino (Pin3)

int stQ1 = 0;     // Variable fuer Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ
int stQ2 = 0;     // ...
int stQ3 = 0;     // ...
int stQ4 = 0;     // ...
int stSTQ = 0;     // ...


void setup(){ 
  Serial.begin(9600);
  
  pinMode(Q1,  INPUT);  // Pins als Input definieren
  pinMode(Q2,  INPUT);  // ...
  pinMode(Q3,  INPUT);  // ...
  pinMode(Q4,  INPUT);  // ...
  pinMode(STQ, INPUT);  // ...
}

void loop(){
  stQ1  = digitalRead(Q1);    // Lese Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ ein.
  stQ2  = digitalRead(Q2);    // ... 
  stQ3  = digitalRead(Q3);    // ... 
  stQ4  = digitalRead(Q4);    // ... 
  stSTQ = digitalRead(STQ);   // ... 
  

  // Taste [1]   
  if(stSTQ==HIGH && stQ4==LOW && stQ3==LOW && stQ2==LOW && stQ1==HIGH )
     {
         Serial.println("1");
     }  
     
  // Taste [2]  
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==LOW && stQ2==HIGH && stQ1==LOW )
    {
         Serial.println("2");
    }
  
  // Taste [3]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==LOW && stQ2==HIGH && stQ1==HIGH )
    {
         Serial.println("3");
    }

  // Taste [4]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==HIGH && stQ2==LOW && stQ1==LOW )
    {
         Serial.println("4");
    }

  // Taste [5]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==HIGH && stQ2==LOW && stQ1==HIGH )
    {
         Serial.println("5");
    }

  // Taste [6]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==HIGH && stQ2==HIGH && stQ1==LOW )
    {
         Serial.println("6");
    }

  // Taste [7]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==HIGH && stQ2==HIGH && stQ1==HIGH )
    {
         Serial.println("7");
    } 

  // Taste [8]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==LOW && stQ2==LOW && stQ1==LOW )
    {
         Serial.println("8");
    }    
    
  // Taste [9]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==LOW && stQ2==LOW && stQ1==HIGH )
    {
         Serial.println("9");
    }

  // Taste [0]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==LOW && stQ2==HIGH && stQ1==LOW )
    {
         Serial.println("0");
    } 
    
  // Taste [*]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==LOW && stQ2==HIGH && stQ1==HIGH )
    {
         Serial.println("*");
    }
    
  // Taste [#]         
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==HIGH && stQ2==LOW && stQ1==LOW )
    {
         Serial.println("#");
    }

  // Taste [A]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==HIGH && stQ2==LOW && stQ1==HIGH )
    {
         Serial.println("A");
    }
    
  // Taste [B]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==HIGH && stQ2==HIGH && stQ1==LOW )
    {
         Serial.println("B");
    }

  // Taste [C]
  else if(stSTQ==HIGH && stQ4==HIGH && stQ3==HIGH && stQ2==HIGH && stQ1==HIGH )
    {
         Serial.println("C");
    } 
    
  // Taste [D]
  else if(stSTQ==HIGH && stQ4==LOW && stQ3==LOW && stQ2==LOW && stQ1==LOW )
    {
         Serial.println("D");
    }

delay(50);  // Debounce wirklich benötigt ?

}

Bleibe ich auf der der Tasten 1 auf dem Encoder das habe ich einen laaaaaaangen Ton … Somit schreibt dann das Terminal z.B.

1
1
1
1
1
1
1
1
1

Das will ich ja nicht. Ich will nur einmal eine “1” wegen der weiterverarbeitung. Mit “Old” will ich nicht abfangen weil ich sonst keine Zahl wie z.B. 5113 empfangen kann. Würde ja sonst eine 513 draus gemacht.

Wolf

Du machst es dir zu einfach.
Die Abfrage der Code-Pins musst du ständig in der Loop machen und erst wenn der stSTQ auf HIGH geht die Daten in die Variable übernehmen.
Unmittelbar danach erfolgt die Auswertung um welche Taste es sich handelt und dann das Übernehmen in das Char Array.

Hmmm, aber ich mach die Abfrage doch ständig in der loop.

void loop(){
  stQ1  = digitalRead(Q1);    // Lese Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ ein.
  stQ2  = digitalRead(Q2);    // ...
  stQ3  = digitalRead(Q3);    // ...
  stQ4  = digitalRead(Q4);    // ...
  stSTQ = digitalRead(STQ);   // ...

Dannach dann die if Anweisungen.

Wolf

Stimmt, da habe ich mich falsch ausgedrückt.
Wichtig ist das Übernehmen in die Variable die danach zur Auswertung gelangt.
Ich würde es etwa so machen.

Beispielcode, ungetestet.

void loop()
{
  stQ1  = digitalRead(Q1);    // Lese Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ ein.
  stQ2  = digitalRead(Q2);    // ...
  stQ3  = digitalRead(Q3);    // ...
  stQ4  = digitalRead(Q4);    // ...
  stSTQ = digitalRead(STQ);   // ...

  if (stSTQ == HIGH)
  {
    if (step1 == 0) {
      decodeDTMF(stQ1, stQ2, stQ3, stQ4);
    }
  }
}


void decodeDTMF(int aQ1, int bQ2, int cQ3, int dQ4) {
  step1 = 1;

  // hier folgt die Wandlung in die entsprechende Taste
  // mit Speicherung ins Array + Zähler für die Stelle und setzen von "step1" auf 0.
   
}

HotSystems ich steh da auf dem Schlauch. Ich muss das erst mal versuchen genau zu verstehen.

DANKE erst mal ...

Wolf

Runter vom Schlauch, Du bist eigentlich nah an der Lösung. Notwendig ist eine Flankenabfrage, also nicht den Zustand von stSTQ sondern seine Änderung von LOW nach HIGH abfragen:

const byte Q1  = 7;  // Pin Q1 vom DTMF Module zum Arduino (Pin7)
const byte Q2  = 6;  // Pin Q2 vom DTMF Module zum Arduino (Pin6)
const byte Q3  = 5;  // Pin Q3 vom DTMF Module zum Arduino (Pin5)
const byte Q4  = 4;  // Pin Q4 vom DTMF Module zum Arduino (Pin4)
const byte STQ = 3;  // Pin STQ vom DTMF Module zum Arduino (Pin3)

bool stQ1 = LOW;     // Variable fuer Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ
bool stQ2 = LOW;     // ...
bool stQ3 = LOW;     // ...
bool stQ4 = LOW;     // ...
bool stSTQ = LOW;     // ...
bool altSTQ;


void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  pinMode(Q1,  INPUT_PULLUP);  // Pins als Input definieren
  pinMode(Q2,  INPUT_PULLUP);  // ...
  pinMode(Q3,  INPUT_PULLUP);  // ...
  pinMode(Q4,  INPUT_PULLUP);  // ...
  pinMode(STQ, INPUT_PULLUP);  // ...
  stSTQ = digitalRead(STQ);   // ...
  altSTQ = stSTQ;
}

void loop() {
  stQ1  = digitalRead(Q1);    // Lese Status (HIGH/LOW) der Pins Q1,Q2,Q3,Q4,STQ ein.
  stQ2  = digitalRead(Q2);    // ...
  stQ3  = digitalRead(Q3);    // ...
  stQ4  = digitalRead(Q4);    // ...
  altSTQ = stSTQ;
  stSTQ = digitalRead(STQ);   // ...


  // Taste [1]
  if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == LOW && stQ2 == LOW && stQ1 == HIGH )
  {
    Serial.println("1");
  }

  // Taste [2]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == LOW && stQ2 == HIGH && stQ1 == LOW )
  {
    Serial.println("2");
  }

  // Taste [3]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == LOW && stQ2 == HIGH && stQ1 == HIGH )
  {
    Serial.println("3");
  }

  // Taste [4]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == HIGH && stQ2 == LOW && stQ1 == LOW )
  {
    Serial.println("4");
  }

  // Taste [5]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == HIGH && stQ2 == LOW && stQ1 == HIGH )
  {
    Serial.println("5");
  }

  // Taste [6]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == HIGH && stQ2 == HIGH && stQ1 == LOW )
  {
    Serial.println("6");
  }

  // Taste [7]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == HIGH && stQ2 == HIGH && stQ1 == HIGH )
  {
    Serial.println("7");
  }

  // Taste [8]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == LOW && stQ2 == LOW && stQ1 == LOW )
  {
    Serial.println("8");
  }

  // Taste [9]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == LOW && stQ2 == LOW && stQ1 == HIGH )
  {
    Serial.println("9");
  }

  // Taste [0]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == LOW && stQ2 == HIGH && stQ1 == LOW )
  {
    Serial.println("0");
  }

  // Taste [*]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == LOW && stQ2 == HIGH && stQ1 == HIGH )
  {
    Serial.println("*");
  }

  // Taste [#]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == HIGH && stQ2 == LOW && stQ1 == LOW )
  {
    Serial.println("#");
  }

  // Taste [A]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == HIGH && stQ2 == LOW && stQ1 == HIGH )
  {
    Serial.println("A");
  }

  // Taste [B]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == HIGH && stQ2 == HIGH && stQ1 == LOW )
  {
    Serial.println("B");
  }

  // Taste [C]
  else if (!altSTQ && stSTQ && stQ4 == HIGH && stQ3 == HIGH && stQ2 == HIGH && stQ1 == HIGH )
  {
    Serial.println("C");
  }

  // Taste [D]
  else if (!altSTQ && stSTQ && stQ4 == LOW && stQ3 == LOW && stQ2 == LOW && stQ1 == LOW )
  {
    Serial.println("D");
  }

  delay(50);  // Debounce wirklich benötigt ?

}

agmue erst mal Danke .. Ich seh den Wald vor Bäumen nicht mehr. HI

Weiter oben schrieb ich noch das ich die "Old" Variante bei den Zahlen nicht verwenden kann :slight_smile:
Aber das ich die für den STQ verwenden kann ist mir wohl nicht mehr in den Sinn gekommen. HI

Danke !!!

Wolf