W1 mini kein Ping oder http Aufruf aus Funktion

Mahlzeit zusammen,

ich habe hier einen D1 mini welchen ich nutzen möchte um einen Rechner aus der Ferne hoch und wieder runter zu fahren.
Auf einem lokalen Web-Server läuft ein php Script welches den Rechner startet, das funktioniert auch zuverlässig. Auf dem entsprechenden PC läuft beim Startet ein Dienst welcher über http angesprochen wird, der den Rechner runterfährt, dass funktioniert auch zuverlässig.

Am W1 ist ein Taster mit LEDs.
Geplant ist, dass der W1 den Rechner anpingt um zu schauen, ob dieser online oder offline ist.
Wird der Taster betätigt löst dieser einen Interupt aus, dort wird je nachdem ob der Rechner online oder offline ist eine weitere Funktion aufgerufen wird, entweder wird halt das php Script angesprochen um dem Rechner hochzufahren oder der Rechner per http um runterzufahren.

Aus dem normalen loop() funktioniert das generell auch alles.
Sobald ich aber aus der Interrupt Funktion oder aus den anderen Funktionen einen Ping absetze bekomme ich als Ergebnis immer 0 zurück und der http Aufruf gibt mir immer -1 zurück (im normalen loop() bekomme ich mit dem selben Aufruf 200 als http Code zurück)

Ich habe mir in den Funktionen schon die Variablen für die IP Adressen ausgeben lassen weil ich befürchtete die sind dort nicht mehr vorhanden, aber die benötigten Variablen liegen alle in den Programmteilen vor.

Ich verstehe einfach nicht, warum aus dem loop() alles funktioniert und aus dem Funktionen nicht.

Hier mal der Code, wir ihr sehen könnt habe ich mir schon einige Ausgaben für den Serial Monitor mit Zeilennummer reingeschrieben um besser zu sehen, wo er gerade im Code ist und was passieren sollte.
Generell ist der Code gerade etwas verbastelt und nicht Final

//192.168.168.54

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266Ping.h>

HTTPClient sender;
WiFiClient wifiClient;

#define taster 14
#define LedBlau 5
#define LedGruen 2
#define LedRot 4

const IPAddress remote_ip(192, 168, 168, 122);
const IPAddress remote_ipServer(192, 168, 168, 36);
const char* ssid = "****";
const char* password = "*********************";

int tasterstatus=0;
bool rechnerOnline = Ping.ping(remote_ip, 1);
bool serverOnline = Ping.ping(remote_ipServer, 1);
bool tasterPushed = false;

void ICACHE_RAM_ATTR pcSteuern(); //Interrupt bei Tasterbetätigung
void hochfahren();
void runterfahren();

void setup() {
  Serial.begin(115200);

  pinMode(LedRot, OUTPUT);
  pinMode(LedGruen, OUTPUT);
  pinMode(LedBlau, OUTPUT);
  pinMode(taster, INPUT);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LedBlau, HIGH);
    delay(500);
    digitalWrite(LedBlau, LOW);
    delay(500);
  }
  Serial.println("43 - WIFI Verbunden");

  attachInterrupt (digitalPinToInterrupt(taster), pcSteuern, HIGH);
}

void loop(){ 
  Serial.println("49 - LOOP gestartet");
  while (WiFi.status() == WL_CONNECTED){
    serverOnline = Ping.ping(remote_ipServer, 1);
    Serial.print("54 - Server Ping Ergebnis: ");
    Serial.println(serverOnline);
    Serial.println("56 - ping wird ausgefuehrt");
    rechnerOnline = Ping.ping(remote_ip, 1);
    Serial.print("58 - PC Ping Ergebins: ");
    Serial.println(rechnerOnline);
    if (rechnerOnline == true){
      Serial.println("61 - Rechner ist online");
      digitalWrite(LedRot, HIGH);
      digitalWrite(LedBlau, LOW);
      digitalWrite(LedGruen, HIGH);
    } else {
      Serial.println("66 - Rechner ist offline");
      digitalWrite(LedRot, LOW);
      digitalWrite(LedBlau, LOW);
      digitalWrite(LedGruen, HIGH);
    }
   //delay(1000); 
  }
  while (WiFi.status() != WL_CONNECTED){
    Serial.println("74 - NEUVERBINDUNG WiFi"); 
    digitalWrite(LedBlau, HIGH);
    digitalWrite(LedGruen, LOW);
    digitalWrite(LedRot, LOW);    
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      Serial.println("80 - Verbinde Wifi");
      digitalWrite(LedBlau, HIGH);
      delay(500);
      digitalWrite(LedBlau, LOW);
      delay(500);
      }
      Serial.println("86 - Wifi verbunden");
  } 
}

