ESP8266 mit Telegram Bot - im Dauerbetrieb unzuverlässig

Sagt mal, eine prinzipielle Verständnisfrage:
Wenn ich mit einem Interrupt ein Signal verarbeiten will, muss ich das im Loop machen, oder kann ein Interrupt, sobald eine Pegeländerung auf LOW oder HIGH erfolgt, von sich aus eine Funktion anstoßen?
Die Bezeichnung "Interrupt" spräche ja dafür...

kann man ohne Kontext so nicht beantworten.

Prinzipiell soll eine ISR so kurz wie möglich sein. Ergo beschränkt ma sich oft darauf ein Flag zu setzen, eine Variable zu erhöhen,... und macht dann den Rest wenn man dazu im loop Zeit hat.

Ardino verlinkt in der Referenz auf

solltest lesen.

Ah, okey.
Ich will nämlich endlich meine Klingelerweiterung umsetzen.
Dazu muss ich die Zeit messen, wenn die Klingel gedrückt und wieder los gelassen wird. Die Klingel wird angezapft, das Signal auf 3.3V umgesetzt und digitalisiert (Klingel gedrückt = 0 V, los gelassen = 3.3V)
Ich würde dann in der ISR das Ereignis beim Wechsel von HIGH eines Interrupts auf LOW (falling, wenn also die Klingel gedrückt wird) dazu nutzen einen Timestamp in ein Array "arr_falling" zu schreiben und dann von LOW auf HIGH (rising, wenn die Klingel wieder los gelassen wird) in ein zweites Array "arr_rising".
Gleichzeitig würde beim ersten Drücken ein Timer getriggert, der nach zB. 5 Sekunden den Code abgleicht, ob er übereinstimmt (und dann den Türsummer betätigt).

etwas "Handbetätigtes" wie ein Klingel-Schalter und Interrupt klingen in sich ja schon eher suboptimal.

Was blockierst du heute in deinem Sketch so sehr, dass man eine Klingelbetätigung nicht mitbekommen würde? Und Zusatzfrage: Warum blockierst du deinen Sketch?

Was blockierst du heute in deinem Sketch so sehr, dass man eine Klingelbetätigung nicht mitbekommen würde? Und Zusatzfrage: Warum blockierst du deinen Sketch?

Im Loop wird jede Sekunde der Bot nach einer neuen Nachricht abgefragt, das könnte die zeitliche Abfolge des Klingelcodes verzögern und damit unbrauchbar machen.

Ich will ja durch das Klingeln einen Code übermitteln, zB: 3 Sek. Klingel gedrückt, 1 Sek. nicht gedrückt, 0.5 Sekunden gedrückt, 0.5 Sek. nicht, 1 Sek. gedrückt.
Falls eine der Zeiten um mehr als zB. 10% abweicht gilt der Drück-Code nicht.
Ich würde daher bei jedem Interrupt-Wechsel millis() abfragen und ins Array schreiben. Nach der maximalen Eingabezeit (mit Timer) werte ich es aus (per Differenz) und betätige den Türsummer, oder eben nicht.
Die Bot-Abfrage im Loop würde ich daher auch in dieser Zeitspanne deaktivieren, damit er nicht in die Quere kommt. Ich vermute, wenn da in der Telegram Bot Library die Funktionen aufgerufen werden, könnte das die millis() Abfragewerte ungenau machen.

Etwas genauer: sobald die Klingel betätigt wird, wird ein Timer (zB 2 Sek.) gestartet und die Botabfrage im Loop deaktiviert. Damit die Codeeingabe gestartet wird, muss 2 Sekunden gedrückt und gehalten werden (wir haben eine Ding-Dong-Klingel, die klingelt also nicht durchgehend, so lange gedrückt wird), danach wird die Klingel selbst per Relais ausgeschaltet (die Klingelsignale natürlich nicht).
Sobald der 2 Sek. Timer abgelaufen ist, wird der Klingelcode durch weiteres Klingeldrücken abgefragt, ausgewertet und der Bot wieder aktiviert. Die Klingel wird dann natürlich wieder eingeschaltet (die Unterbrechung per Relais deaktiviert). Falls also die Übermittlung der Codesignale zB 3 Sekunden dauert, wird der Bot insgesamt 5 Sekunden unterbrochen (2 Sekunden als Startsignal, 3 Sekunden für den Code).
Falls dann jemand bei uns "Sturm" klingelt, denkend, wir hätten eine RRRRing-Klingel, wird mein ESP (höchstwahrscheinlich vergeblich) einem Code lauschen und insgesamt 5 Sekunden den Bot aussetzen.

Die Klingel will ich also mit drei Kabeln anzapfen: eine Zuleitung wird unterbrochen und führt zu einem Kontakt der Klingel zum ESP und zurück (das sind zwei Kabel) und eines führt vom anderen Kontakt der Klingel zum ESP.

das würde ich an deiner Stelle erst mal in einen Stand-Alone Sketch auf Praktikabilität testen.
10% von 500 ms ... das heißt der Anwender müsste zwischen 475ms und 525 ms treffen, das stelle ich mir sehr schwierig vor (auch wennst auf +/- 10% gehen würdest).

An wie viele verschiedene Events denkst du aktuell?

Genau das hatte ich schon vor :slight_smile:
Mit einem anderen NodeMCU. Ich habe auch einen Test-Bot, an dem ich das alles immer erst mal austeste und wenn es passt kommentiere ich ein #define Befehl aus, dann wird der produktive Bot genutzt.

Ich würde natürlich die Abweichung als Variable hinterlegen, konfigurierbar und im Flashspeicher ablegbar (so wie den Öffnungs-Code selbst auch).
Falls das schwer zu treffen wäre, würde ich natürlich hoch gehen mit der Toleranz. Letztlich sollte es aber schon auch wenigstens ein bisschen schwer sein, es zu treffen :wink:
Auch schon damit es nicht zu oft zufällig getroffen würde.

Im Moment denke ich an einen einfachen Code etwa:
AN(3) - AUS(1) - AN(0.5) - AUS(0.5) - AN(0.5) - AUS(0.5) - AN(0.5)
In Klammer die Sekunden.
Ich kann mir aber auch vorstellen, dass ich, wenn die Kinder das gar nicht hinkriegen (dann bräuchte ich es auch nicht) auf zB 5 Sekunden Dauerdrücken stelle dann geht es auf. Plus Minus eine Sekunde etwa. Oder danach noch mal kurz einen einzigen Drücker (und mehr als einer sperrt).
Ich muss eigentlich nur die Sturmklingler ausschließen. Die zeichnen sich ja durch Ungeduld aus.
Der durchschnittliche Sturmklingler weiß aber auch nicht, ob die Klingel eine Dingdongklingel oder eine Rrrringklingel ist.
Ich vermute mal, ein typischer Sturmklingler kombiniert, etwa:
AN(3) - AUS(0.5) - AN(0.2) - AUS(0.2) - AN(0.2) - AUS(0.2) - AN(0.2) - AUS(0.2) - AN(0.2) - AUS(0.2) etc.
Müsste ich mal bei Allensbach eine Umfrage in Auftrag geben :wink:
Aber das Sturmklingeln würde ich nebenbei natürlich auch verunmöglichen :wink:

nein ich meine wie viele verschiedene Aktionen du über die Leitung steuern willst?

