Ich hatte ein Wochenende Sturmfrei und am Freitag gemerkt, dass die alte „Auerswald Commander Basic“ Anlage mal wieder abgeraucht ist. Die war nur noch für die Türklingel da, weil die Festnetz-Telefone bereits alle als DECT Telefone über die Fritzbox liefen. Ein Ersatzmainboard für die Auerswald würde zwar nicht die Welt kosten, dann wär aber immer noch die Kiste nur für Klingel ein Stromfresser. Am besten wäre es, das Klingelsignal von der Tür in die Fritzbox zu bekommen, dass die DECT-Telefone läuten, wenn es klingelt. Es gibt dafür auch Kauf-Lösungen (bspw. KlingelPaul) aber das müsste man auch erst wieder bestellen. Nach (relativ viel) Recherche, habe ich mich entschieden, die Fritzbox Klingel nachzubauen. Dafür hatte ich alles da – dachte ich zumindest. Das Funktionsprinzip, von hinten an der Fritzbox endend betrachtet, ist folgendes:

  • Die Fritzbox macht ein Rundruf auf alle DECT Telefone, wenn eine bestimmte Rufnummer gewählt wird. In meines Fall die Nummer 11. (Telefoniegeräte -> FON1 oder FON2 -> Einstellungen aus Screenshot)
  • An dem entsprechenden RJ11 Input der Fritzbox (FON2 bei mir) wird das Signalkabel des Klingelarduino angeschlossen. Das Signal kommt von Pin 12 & 13 am Arduino und wird an den beiden mittleren Pins im RJ11 Kabel angeschlossen.
  • Der Arduino, bei mir ein UNO, erzeugt einen Anruf mit einer Tonfolge im DTMF Format, die zur Signalanpassung noch durch den Übertrager mit vorgeschalteten Widerständen muss. Das passendste das bei mir rumlag war ein 12V Trafo. Der Arduino macht also“ Biep Biep“ und die Fritzbox denkt, es wurde die Nummer 11 gewählt.
  • Damit der Anruf aufgelegt werden kann, muss das Signal auf der Sekundärseite des Trafos unterbrochen werden, sonst klingelt es bis ans Ende der Zeit. Das Unterbrechen passiert über ein Relais. Ich hatte nur ein 12V Relais.
  • Daher brauchte ich noch eine 12V Spannungsquelle (Steckernetzteil) und ein NPN Transistor (BC337) um mit meinem 5V Arduino Signal die 12V vom Relais zu schalten.
  • Das ganze wird über die Türklingel ausgelöst, was in diesem Fall ein einfacher Taster ist.
  • Zuletzt muss Phantomklingeln verhindert werden = Störsignale werden in die Klingelleitung eingestreut und erzeugen ein Klingeln ohne dass jemand den Taster drückt. In der oben verlinkten Anleitung wird dafür ein weiteres Relais genutzt. Das wollte ich nicht (weil ich kein passendes hatte) und habe ein Debounce/Entprellen des Schalters softwareseitig gelöst. Der Klingeltaster muss mindestens 250ms gedrückt werden, damit der Arduino den Tasterdruck akzeptiert.

Ich habe zum basteln erstmal alles frei verdrahtet und gelötet. Damit der Printtrafo nicht rumfliegt habe ich den mit Kabelbindern an den Arduino gezurrt. Das ganze Geraffel ist übergangsweise in einer kleinen Papp-Kiste neben der Fritzbox (ich weiß selbst dass das „übergangsweise“ vmtl. doch eine Dauerlösung ist). Als Klingeldauer sind aktuell 10 Sekunden eingestellt, die (und auch die Debounce-Zeit) können sehr einfach über das INO-File angepasst werden.

