Steuerung einer Actioncam (Sjcam SJ4000) mittels mehrerer Taster am Quad (ATV)

/*    
      *** Fernbedienung einer Action-Kamera (SJ4000 und Clones) via 3 Taster 1 Videoaufnahmekontroll-LED und OTA ***

      SJ4000.ino
      
          Code compatible with ESP8266 Boards Version 3.0.0 or above 
          (see in Tools > Boards > Boards Manager > Generic ESP8266 Module)

      Dank an Funduino GmbH - Ralf Snieders https://funduino.de/nr-5-taster-am-arduino
      und an die vielen aktiven User (Berater, Rater, Probierer etc.) aus dem https://forum.arduino.cc/
      Thx to Nutchanon Wetchasit @ https://sj4000programming.sourceforge.net/0.7.0/html/book.html
*/
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ArduinoOTA.h>
#include "zugangsdaten.h"

#define DEBUGGING  // Auskommentieren, wenn keine serielle Ausgabe erwünscht wird

#ifdef DEBUGGING
#define debugBegin(...) Serial.begin(__VA_ARGS__)
#define debugPrint(...) Serial.print(__VA_ARGS__)
#define debugPrintln(...) Serial.println(__VA_ARGS__)
#else
#define debugBegin(...)
#define debugPrint(...)
#define debugPrintln(...)
#endif

WiFiClient client;
HTTPClient http;
ESP8266WiFiMulti wifiMulti;

String ServerName1 = "http://192.168.1.254/?custom=1&cmd=";
String ServerName2 = "http://192.168.100.1/?custom=1&cmd=";
String ServerName3 = "http://192.168.0.1";
String ServerName  = "http://";

// Pinbelegung
const int LEDVideo = 14;  //Das Wort „LEDVideo“ steht jetzt für den Pin D5 PGIO 14.
const int TastViAn = 12;  //Das Wort „TastViAn“ steht jetzt für den Pin D6 GPIO 12.
bool TastStatus1 = 0;     //Das Wort „TastStatus1“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

const int TastViAus = 13;  //Das Wort „TastViAus“ steht jetzt für den Pin D7 GPIO 13.
bool TastStatus2 = 0;      //Das Wort „TastStatus2“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

const int TastFoto = 15;  //Das Wort „TastFoto“ steht jetzt für den Pin D8 GPIO 15.
bool TastStatus3 = 0;     //Das Wort „TastStatus3“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.


// GET Übergaben
const char* VideoFunc = "3001&par=1";  //http://192.168.1.254/?custom=1&cmd=3001&par=1	 	VIDEOMODUS
const char* VideoAn = "2001&par=1";    //http://192.168.1.254/?custom=1&cmd=2001&par=1		Video starten
const char* VideoAus = "2001&par=0";   //http://192.168.1.254/?custom=1&cmd=2001&par=0		Video stoppen

const char* FotoFunc = "3001&par=0";  //http://192.168.1.254/?custom=1&cmd=3001&par=0		FOTOMODUS
const char* FotoAn = "1001";          //http://192.168.1.254/?custom=1&cmd=1001		    	Foto machen

char buf[160] = { "\0" };

// WLAN Verbindungs-Timeout pro AP. Erhöhen, wenn Zeit zum verbinden länger dauert.
const uint32_t connectTimeoutMs = 9000;



void setup() {
  Serial.begin(115200);
  delay(500);
  pinMode(LEDVideo, OUTPUT);  //Der Pin mit der LED (D5) ist jetzt ein Ausgang.
  pinMode(TastViAn, INPUT);   //Der Pin mit dem Taster (D6) ist jetzt ein Eingang.
  pinMode(TastViAus, INPUT);  //Der Pin mit dem Taster (D7) ist jetzt ein Eingang.
  pinMode(TastFoto, INPUT);   //Der Pin mit dem Taster (D8) ist jetzt ein Eingang.
   
  WiFi.mode(WIFI_STA);
  
  // Speichern der WLAN-Konfiguration im Flashspeicher - optional
  WiFi.persistent(false);

  Serial.begin(115200);
  Serial.println("\nESP8266 Suche nach Kamera- oder OTA-Verbindung");

 
  // WLAN Verbindungsdaten in zugagangsdaten.h eingeben/erweitern
  wifiMulti.addAP(SSID_Cam1, PASS_Cam1);  //SJ4000
  wifiMulti.addAP(SSID_Cam2, PASS_Cam2);  //Beatfoxx
  wifiMulti.addAP(SSID_OTA1, PASS_OTA1);  //OTA
  // Mehr Verbindungen sind möglich


}  //Mit dieser letzten Klammer wird void setup geschlossen.




void WLANScan() {
  // WLAN-Verbindung herstellen und Variable ServerName festlegen
  if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) {
    Serial.print("WiFi connected: ");
    Serial.print(WiFi.SSID());
    if (WiFi.SSID() == SSID_OTA1) {
      Serial.println(F("\nVerbunden mit OTA-Server, warte auf Updates"));       //OTA
      Serial.println(WiFi.localIP());
      ArduinoOTA.begin();
    } else {
      if (WiFi.SSID() == SSID_Cam2) {
        Serial.println(F("\nVerbunden mit Cam2"));          //Beatfoxx
        ServerName.replace(ServerName, ServerName2);
        Serial.println(ServerName);
        Serial.println(WiFi.localIP());
      } else {
        if (WiFi.SSID() == SSID_Cam1) {
          Serial.println(F("\nVerbunden mit Cam1"));        //SJ4000
          ServerName.replace(ServerName, ServerName1);
          Serial.println(ServerName);
          Serial.println(WiFi.localIP());
        }
      }
    }

  } else {
    Serial.println("WLAN nicht verbunden!");
  }

  delay(1000);
}




void VideoAN_F() {                      //Mit dieser Klammer wird die Funktion VideoAn_F geöffnet.
  TastStatus1 = digitalRead(TastViAn);  //Hier wird der Pin D6 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus1“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus1 == HIGH)              //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                     //Programmabschnitt des IF-Befehls öffnen.
    digitalWrite(LEDVideo, HIGH);       //dann soll die LED leuchten

    /*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoFunc);

    Serial.println(buf);
*/
    String VideoUmschalter = ServerName+VideoFunc;

    // GET Übergaben
    //http.begin(client, buf); 
    http.begin(client, VideoUmschalter);

    {
      delay(300);

      Serial.println("Ich schalte auf Videofunktion um...   ");
    }

    // HTTP GET request senden
    int httpResponseCode5 = http.GET();

    if (httpResponseCode5 > 0) {

      Serial.print("Videofunktion an!   ");
      //Serial.println(httpResponseCode5);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode5);
    }

/*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAn);

    Serial.println(buf);
*/

    // GET Übergaben
    //http.begin(client, buf); 
    String VideoAnschalter = ServerName+VideoAn;
    http.begin(client, VideoAnschalter);

    {
      delay(300);

      Serial.println("Aufnahme wird gestartet...   ");
    }
    // HTTP GET request senden
    int httpResponseCode6 = http.GET();

    if (httpResponseCode6 > 0) {

      Serial.print("Aufnahme läuft!   ");
      //Serial.println(httpResponseCode6);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode6);
    }

   
    http.end();

  }  //Programmabschnitt des IF-Befehls schließen.

}  //Mit dieser letzten Klammer wird die Funktion VideoAn_F geschlossen.




void VideoAUS_F() {                      //Mit dieser Klammer wird die Funktion VideoAus_F geöffnet.
  TastStatus2 = digitalRead(TastViAus);  //Hier wird der Pin D7 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus2“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus2 == HIGH)               //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                      //Programmabschnitt des IF-Befehls öffnen.
    digitalWrite(LEDVideo, LOW);         //dann soll die LED ausgehen



   /* snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoFunc);


    Serial.println(buf);
   */

    // GET Übergaben
    //http.begin(client, buf); 
    String VideoUmschalter = ServerName+VideoFunc;
    http.begin(client, VideoUmschalter);

    {
      delay(300);

      Serial.println("Ich schalte auf Videofunktion um...");
    }

    // HTTP GET request senden
    int httpResponseCode3 = http.GET();

    if (httpResponseCode3 > 0) {

      Serial.print("Videofunktion an!   ");
      //Serial.println(httpResponseCode3);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode3);
    }
/*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAus);

    Serial.println(buf);
*/

    // GET Übergaben
    //http.begin(client, buf);
    String VideoAusschalter = ServerName+VideoAus;
    http.begin(client, VideoAusschalter);

    {
      delay(300);

      Serial.println("Aufnahme wird beendet...   ");
    }
    // HTTP GET request senden
    int httpResponseCode4 = http.GET();

    if (httpResponseCode4 > 0) {

      Serial.print("Aufnahme beendet!   ");
      //Serial.println(httpResponseCode4);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode4);
    }

    // Free resources
    http.end();
  }
}  //Mit dieser letzten Klammer wird die Funktion VideoAus_F geschlossen.

                                                              


void Foto_F() {                         //Mit dieser Klammer wird die Funktion Foto_F geöffnet.
  TastStatus3 = digitalRead(TastFoto);  //Hier wird der Pin D8 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus3“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus3 == HIGH)              //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                     //Programmabschnitt des IF-Befehls öffnen.

    digitalWrite(LEDVideo, LOW);  //dann soll die LED ausgehen
                                  // GET Übergaben

/*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAus);

    Serial.println(buf);
*/

    // GET Übergaben
    //http.begin(client, buf);  // zur Sicherheit falls Videoaufnahme läuft
    String VideoAusschalter = ServerName+VideoAus;
    http.begin(client, VideoAusschalter);

    {
      delay(300);

      Serial.println("Ich stoppe zur Sicherheit Videoaufnahme...   ");
    }

    // HTTP GET request senden
    int httpResponseCode0 = http.GET();

    if (httpResponseCode0 > 0) {

      Serial.print("Videoaufnahme beendet!   ");
      //Serial.println(httpResponseCode0);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode0);
    }

/*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, FotoFunc);

    Serial.println(buf);
*/

    // GET Übergaben
    //http.begin(client, buf);
    String FotoUmschalter = ServerName+FotoFunc;
    http.begin(client, FotoUmschalter);

    {
      delay(300);

      Serial.println("Ich schalte auf Fotofunktion um...   ");
    }
    // HTTP GET request senden
    int httpResponseCode1 = http.GET();

    if (httpResponseCode1 > 0) {

      Serial.print("Fotofunktion an!   ");
      //Serial.println(httpResponseCode1);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode1);
    }
/*
    snprintf(buf, sizeof(buf), "%s%s", ServerName, FotoAn);

    Serial.println(buf);
*/

    // GET Übergaben
    //http.begin(client, buf);
    String FotoAnschalter = ServerName+FotoAn;
    http.begin(client, FotoAnschalter);

    {
      delay(100);

      Serial.println("Ich mache ein Foto...   ");
    }

    // HTTP GET request senden
    int httpResponseCode2 = http.GET();

    if (httpResponseCode2 > 0) {

      Serial.print("Foto aufgenommen!    ");
      //Serial.println(httpResponseCode2);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode2);
    }
    // Free resources
    http.end();

  }  //Programmabschnitt des IF-Befehls schließen.
}  //Mit dieser letzten Klammer wird die Funktion Foto_F geschlossen.