zwei?
drei
10?
Viele`?

Das verstehe ich jetzt nicht. Über die Leitung der Klingel?
Keine. Da lausche ich ja nur und unterbreche sie, damit sie nicht weiter klingeln kann, wenn es mir zu viel wird (oder ich sie sonst warum mal ausschalten will). Gelauscht nach den 13.4 Volt AC beim Klingeln wird natürlich weiterhin (mit Diode, Elko, Widerständen und einem BC irgendwas Transistor).
Klingel und Türsummer sind zwei verschiedene Systeme.

du schriebst:

Was soll klingeln?
Worüber wird der "Code" übertragen?

Hatte ich doch weiter oben schon beschrieben.
Kurz: Die Kinder klingeln auf eine bestimmte Weise (=Code) und dann betätigt mein ESP den Türsummer, wenn der Klingelrhythmus gepasst hatte.

Für einen außenstehenden ist es nicht zu unterscheiden, ob ich in der Wohnung den Türsummer betätigt hatte, oder ob das die Kinder ausgelöst hatten.
Schon jetzt stehe ich nicht auf und gehe zur Türsprechanlage (wo der Türsummerknopf angebracht ist) um zu öffnen. Ich weiß, wann sie ungefähr kommen, also öffne ich per Bot (s.o.).

das heißt es gibt einen einzigen Code, der genau eine Aktion auslöst - nämlich den Summer einzuschalten?

Genau. Den Türsummer für 2 Sekunden (derzeit so eingestellt) einzuschalten.
Weicht er (zu sehr) ab macht der ESP nichts. Wird "Sturm" geklingelt unterbricht der ESP die Klingel für eine kurze Zeit.

ich würde keine fixen Zeiten definieren.
Basierend auf MorseCode definieren dah = 3 x dit
Die erste Klingelbetätigung als Längendefinition nehmen (entweder als dit oder dah)
Davon abhängig die weiteren dit/dahs mit großzügigen Varianzen interpretieren.

Nichts kompliziertes einfach einen "Buchstaben" der ausreichend lang ist und so anfängt wie deine Startbedingung.

(link anschauen, ich hab da bewusst wohin gelinkt!(!!!).

1 Like

Gute Idee, danke für den Vorschlag! Werde ich prüfen, klingt schlüssig!

Übrigens ist mein ESP jetzt schon seit 20.11.2022 morgens ohne Reboot, funktioniert problemlos.
Entweder Zufall oder meine Maßnahmen Strings zu vermeiden (char* oder F-Makro usw.) haben tatsächlich geholfen.
Allerdings waren am 19. und 20.11. drei Reboots relativ kurz nacheinander (paar Stunden) woraus ich schließe, dass der ESP wg. des öffentlich erreichbaren Bots durchaus noch anfällig ist gegenüber DoS o.ä. Attacken aus dem Netz. Ich habe zwar die Lib. geändert und die Nachrichtenlänge drastisch gekürzt, aber ich vermute, da gibt es Spambots, die alles abgrasen und auch mal meinen Bot erwischen.

Seit ein paar Wochen habe ich jetzt nichts mehr gemacht, der Code schnurrt vor sich hin.
Gelegentlich, aber selten startet der ESP neu, ich vermute dass irgendwelche Nachrichten vom Bot, die ich nicht sehe, ihn zum Absturz und Neustart bringen, aber hängen geblieben ist er nicht mehr, ist also eigentlich zuverlässig.
Einmal hatte ich es aber, dass die Nachricht zum öffnen einfach nicht bearbeitet wurden, dann ging die Tür natürlich auch nicht auf und ich musste den Schlüssel nehmen. Keine Ahnung warum, die Nachrichten hatten zwei Häkchen, waren also beim Bot angekommen.
Hatte es sofort nochmal probiert, also zwei Nachrichten, die nie bearbeitet wurden.
So was darf natürlich gar nicht vorkommen.

Das Projekt mit der Klingel abgreifen ruht noch, ich ahne, dass mich das wieder sehr aufhalten wird :wink:

Seit 31. Januar 2023 keinen Reboot mehr.
Ich vermute Reboots werden von irgendwelchen Werbebots verursacht, die meinen Bot zuballern o.ä.
"Bei Gelegenheit" werde ich mal einen schwierigeren Namen für den Bot probieren...

Seit ein paar Tagen, genauer: seit 10. Mai, habe ich gehäufte Reboots :frowning:
Ohne viel eigene Aktivitäten, also täglich betätige ich den Öffner im Schnitt vielleicht 5 mal.

Ich glaube, die Reboots sind entweder Telegram oder irgendwelchen Spambots geschuldet.
Gestern hat er auch seit längerem mal wieder auf einen öffnen Befehl gar nicht reagiert, ich vermute, das liegt dann an den Telegram Servern, hatte ich schon mal, lag offenbar aber nicht an meinem Code, bzw. höchstens indirekt, weil ich so was nicht abfange, weil ich auch gar nichts davon mit kriege.

PS.: der Klingel Code ist immer noch auf dem ToDo-Haufen ...

Jetzt hat es sich wieder beruhigt. Heute Morgen zwar ein (spontaner) Reboot, aber davor erst am 1. Juni 2023.
Die Ausgabe des Heap Speicher Zustandes ist aber offenbar willkürlich. Im Moment heißt es:

Freier (Heap) Speicher: 9984
maximal verfügbar: 8904
fragmentiert: 11%

und ein paar Sekunden später sind es nur noch 9%:

Freier (Heap) Speicher: 9984
maximal verfügbar: 9104
fragmentiert: 9%

und mein Code, um den Heap anzuzeigen ist ja gerade sogar fragmentierend:

     uint32_t free;
        uint16_t max;
        uint8_t frag;
        ESP.getHeapStats(&free, &max, &frag);
        bot.sendMessage(trusted_chat_id1, "Freier (Heap) Speicher: " + String(free) + "\nmaximal verfügbar: " + String(max) + "\nfragmentiert: " + String(frag) + "%", "");

Ist ja nicht dazu gedacht dauernd aufgerufen zu werden, daher auch munter String-Klassen-Verwendungen.

Also zur Zeit habe ich wieder auffällig viele Reboots, ich denke das sind irgendwelche Telegram Spam Nachrichten, die ich so nicht mit kriege.
Muss ich mal was in die Bibliothek einbauen, damit ich sehe, ob da was aufläuft...
... Ich hab jetzt einen Test-Arduino mit Test-Bot (mit dem selben Code bis auf die Bot-ID) an einen Laptop angeschlossen, den ich durchlaufen lassen kann. In der Hoffnung es tritt da auch auf.
Mit Debugmeldung, wenn eine unberechtigte Nachricht kommt und auch Debug-Ausgaben auf der seriellen Schnittstelle. Mal sehen, ob ich was raus kriege.