void pcSteuern(){
  Serial.println("91 - Taster gedrückt");
  serverOnline = Ping.ping(remote_ipServer, 1);
  Serial.print("93 - Server Ping Ergebnis: ");
  Serial.println(serverOnline);
  Serial.println("95 - ping wird ausgefuehrt");
  bool pcOnline = Ping.ping(remote_ip, 1);
  Serial.print("97 - PC Ping Ergebnis: ");
  Serial.println(pcOnline);
  digitalWrite(LedBlau, HIGH);
  digitalWrite(LedGruen, LOW);
  digitalWrite(LedRot, LOW);
  if (pcOnline == true){
    Serial.println("103 - starte runterfahren");
    runterfahren();
  } else {
    Serial.println("106 - starte hochfahren");
    hochfahren();
  }
}

void hochfahren(){
    Serial.println("112 - Rechner START");
    sender.begin(wifiClient, "http://192.168.168.36/wol/konfwol.php");
    int httpCode = sender.GET();
    Serial.print("115 - ");
    Serial.println(httpCode);
    sender.end();
}

void runterfahren(){
    Serial.println("121 - Rechner SHUTDOWN");
    sender.begin(wifiClient, "http://192.168.168.122:5001/shutdown");
    int httpCode = sender.GET();
    Serial.print("124 - ");
    Serial.println(httpCode);
    sender.end();
}

Interrupt-Routinen müssen sehr schnell/kurz sein. So etwas Langsames wie Netzwerkverbindung und Serial.print gehört da nicht rein.
Für Tastenerkennung brauchst Du keinen Interrupt. Nutze die funktionierende Lösung im loop.

Gruß Tommy

Rufe doch einfach per Tastendruck ein Script (oder sende eine Nachricht per BC oder UPD) auf dem lokalen Webserver auf, das entscheidet dann (per Ping o.ä.) ob der Rechner starten soll oder heruntergefahren wird.

Die Option ist abgewählt, weil man immer erst beim entsprechenden Punkt im Schleifendurchlauf den Taster abgreift. Sprich man muss immer entsprechend lange gedrückt halten.

Da der Webseitenaufruf nicht funktioniert geht das auch nicht.

Deine while im loop versauen Dir den ganzen Zeitablauf. Die haben da auch nichts zu suchen. Im loop Taster abfragen, entscheiden ob etwas getan werden soll (Taster betätigt). Ende.

Gruß Tommy

Ich hatte die beiden while Scheifen so eingebaut für den Fall, dass die WiFi Verbindung verloren geht.
Im Grunde fängt sich der W1 ja in der ersten Schleife so lange WiFi verbunden ist, in die zweite springt er ja nur wenn WiFi nicht verbunden ist.
Und die Idee mit dem Interupt ist gekommen, weil es nicht zuverlässig war, wenn ich alles im Loop hatte und dort auf Tastendruck reagiert habe.
Also einmal das Problem, dass erst beim entsprechenden Abfragen des Tastereingangs geschaltet wurde und zum anderen war es nicht verlässlich.
Wobei, jetzt wo ich hier schreibe fällt mir noch eine Struktur ein mit der ich es mal testen könnte.

Das ist ein Irrtum. Er bleibt in der Schleife gefangen, solange die Verbindung steht.
Deswegen brauchst Du auch den Interrupt am Taster. Interrupts an von Hand bedienten Eingabegeräten sind nur dafür da, eine schlechte Programmplanung zu kaschieren.

Ich empfehle Dir, Deinen Sketch nochmal grundlegend zu überdenken.
Hast Du einen PullDown-Widerstand am Taster?

Gruß Tommy

Naja....
Etwas zu pauschal.
(Aber, ich weiß was du meinst)

Ja, Pulldown am Taster ist vorhanden.
Auf die Idee mit dem Interupt bin ich halt gekommen, weil man damit halt außerhalb der Routine den eigentlichen Event Zeitunabhängig starten kann.

Aber ja, ich überlege gerade mit mills() nur alle 5sek oder 10sek nen Ping zu machen um zu schauen ob der Rechner online ist und damit dann die LEDs zu schalten damit man am Taster sieht ob der Rechner an ist oder nicht und ansonsten "normal" im loop den Taster abzufragen und dann auf Tasterbetätigung hin zu prüfen was zu tun ist.

Damit werde ich mich aber erst übernächste Woche beschäftigen, weil gleich ist Wochenende und kommende Woche bin ich nicht im Büro.

Aber danke soweit für eure Hilfe hier und die Denkanstöße.

Falsch. Interrupts sind nicht für Multitasking.

Falsch ist die Annahme, dass ich hier Multitasking machen möchte.
Es geht darum einen Event zeitunabhängig zu triggern.
Die Routine aus dem loop() brauche ich in dem Augenblick nicht.

Wie wäre es, den Loop zeitunabhängig zu durchlaufen? Dann könnte man im Loop zeitunabhängig auf Taster reagieren.

2 Dinge unabhängig voneinander erledigen zu wollen, ist Multitasking.
Vielleicht eine ganz primitive Form. Aber Multitasking.
Der erste Schritt in genau diese Richtung.

Wie meinst Du dass den Loop zeitunabhängig laufen zu lassen?
Der loop wird immer von oben nach unten abgearbeitet und startet oben wieder. Also wird der Taster immer nur dann abgefragt wenn die entsprechende Zeile kommt.

Multitasking bedeutet zwei (oder mehr) Dinge Zeitgleich zu tun.
Ich wollte Aufgabe A so lange kontinuierlich machen bis über einen Taster Aufgabe B erledigt wird. In dem Moment müssen nicht A und B erledigt werden.
Aber ist jetzt auch egal, da ich vom Interrupt weg bin für diese Aufgabe.

Du möchtest das dein Programm rechtzeitig auf deinen Tastendruck reagiert. Rechtzeitig würde in diesem Fall bedeuten, das du als Benutzer keine Verzögerung mitbekommst. Du als Mensch würdest eine Verzögerung von unter 0,1s nicht mitbekommen. Es würde also reichen, wenn dein Loop unter 0,1s durchlaufen wird. Wenn man blockadefrei programmiert, sollte dies leicht zu unterbieten sein. Das meinte ich mit zeitunabhängig, also blockadefrei, kein Teil was den Loop zeitlich ausbremst.

Sieh es so:
Du benötigst auch eine dritte Aufgabe C: "Taster abfragen"
Du machst also Aufgabe A und Aufgabe C "gleichzeichtig", damit du Aufgabe B starten kann.

Übrigens wenn ich deine Beschreibung richtig verstanden habe, dann brauchst du in deinem Loop nur eine einzige Aufgabe: Den Taster prüfen.
Wird der Taster gedrückt prüfst du ob der PC läuft
.. Läuft der PC - schaltest ihn ab
.. Ist der PC abgeschaltet - schaltest ihn ein.

Da das einschalten/ausschalten wohl länger dauern wird, würde sich eine State Machine anbieten.
Nur so als Idee:

Naja, ich muss zwischendurch immer wieder prüfen, ob der Rechner nicht schon an ist und dann entsprechend die LEDs vom Taster leuchten lassen.
Wir haben noch ein paar Mitarbeiter die keinen festen Arbeitsplatz in der Firma haben und loggen sich dann per VPN ein und arbeiten dann mit dem Rechner.
Aber wie gesagt, das ganze wird ah nochmal überarbeitet ohne Interupt.

Ja, ich muss das Programm sowas abspecken, dass man keine Verzögerung wahrnimmt.