void loop() {
  WLANScan();
  VideoAN_F();
  VideoAUS_F();
  Foto_F();
   if (WiFi.SSID() == SSID_OTA1) ArduinoOTA.handle();   // OTA abhandeln
}

Nachdem mich der Forumbot so nett angeschrieben, versucht hatte mich zu ermuntern doch mal meinen ersten Beitrag zu verfassen und ich mich auch mal bedanken wollte, kommt hier nun mein erster Beitrag.

Zu meinem Projekt:
Nachdem die damals beigefügte Fernbedienung meiner SJ 4000 ihren Geist aufgegeben hatte und es scheinbar keinen Ersatz zu geben schien, entschloss ich mich etwas mit einem ESP in Angriff zu nehmen. Da ich wusste das die Kamera auch über den Browser via http get request zu steuern ist, habe ich mich hier und anderswo belesen.

Die Idee war die Kamera, welche sich auf meinem Helm befindet mittels Taster an meinem Quad und einer WLAN-Verbindung zu steuern. (Video starten/beenden, Foto aufnehmen).

Zu mir, ich habe eigentlich überhaupt keine Ahnung von Programmierung, wo ich "fortgeschrittene" Anfängerkenntnisse ist im php-scripten, das half mir aber nur insoweit, das mir die Klammerstruktur bekannt vorkam, ich also wusste bzw. annahm, wo welche Klammer geöffnet oder geschlossen werden und wo welcher Codeschnipsel hingehören musste. Meine Vorgehensweise ist im folgendermaßen, ich suche etwas, was im Kern annähernd zu meinem Projekt passt, baue es auf, teste es und funktioniert es, lese, lese und nochmals lese und erweitere es Stück für Stück und versuche zu begreifen woran es scheitert... (was sehr oft war)
Daher weiss ich auch garnicht mehr bei wem ich mich hier alles bdeanken sollte, weil ich meinen Codeschnipsel, meist aus den unterschiedlichsten Projekten "zusammengklaut", modifiziert und eingebaut wurden. Dennoch möchte ich ein großes Danke sagen, da mein Projekt ohne all den aktiven und hilfsbereiten Mitgliedern hier nicht machbar gewesen wäre.

Verbaut wurde:

  1. 1 x D1 Mini NodeMCU mit ESP8266
  2. 3 x Taster mit je 1 x 1KOhm Widerstand geerdet (Pulldown)
  3. 1 x Kontroll LED
  4. 1x 12 auf 5 V Spannungswandler als Spannungsquelle

Vielleicht sucht ja jemand genau sowas und kann es sich nachbauen, es funktioniert und kann auch angepasst werden. Für mich erfüllt es auch soweit meine Bedürfnisse, eventuell setze ich mich auch nochmals davor und werde noch ein paar Stunden damit verbringen, zu versuchen die LED blinken zu lassen, wenn die WLAN-Verbindung zur Kamera verloren geht.

Wie gesagt, wenn jemand nen Codeschnipsel von sich erkennt -- Danke.
Aja vielleicht eine Bitte noch an alle aktiven Experten, vielleicht hat ja der ein oder andere Zeit mal drüber zu schauen und mir eventuell nen Tip geben, falls da noch etwas einzukürzen oder zu verbessern gebe?!

MfG André

PS: Ich werd mal die Tage ein zwei Bilder machen, wie ichs verbaut habe.

1 Like

Dann kannst es an die geilen Projekte ranhängen - mit gegenseitigen Querverweis :wink:
Schon jetzt Danke für's teilen.

Das kommt leider viel zu selten vor, daher Dank fürs Danke :smiley:

Schutzhelm auf, los geht's!

int LEDVideo = 14;    //Das Wort „LEDVideo“ steht jetzt für den Wert D5.
int TastViAn = 12;    //Das Wort „TastViAn“ steht jetzt für den Wert D6.
int TastViAus = 13;   //Das Wort „TastViAus“ steht jetzt für den Wert D7.
int TastFoto = 15;    //Das Wort „TastFoto“ steht jetzt für den Wert D8.

Der Kommentar paßt nicht zum Wert (14 != D5) und es handelt sich um Konstanten. Mit const könntest Du Variablenspeicher sparen.

int TastStatus1 = 0;  //Das Wort „TastStatus1“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.
int TastStatus2 = 0;  //Das Wort „TastStatus2“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.
int TastStatus3 = 0;  //Das Wort „TastStatus3“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

Du verwendest diese Variablen als bool, dann solltest auch diesen Typ wählen.

String VideoFunc = serverName + "3001&par=1";    //http://192.168.1.254/?custom=1&cmd=3001&par=1	 	VIDEOMODUS
String VideoAn = serverName + "2001&par=1";      //http://192.168.1.254/?custom=1&cmd=2001&par=1		Video starten
String VideoAus = serverName + "2001&par=0";     //http://192.168.1.254/?custom=1&cmd=2001&par=0		Video stoppen

String FotoFunc = serverName + "3001&par=0";     //http://192.168.1.254/?custom=1&cmd=3001&par=0		FOTOMODUS
String FotoAn = serverName + "1001";             //http://192.168.1.254/?custom=1&cmd=1001		    	Foto machen

Erst baust Du Dir String-Objekte zusammen, um sie dann durch .c_str als C-Zeichenkette zu verwenden. Das ist nicht falsch, könnte man aber nochmal nachdenken.

Serial...

Serielle Ausgabe sind zur Fehlersuche gut geeignet, im produktiven Programm aber nur Zeitfresser. Durch bedingte Kompilierung kann man die ausblenden.

void VideoAN() {                        //Mit dieser Klammer wird der Loop-Teil geöffnet.
...
      http.begin(client, VideoAn.c_str());

Der Kommentar stimmt auch noch an anderen Stellen nicht. Funktion und Variable gleich zu benennen, halte ich für ungeschickt.

}                                     //Programmabschnitt des IF-Befehls schließen.

}  //Mit dieser letzten Klammer wird der Loop-Teil geschlossen.

Im Editor der IDE <Strg+T> formatiert die Einrückungen, was das Lesen erleichtert.

Du hast es so gewollt :innocent:

1 Like

So schlimm fand ich Deine Antwort eigntlich erst garnicht, hat mich aber einiges an Stunden lesen gekostet und so recht bin ich eigentlich soweit wie zuvor, wahrscheinlich aufgrund der nichtvorhandenen Programmierkenntnisse :joy: :woozy_face: :woozy_face:

Dachte damit wird mehr oder weniger die Variable für den dazugehörigen PIN festgelegt PIN D5 auf GPIO 14?! Habe mir const angeschaut und bissl rumprobiert, aber gibt dann immer Probleme irgendwo, die ich nicht nachvollziehen kann :rofl: :rofl:

Hab mir auch die Arduino-Referenz zu bool durchgelesen, also ich glaub das würde ich hinbekommen, das erschließt sich mir. Ist es besser als das was ich hier zusammengeraubt und zusammengeschustert habe?

Wieder die bei mir vorhandenen Kenntnisse, habe 0 Ahnung was Du damit meinst?

Das habe ich mal probiert zu beheben, aber ich weiß nicht was ich falsch mache. Egal ob ich #define DEBUG aus oder nicht auskommentiere, mein serieller Monitor spuckt weiterhin alles aus?!

Bin nochmal alle Kommentare durchgegangen und das sollte soweit behoben sein, kommt halt vom Kopieren, wieder runterkopieren usw. :rofl: Funktionen und die Variablen haben jetzt unterschiedliche Namen.

Bei mir, ganz ehrlich, passiert nix in der Arduino IDE, wenn ich STRG und T drücke??

Danke, ich editiere mal den Erstbeitrag und lade den veränderten Code hoch, vielleicht hast du ja nochmal ein zwei Minuten und kannst mir sagen, was ich bei dem.

Gruß André

Manchmal bekomme ich wegen meiner "unfreundlichen" Art Prügel. Gut, wenn es mal nicht so ist :wink:

Wenn das so ist, dann stimmt der Kommentar.

Hier geht es darum, daß Du auch nach längerer Zeit noch Dein Programm verstehst. Also eher verständlicher.

Laß die String-Objekte erstmal unverändert, ist Kosmetik.

Du mußt alle Serial.print.. ändern, sonst wirkt der Zauber nicht.

Versuche mal "Werkzeuge/Automatische Formatierung".

Wo hast Du eine "unfreundliche" Art? Egal ob mit oder ohne ""

Gruß Tommy

Ich möchte die Antwort gerne offen lassen, um dieses Thema nicht zu stören. Es war nur eine Randbemerkung.

Wenn Du einen Apfelkuchen backen möchtest, kaufst Du keine Pflaumen.

Wenn Du einen C-String brauchst, baust Du kein C-Objekt zusammen wie beispielsweise bei http.begin(client, VideoFunc.c_str());

String VideoFunc = serverName + "3001&par=1";  // C-Objekt
const char * VideoAn = "2001&par=1";           // C-String

Auf Prozessoren mit wenig Speicher können C-Objekte zur Speicherfragmentierung führen, also zum Programmabsturz irgendwann zur Laufzeit.

Es geht auch mit C-Strings:


const char * serverName = "http://192.168.1.254/?custom=1&cmd=";

void setup() {
  Serial.begin(115200);
  delay(500);  // Mein ESP32 braucht eine Pause
  Serial.println("\nStart ...");
  VideoAN_F();
}

void loop() {}

void VideoAN_F() 
{
  const char * VideoAn = "2001&par=1";    //http://192.168.1.254/?custom=1&cmd=2001&par=1    Video starten
  char buf[60] = {"\0"};
  snprintf( buf, sizeof(buf), "%s%s", serverName, VideoAn );
  Serial.println(buf);
  // GET Übergaben
  //http.begin(client, buf);  // so dann bei Dir
}

Serieller Monitor:

Start ...
http://192.168.1.254/?custom=1&cmd=2001&par=1

Doku: snprintf

Bei UNO/Nano/ProMini und Mega2560 vermeide ich C-Objekte, beim ESP32 nutze ich sie. Mit dem ESP8266 habe ich keine Erfahrungen.

Wie war das mit der unfreundlichen Art??? Ich versuch mich mal am Wochenende da reinzufuchsen. Mit dem #definde Debug hab ich hinbekommen, habe die Seite die ich bsucht hatte wohl falsch verstanden. Danke Dir

Hallo agmue, nochmals vielen Dank für Deine Ratschläge, könntest Du nochmals rüberschauen und mir sagen, ob ich es jetzt richtig umgesetzt habe?
Laufen tut's auf jeden Fall.

Das freut mich, dann kann es sich ja nur um etwas Kosmetik handeln.

  1. Wäre nicht OTA sinnvoll?

  2. Die Pins hinter "Pinbelegung" gehören in Konstanten, denn dann benötigen sie keinen Variablenspeicher und können nicht versehendlich geändert werden.

  3. Variablen (TastStatusX), die boolean verwendet werden, sollten wegen der Deutlichkeit den Typ bool erhalten.

  4. Warum nicht INPUT_PULLUP, dann hat man auch bei abgefallenem Kabel einen definierten Zustand:

  pinMode(TastViAn, INPUT);   //Der Pin mit dem Taster (D6) ist jetzt ein Eingang.
  pinMode(TastViAus, INPUT);  //Der Pin mit dem Taster (D7) ist jetzt ein Eingang.
  pinMode(TastFoto, INPUT);   //Der Pin mit dem Taster (D8) ist jetzt ein Eingang.
  1. Hat das nicht funktioniert?
#define DEBUGGING  // Einkommentieren für die Serielle Ausgabe
#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.println(__VA_ARGS__)
#define DEBUG_F(...) Serial.printf(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_F(...)
#endif
...
  DEBUG_B(115200);
  DEBUG_F("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n\n", __FILE__, __TIMESTAMP__, ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10);

Ja vielleicht aber hab mir da nen Beispieltext angesehen, das einzufriemeln, da brauch ich Jahre^^

Hoffe das ich das jetzt zu Deiner und meiner Zufriedenheit hinbekommen habe?!

Hoffe hier jetzt auch?!

Hab mich belesen, was das bedeutet/bewirkt, mh ja hätte ich das gewusst hätte ich mir wohl ein paar Sachen an Löterein sparen können und den internen Pull-Up-Widerstand nutzen können... (richtig verstanden?) Bleibt aber nun so! :smiley:

Nach 2 Tagen rumprobieren, weiterer Beispielsketche und einigen Wutausbrüchen hab ich nun auch das hinbekommen, danke, konnte ich wieder einiges an #ifdef's und #endif's herausnehmen und es wirkt wieder kompakter und übersichtlicher und erfüllt seinen Zweck :wink:

Hättest Du für mich eventuell noch ne Idee, wie ich es hinbekommen könnte, das ich beide Kameras nutzen kann? Hatte mir MultiWiFi angeschaut aber irgenndwie steig ich da dann nicht durch, wie ich ne Abfrage mache, mit welchem Wlan-Netz er verbunden ist und dann entweder die const char * servername 1 bzw 2 nimmt. Hintergrund ist, dass ich nie beide Kameras im Einsatz habe und jene bei der ich das WLAN einschalte, mit der verbindet er sich ja auch, das funzt. Da aber beide Kameras unterschiedlich IP-Adressen haben funzt dann halt nur bei einer ....
Bin grad selbst noch auf eine Idee gekommen, man warum nicht gleich...
Sag mal ist es möglich, wenn ich MultiWiFi einsetze, dann ne Abfrage auf
WiFi.gatewayIP() und sage wenn WiFi.gatewayIP() = ... dann nehme servername.. und wenn nicht dann...? Bestimmt irgendwie... ich versuch mein Glück und meld mich nochmal :rofl: :rofl:

Alles, was ich schreibe, bezieht sich auf den ESP32, Abweichungen zum ESP8266 sind möglich.

  1. OTA in zwei Minuten:
#include <ArduinoOTA.h>
...
void setup() {
...
  ArduinoOTA.begin();
}

void loop() {
  ArduinoOTA.handle();
...
}
  1. bis 5. OK

:slightly_smiling_face:

Dann brauchst Du kein MultiWiFi oder sowas. Du versuchst Dich mit Cam1 zu verbinden. Wenn das klappt, dann gut, wenn nicht versuchst Du Dich mit Cam2 zu verbinden.

Alternativ könntest Du auch nach den in der Umgebung vorhandenen Access Points suchen und Dir dann Cam1 oder Cam2 herauspicken.

Da müsste ich ja noch nen 3. WLAN abfragen, irgendwie bekomme ich das schon mit den beiden Kameras nicht hin. Bzw ich bekomm es mit WiFiMulti hin, hab aber absolut kein Plan wie ich es dann hinbekomme die Konstante "Servername" dann zu ändern. Dachte ich kann nach der Verbindung die SSID abfragen und dann ne if Anweisung setzen wenn ssid=... dann const char* servername =... Aber ich bin zu blöde :smiley:

Autsch, die Kameras können ja kein OTA :flushed:

Laß mich mal nachdenken :thinking:

Ist das Thema noch relevant?

Einen ESP32 konnte ich überreden, CAM_1 oder CAM_2 zu sein. Außerdem ist meine Fritz!Box als Router eingeschaltet. Priorität CAM_1 → CAM_2 → Router.

Der zweite Fernbedienungs-ESP32 versucht sich mit einem der drei möglichen Access Points zu verbinden, gibt bei Erfolg eine Meldung aus und läßt eine LED leuchten.

Bei einer Verbindung mit dem Router wird OTA ausgeführt.

#include "zugangsdaten.h"
#include <ArduinoOTA.h>  // Programm hochladen Over The Air, siehe IDE Werkzeuge/Port

const byte ledCam1 = 12;
const byte ledCam2 = 13;
const byte ledRouter = 14;

byte verbindung = 0;

void setup()
{
  Serial.begin(115200);
  delay(500);
  pinMode(ledCam1, OUTPUT);
  pinMode(ledCam2, OUTPUT);
  pinMode(ledRouter, OUTPUT);
  
  Serial.println(F("\nSuche Verbindung"));
  WiFi.mode(WIFI_STA);

  while (verbindung == 0)
  {
    WiFi.begin("CAM_1", "12345678");
    delay(1000);
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println(F("\nVerbunden mit CAM_1"));
      digitalWrite(ledCam1, HIGH);
      verbindung = 1;
    } else {
      WiFi.begin("CAM_2", "12345678");
      delay(1000);
      if (WiFi.status() == WL_CONNECTED) {
        Serial.println(F("\nVerbunden mit CAM_2"));
        digitalWrite(ledCam2, HIGH);
        verbindung = 2;
      } else {
        WiFi.begin(STA_SSID, STA_PASSWORD);
        delay(1000);
        if (WiFi.status() == WL_CONNECTED) {
          Serial.println(F("\nVerbunden mit Router"));
          digitalWrite(ledRouter, HIGH);
          verbindung = 255;
        } else {
          Serial.print('.');
        }
      }
    }
  }

  if (verbindung == 255) ArduinoOTA.begin(); // OTA starten
}

void loop()
{
  if (verbindung == 255) ArduinoOTA.handle();   // OTA abhandeln
}

Mit seriellem Monitor:

Suche Verbindung

Verbunden mit CAM_1

RESET

Suche Verbindung

Verbunden mit CAM_2

RESET

Suche Verbindung

Verbunden mit Router

Hilft Dir das?

Hi "unfreundlicher" agmue :grinning: ja Thema ist noch aktuell, hab nur Immo sehr wenig Zeit. Werde mich mal am Wochenende dran setzen und Dir dann ne Rückmeldung geben. Sorry das ich jetzt erst antworte.

Danke für die Zwischenmeldung, dann bis zum Wochenende :slightly_smiling_face:

/*    
      *** Steuerung einer Action-Kamera (SJ4000 und Clones) via 3 Taster ***

      SJ4000.ino
      
          Code compatible with ESP8266 Boards Version 3.0.0 or above 
          (see in Tools > Boards > Boards Manager > Generic ESP8266 Module)

      Dank an Funduino GmbH - Ralf Snieders https://funduino.de/nr-5-taster-am-arduino
      und an die vielen aktiven User (Berater, Rater, Probierer etc.) aus dem https://forum.arduino.cc/
      Thx to Nutchanon Wetchasit @ https://sj4000programming.sourceforge.net/0.7.0/html/book.html
*/
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>
#include "zugangsdaten.h"

#define DEBUGGING  // Auskommentieren, wenn keine serielle Ausgabe erwünscht wird

#ifdef DEBUGGING
#define debugBegin(...) Serial.begin(__VA_ARGS__)
#define debugPrint(...) Serial.print(__VA_ARGS__)
#define debugPrintln(...) Serial.println(__VA_ARGS__)
#else
#define debugBegin(...)
#define debugPrint(...)
#define debugPrintln(...)
#endif

// String.replace für ServerName nach erfolgreicher Verbindung
String ServerName = "http://";    
    // ServerName.replace('http://','http://192.168.1.254/?custom=1&cmd=');  //SJ4000
    // ServerName.replace('http://','http://192.168.100.1/?custom=1&cmd=');  //Beatfoxx
    // ServerName.replace('http://','http://192');                           //OTA


WiFiClient client;
HTTPClient http;


// Pinbelegung
const int LEDVideo = 14;  //Das Wort „LEDVideo“ steht jetzt für den Pin D5 PGIO 14.
const int TastViAn = 12;  //Das Wort „TastViAn“ steht jetzt für den Pin D6 GPIO 12.
bool TastStatus1 = 0;     //Das Wort „TastStatus1“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

const int TastViAus = 13;  //Das Wort „TastViAus“ steht jetzt für den Pin D7 GPIO 13.
bool TastStatus2 = 0;      //Das Wort „TastStatus2“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

const int TastFoto = 15;  //Das Wort „TastFoto“ steht jetzt für den Pin D8 GPIO 15.
bool TastStatus3 = 0;     //Das Wort „TastStatus3“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.


// GET Übergaben
const char* VideoFunc = "3001&par=1";  //http://192.168.1.254/?custom=1&cmd=3001&par=1	 	VIDEOMODUS
const char* VideoAn = "2001&par=1";    //http://192.168.1.254/?custom=1&cmd=2001&par=1		Video starten
const char* VideoAus = "2001&par=0";   //http://192.168.1.254/?custom=1&cmd=2001&par=0		Video stoppen

const char* FotoFunc = "3001&par=0";  //http://192.168.1.254/?custom=1&cmd=3001&par=0		FOTOMODUS
const char* FotoAn = "1001";          //http://192.168.1.254/?custom=1&cmd=1001		    	Foto machen

char buf[60] = { "\0" };




void setup() {
  debugBegin(115200);
  delay(500);

  pinMode(LEDVideo, OUTPUT);  //Der Pin mit der LED (D5) ist jetzt ein Ausgang.
  pinMode(TastViAn, INPUT);   //Der Pin mit dem Taster (D6) ist jetzt ein Eingang.
  pinMode(TastViAus, INPUT);  //Der Pin mit dem Taster (D7) ist jetzt ein Eingang.
  pinMode(TastFoto, INPUT);   //Der Pin mit dem Taster (D8) ist jetzt ein Eingang.

  Serial.println(F("\nSuche Verbindung"));
  WiFi.mode(WIFI_STA);

  while (ServerName == "http://")
  {
    WiFi.begin("Sportscam", "1234567890");                // ssid und Passwort Kamera 1 Wenn´s funzt in zugangsdaten.h übertragaen
    delay(1000);                                           // und in SSID_Cam1 & PASSW_Cam1 ändern
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println(F("\nVerbunden mit SJ4000"));
      ServerName.replace('http://','http://192.168.1.254/?custom=1&cmd=');  //SJ4000
    } else {
      WiFi.begin("Sport-cameras", "1234567890");          // ssid und Passwort Kamera 2 Wenn´s funzt noch in zugangsdaten.h übertragaen
      delay(1000);                                         // und in SSID_Cam2 & PASSW_Cam2 ändern
      if (WiFi.status() == WL_CONNECTED) {
        Serial.println(F("\nVerbunden mit Beatfoxx"));
        ServerName.replace('http://','http://192.168.100.1/?custom=1&cmd=');  //Beatfoxx
      } else {
        WiFi.begin(SSID_OTA, PASS_OTA);
        delay(1000);
        if (WiFi.status() == WL_CONNECTED) {
          Serial.println(F("\nVerbunden mit Router"));
          ServerName.replace('http://','http://192');                           //OTA
        } else {
          Serial.println(ServerName);
          Serial.print('.');
        }
      }
    }
  }
  if (ServerName == "http://192") ArduinoOTA.begin(); // OTA starten
}  //Mit dieser letzten Klammer wird void setup geschlossen.




void VideoAN_F() {                      //Mit dieser Klammer wird die Funktion VideoAn_F geöffnet.
  TastStatus1 = digitalRead(TastViAn);  //Hier wird der Pin D6 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus1“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus1 == HIGH)              //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                     //Programmabschnitt des IF-Befehls öffnen.
    digitalWrite(LEDVideo, HIGH);       //dann soll die LED leuchten


    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoFunc);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);

    {
      delay(300);

      Serial.println("Ich schalte auf Videofunktion um...   ");
    }

    // HTTP GET request senden
    int httpResponseCode5 = http.GET();

    if (httpResponseCode5 > 0) {

      Serial.print("Videofunktion an!   ");
      //Serial.println(httpResponseCode5);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode5);
    }


    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAn);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);
    {
      delay(300);

      Serial.println("Aufnahme wird gestartet...   ");
    }
    // HTTP GET request senden
    int httpResponseCode6 = http.GET();

    if (httpResponseCode6 > 0) {

      Serial.print("Aufnahme läuft!   ");
      //Serial.println(httpResponseCode6);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode6);
    }

    // Free resources
    http.end();

  }  //Programmabschnitt des IF-Befehls schließen.

}  //Mit dieser letzten Klammer wird die Funktion VideoAn_F geschlossen.




void VideoAUS_F() {                      //Mit dieser Klammer wird die Funktion VideoAus_F geöffnet.
  TastStatus2 = digitalRead(TastViAus);  //Hier wird der Pin D7 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus2“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus2 == HIGH)               //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                      //Programmabschnitt des IF-Befehls öffnen.
    digitalWrite(LEDVideo, LOW);         //dann soll die LED ausgehen



    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoFunc);


    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);
    {
      delay(300);

      Serial.println("Ich schalte auf Videofunktion um...");
    }

    // HTTP GET request senden
    int httpResponseCode3 = http.GET();

    if (httpResponseCode3 > 0) {

      Serial.print("Videofunktion an!   ");
      //Serial.println(httpResponseCode3);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode3);
    }

    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAus);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);
    {
      delay(300);

      Serial.println("Aufnahme wird beendet...   ");
    }
    // HTTP GET request senden
    int httpResponseCode4 = http.GET();

    if (httpResponseCode4 > 0) {

      Serial.print("Aufnahme beendet!   ");
      //Serial.println(httpResponseCode4);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode4);
    }

    // Free resources
    http.end();
  }
}  //Mit dieser letzten Klammer wird die Funktion VideoAus_F geschlossen.




void Foto_F() {                         //Mit dieser Klammer wird die Funktion Foto_F geöffnet.
  TastStatus3 = digitalRead(TastFoto);  //Hier wird der Pin D8 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „TastStatus3“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (TastStatus3 == HIGH)              //Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  {                                     //Programmabschnitt des IF-Befehls öffnen.

    digitalWrite(LEDVideo, LOW);  //dann soll die LED ausgehen
                                  // GET Übergaben

    snprintf(buf, sizeof(buf), "%s%s", ServerName, VideoAus);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);  // zur Sicherheit falls Videoaufnahme läuft
    {
      delay(300);

      Serial.println("Ich stoppe zur Sicherheit Videoaufnahme...   ");
    }

    // HTTP GET request senden
    int httpResponseCode0 = http.GET();

    if (httpResponseCode0 > 0) {

      Serial.print("Videoaufnahme beendet!   ");
      //Serial.println(httpResponseCode0);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode0);
    }


    snprintf(buf, sizeof(buf), "%s%s", ServerName, FotoFunc);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);
    {
      delay(300);

      Serial.println("Ich schalte auf Fotofunktion um...   ");
    }
    // HTTP GET request senden
    int httpResponseCode1 = http.GET();

    if (httpResponseCode1 > 0) {

      Serial.print("Fotofunktion an!   ");
      //Serial.println(httpResponseCode1);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode1);
    }

    snprintf(buf, sizeof(buf), "%s%s", ServerName, FotoAn);

    Serial.println(buf);


    // GET Übergaben
    http.begin(client
  , buf);
    {
      delay(100);

      Serial.println("Ich mache ein Foto...   ");
    }

    // HTTP GET request senden
    int httpResponseCode2 = http.GET();

    if (httpResponseCode2 > 0) {

      Serial.print("Foto aufgenommen!    ");
      //Serial.println(httpResponseCode2);

      String payload = http.getString();
      //Serial.println(payload);
    } else {

      Serial.print("Error code: ");
      Serial.println(httpResponseCode2);
    }
    // Free resources
    http.end();

  }  //Programmabschnitt des IF-Befehls schließen.
}  //Mit dieser letzten Klammer wird die Funktion Foto_F geschlossen.




void loop() {

  VideoAN_F();
  VideoAUS_F();
  Foto_F();
  if (ServerName == "http://192") ArduinoOTA.handle();   // OTA abhandeln
}

Hat mir keine Ruhe gelassen und jetzt bin ich richtig Asche, ohne was hinbekommen zu haben. Also weder Dein Sketch noch den hier für mich abgewandelten scheint es möglich zu sein mich mit der Kamera oder dem WLAN zu verbinden. Weiss auch nicht, ob das mit dem String ServerName überhaupt so funktionieren würde?? Kannst Du da nochmal schauen? Aja ich weiss man soll den Code nicht nochmal einfügen der Übersicht halber, aber ich bin so übermüdet, weiss nicht ob ich ich alles hier bei mir richtig abgespeichert habe. SO hab ichs wenigstens noch, lösch das hier dann bei klarem Vwerstand auch wieder:D

Mach weiter, wenn Du Zeit hast und ausgeschlafen bist :yawning_face:

Eigentlich halte ich WiFiMulti für Dich nicht sinnvoll, aber das Scannen der vorhandenen Netzwerke könnte Dir helfen: ESP32 WiFiMulti: Connect to the Strongest Wi-Fi Network (from a list of networks).

Im Beitrag ESP32 Useful Wi-Fi Library Functions (Arduino IDE) sehe ich nach WiFi.scanNetworks() einen Index bei WiFi.SSID(i). So könnte man eine passende Verbindung aussuchen.

Achja, ich schaue bei ESP32, sowas gibt es bestimmt auch für ESP8266.

Hi unfreundlicher agmue, wollte mich nochmal zu Wort melden und Dir den Stand der Dinge durchgeben, bin noch am Ball und probiere auch weiter, sorry für das NICHTGLEICHANTWORTEN, aber immo... :wink:

Warum nicht, damit habe ich es nämlich hinbekommen?? Im Prinzip ist ja nur eine Kamera an und das Heimentzwerk nehme ich nicht auf meine Quadtouren mit. bzw. kann ich ja nen AP aufm´m Läppi einrichten und so das OTA durchführen und stärke WLAN-Netze würde er ja nur verbinden, sofern sie in der Liste sind oder?
Mit WiFi.scanNetworks das hatte ich mir schon vor Deinem Beitrag angesehen, irgendwie hab ich das mit den if´s und elsen nicht hinbekommen, was wäre wenn dieses oder jenes Netzwerk auftaucht und ich dann... Sorry ich hab fast ne halbe Woche damit verbracht den Fehler zu finden warum das WiFiMulti bei mir nicht funzte, hatte dieses ConnectTimeout mit delay() verwechselt und es runtergenommen, weil ich mir dachte warum soll er denn da so lange... Lange Rede kurzer Sinn, die auf 500Ms runtergeschraubt ergeben SCHEI... :rofl:

Falls Du jetzt keine trifftigen Grund lieferst, würde ich Dir noch kurz mein Test- und Probiersketch vorstellen, muss natürlich noch in den eigentlichen eingefügt werden, aber ich denke und hoffe das bekomm ich hin. Aja falls Du irgendwas zwecks dem String ServerName sagen willst - ES IST MIR EGAL! :joy: Ich hab echt lange geschaut und gelesen. Ich bin mit meinem Latein da am Rande des Abgrunds und ... ES FUNZT SO und ich bin froh es überhaupt hinbekommen zu haben, das er mir diese VAriable halt anders ausgibt , je nachdem, ob er mit KAm1 oder 2 verbunden ist.

#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFi.h>
#include <zugangsdaten.h>

ESP8266WiFiMulti wifiMulti;

String ServerName1 = "http://192.168.1.254/?custom=1&cmd=";
String ServerName2 = "http://192.168.100.1/?custom=1&cmd=";
String ServerName3 = "http://192.168.0.1";
String ServerName  = "http://";

// WiFi connect timeout per AP. Increase when connecting takes longer.
const uint32_t connectTimeoutMs = 7000;

void setup() {
  // Don't save WiFi configuration in flash - optional
  WiFi.persistent(false);

  Serial.begin(115200);
  Serial.println("\nESP8266 Multi WiFi example");

  // Set WiFi to station mode
  WiFi.mode(WIFI_STA);

  // Register multi WiFi networks
  wifiMulti.addAP(SSID_Cam1, PASS_Cam1);  //SJ4000
  wifiMulti.addAP(SSID_Cam2, PASS_Cam2);  //Beatfoxx
  wifiMulti.addAP(SSID_OTA1, PASS_OTA1);  //OTA
  // More is possible
}

void WLANScan() {
  // Maintain WiFi connection
  if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) {
    Serial.print("WiFi connected: ");
    Serial.print(WiFi.SSID());
    if (WiFi.SSID() == SSID_OTA1) {
      Serial.println(F("\nVerbunden mit OTA-Server"));  //OTA
      ServerName.replace(ServerName, ServerName3);
      Serial.println(ServerName);
      Serial.println(WiFi.localIP());
    } else {
      if (WiFi.SSID() == SSID_Cam2) {
        Serial.println(F("\nVerbunden mit Cam2"));  //Beatfoxx
        ServerName.replace(ServerName, ServerName2);
        Serial.println(ServerName);
        Serial.println(WiFi.localIP());
      } else {
        if (WiFi.SSID() == SSID_Cam1) {
          Serial.println(F("\nVerbunden mit Cam1"));  //SJ4000
          ServerName.replace(ServerName, ServerName1);
          Serial.println(ServerName);
          Serial.println(WiFi.localIP());
        }
      }
    }

  } else {
    Serial.println("WLAN nicht verbunden!");
  }

  delay(1000);
}




void loop() {

  WLANScan();
}

Und die serielle Ausgabe, hatte die 1. Kamera an und nach dem Trennen mit meinem WLAN verbunden (OTA) Variable ServerName wird richtig ausgegeben.

WiFi connected: Sportscam
Verbunden mit SJ4000
http://192.168.1.254/?custom=1&cmd=
192.168.1.12
WiFi connected: zipfel
Verbunden mit Router
http://192.168.0.1
192.168.0.16 <

Werd´s die Tage mal ins eigentlichen Sketch einfügen und berichten. Wie gesagt würde mich freuen, wenn Du mir nochmals Anregungen bzw. Verbesserungsvorschläge geben könntest.

MfG

PS: Hab jetzt den Hauptsketch um geändert, musste das mit snprintf(buf, sizeof(buf).... rausnehmen sonst hat er da Kuadewelsch gemacht. Ist also, insofern du es nicht auseinandernimmst fertisch??????