#include #include // --- Pin-Konfiguration --- const int PIN_HOOK = 25; // Gabelumschalter (Hörer abgenommen) const int PIN_NSA = 26; // Wählscheibe dreht sich (Arbeitskontakt) const int PIN_NSI = 27; // Wählscheibe Impulse // --- BLE Keyboard --- BleKeyboard bleKeyboard("Retro Phone", "Custom", 100); // --- Variablen --- String phoneNumber = ""; int pulseCount = 0; bool isDialing = false; bool lastNsiState = HIGH; unsigned long lastDebounceTime = 0; const unsigned long debounceDelay = 20; // 20ms Entprellung für alte Mechanik // Timer für den automatischen Anruf nach Eingabe der letzten Ziffer unsigned long lastDigitTime = 0; const unsigned long dialTimeout = 4000; // 4 Sekunden warten nach der letzten Ziffer bool callPending = false; void setup() { Serial.begin(115200); // Interne Pull-Ups aktivieren. (Bei stark oxidierten Kontakten des // alten Telefons externe 10k Widerstände gegen 3.3V verwenden!) pinMode(PIN_HOOK, INPUT_PULLUP); pinMode(PIN_NSA, INPUT_PULLUP); pinMode(PIN_NSI, INPUT_PULLUP); Serial.println("Starte BLE Keyboard..."); bleKeyboard.begin(); } void triggerShortcutAndCall(String number) { if (!bleKeyboard.isConnected()) { Serial.println("Fehler: iPhone nicht über BLE verbunden."); return; } Serial.println("Wähle Nummer: " + number); // 1. Kurzbefehl auslösen (Beispiel: Option + Command + C) // Passe diese Kombination an das an, was du im iPhone eingestellt hast. bleKeyboard.press(KEY_LEFT_ALT); // Option bleKeyboard.press(KEY_LEFT_GUI); // Command bleKeyboard.press('c'); delay(100); bleKeyboard.releaseAll(); // 2. Warten, bis das iOS-Eingabefeld des Kurzbefehls erscheint delay(1000); // 3. Nummer eintippen bleKeyboard.print(number); // 4. Mit Enter bestätigen, um den Anruf zu starten delay(200); bleKeyboard.write(KEY_RETURN); } void loop() { bool hookState = digitalRead(PIN_HOOK); // LOW = Hörer abgenommen (je nach Verdrahtung) bool nsaState = digitalRead(PIN_NSA); // LOW = Scheibe dreht bool nsiState = digitalRead(PIN_NSI); // Wechselt LOW/HIGH bei Impulsen // Nur aktiv, wenn der Hörer abgenommen ist if (hookState == LOW) { // Wählscheibe wird gerade gedreht if (nsaState == LOW) { isDialing = true; callPending = false; // Anruf-Timer abbrechen, solange gewählt wird // Impulse zählen (Entprellt) if (nsiState != lastNsiState) { if (millis() - lastDebounceTime > debounceDelay) { lastDebounceTime = millis(); if (nsiState == LOW) { // Flanke je nach Schalterart anpassen pulseCount++; } } } } // Wählscheibe ist in Ruheposition zurückgekehrt else if (isDialing) { isDialing = false; // 10 Impulse bedeuten die Ziffer 0 int digit = (pulseCount == 10) ? 0 : pulseCount; phoneNumber += String(digit); Serial.print("Erkannte Ziffer: "); Serial.println(digit); pulseCount = 0; lastDigitTime = millis(); callPending = true; // Timer für automatischen Anruf starten } // Wenn 4 Sekunden nach der letzten Ziffer nichts passiert ist -> Anrufen if (callPending && (millis() - lastDigitTime > dialTimeout)) { if (phoneNumber.length() > 0) { triggerShortcutAndCall(phoneNumber); phoneNumber = ""; // Nummernspeicher leeren callPending = false; } } } else { // Hörer ist aufgelegt -> Alles zurücksetzen if (phoneNumber.length() > 0 || callPending) { Serial.println("Hörer aufgelegt, setze zurück."); } phoneNumber = ""; pulseCount = 0; isDialing = false; callPending = false; } lastNsiState = nsiState; }