Da nun das Klingelsignal von der Fritzbox erkannt wird, kann man noch einiges mehr anstellen. Ich hab mir die FRITZ!App Fon heruntergeladen. Jetzt bekomme ich auch einen Anruf aufs Handy wenn ich heimischen WLAN bin und die App im Hintergrund läuft. Das ist sehr praktisch, wenn ich mal im Garten oder der Werkstatt bin. Da ist das Handy meist eh dabei.


 /* DTMF encoder (Dual Tone Generator) for a Phone Dialer
 *  Created by David Dubins, May 13th, 2016.
 *  Released into the public domain.
 * 
 *  modifiziert zur einfachen Fritzbox a/b Klingel von klx 07/2018
 *  
 * Setup:
 * 4,7KOhm als Pull-Up von Pin 2 auf 5V
 * Klingeltaster zw. Pin 2 und GND
 * Pin 12 und 13 je via 240 Ohm auf Übertrager 
 * Übertrager dann nach GND, 4,7uF paralell zum Übertrager
 * Leiterplattenrelais zw. Pin 8 und 5V
 * Ausgangsseite des Übertrager über den Relaiskontakt zur a/b Schnittstelle 
 *
 * Übertrager Wicklung 1:6; 6 Ohm zu 180 Ohm, ähnliche sicherlich auch möglich
 *
 * Funktion:
 * beim Betätigen des Tasters zieht das Relais an und belegt die a/b Schnittstelle.
 * Es wird die Rufnummer 11 gewählt und nach 10 Sek die Verbindung wieder beendet
 */

const byte tone1Pin=12; // pin for tone 1
const byte tone2Pin=13; // pin for tone 2
byte PhoneNumber[]={1,1}; // for special characters: 10=*, 11=#, 12=1sec delay  // zu wählende Rufnummer
byte PhoneNumberLength = 2;  // adjust to length of phone number
const byte buttonPin=2; // for momentary switch
const int ledPin =  8;

int buttonState = LOW; //this variable tracks the state of the button, low if not pressed, high if pressed
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 250;    // the debounce time; increase if the output flickers


// frequencies adopted from: https://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling
int DTMF[13][2]={
  {941,1336}, // frequencies for touch tone 0
  {697,1209}, // frequencies for touch tone 1
  {697,1336}, // frequencies for touch tone 2
  {697,1477}, // frequencies for touch tone 3
  {770,1209}, // frequencies for touch tone 4
  {770,1336}, // frequencies for touch tone 5
  {770,1477}, // frequencies for touch tone 6
  {852,1209}, // frequencies for touch tone 7
  {852,1336}, // frequencies for touch tone 8
  {852,1477}, // frequencies for touch tone 9
  {941,1209}, // frequencies for touch tone *
  {941,1477}, // frequencies for touch tone #
  {0,0} // pause
};


void setup()
{  
  pinMode(tone1Pin,OUTPUT); // Output for Tone 1
  pinMode(tone2Pin,OUTPUT); // Output for Tone 2
  pinMode(buttonPin,INPUT); // Button
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}


void loop()
{
//sample the state of the button - is it pressed or not?
  buttonState = digitalRead(buttonPin);
  //if the button has been pressed
  if ((buttonState == HIGH) ) {
   //filter out any noise by setting a time buffer = is enough time gone since the button is pressed? 
    if (  (millis() - lastDebounceTime) > debounceDelay) {
      digitalWrite(ledPin, LOW);
        delay(300);
      dialNumber(PhoneNumber,PhoneNumberLength);  // Dial the number
      lastDebounceTime = millis(); //set the current time
    }
    else  {
      lastDebounceTime = millis(); //set the current time
    }
  }
}

void playDTMF(byte digit, byte duration){
  boolean tone1state=false;
  boolean tone2state=false;
  int tone1delay=(500000/DTMF[digit][0])-10; // calculate delay (in microseconds) for tone 1 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing.
  int tone2delay=(500000/DTMF[digit][1])-10; // calculate delay (in microseconds) for tone 2 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing.
  unsigned long tone1timer=micros();
  unsigned long tone2timer=micros();
  unsigned long timer=millis(); // for timing duration of a single tone
  if(digit==12){
    delay(1000); // one second delay if digit is 12
  } else {
    while(millis()-timer<duration){
      if(micros()-tone1timer>tone1delay){
        tone1timer=micros(); // reset the timer
        tone1state=!tone1state; // toggle tone1state
        digitalWrite(tone1Pin, tone1state);
      }
      if(micros()-tone2timer>tone2delay){
        tone2timer=micros(); // reset the timer
        tone2state=!tone2state; // toggle tone2state
        digitalWrite(tone2Pin, tone2state);
      }
    }
    digitalWrite(tone1Pin,LOW);
    digitalWrite(tone2Pin,LOW);
  }
}

void dialNumber(byte number[],byte len){
  for(int i=0;i<len;i++){
    playDTMF(number[i], 100);  // 100 msec duration of tone
    delay(100); // 100 msec pause between tones
 }
  delay(10000);  //Zeit bis die Verbindung wieder getrennt wird
 digitalWrite(ledPin, HIGH);
}
//END OF FILE

Leave a comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert