AI Thinker ESP32 - CamerWebserver - WLAN reconnect

Hallo, kann es sein, dass es im Default-Sketch des CameraWebServer keinen Reconnect gibt, wenn die WLAN-Verbindung temporär ausfällt?

Ich hatte gestern mal den Router, an dem die ESP-Kameras eingebucht sind, neu gestartet. Dabei gingen alle Verbindungen der ESP32-Kameras verloren und wurden nicht wieder aufgebaut. Sprich, ich musste in den Keller und alle Kameras manuell neu starten.

Gibt es ggf. eine Möglichkeit, die Kameras selbst alle 24 Stunden neu zu starten oder – noch besser – einen WLAN-Reconnect zu programmieren?

Ja, die Möglichkeit gibt es.
Du kannst NTP nutzen und damit alle 24 Std. neu starten oder WLan reconnecten.

Ich bin in der Programmierung bezüglich des AI Thinker ESPBaord recht neu, wie mache ich das? Wo finde ich dazu Infos?

mfg

Evtl. findest du hier etwas darüber.

Das ist nicht so ganz, was ich suche. Ein WLAN reconnect wäre super. ChatGPT sagt mir Folgendes:

Du musst die WLAN-Reconnect-Funktion in deine Hauptdatei (.ino oder .cpp) einfügen, also direkt in den Code, den du gepostet hast.

:one: Funktion einfügen

Platziere diese Funktion irgendwo vor setup() oder am Ende der Datei, damit sie verfügbar ist:

void checkWiFiConnection() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WLAN-Verbindung verloren! Versuche Reconnect...");
    WiFi.disconnect();
    WiFi.reconnect();
    unsigned long startAttemptTime = millis();
    while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
      delay(500);
      Serial.print(".");
    }
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("\nWLAN wiederhergestellt!");
    } else {
      Serial.println("\nWLAN-Reconnect fehlgeschlagen.");
    }
  }
}

:two: loop() anpassen

Suche in deinem Code nach der loop()-Funktion und ändere sie so:

void loop() {
  checkWiFiConnection();  // WLAN-Verbindung regelmäßig prüfen
  delay(10000);  // Alle 10 Sekunden prüfen
}

Datei:
Das gehört in die Hauptdatei deiner ESP32-CAM-Anwendung, also die .ino-Datei (zum Beispiel esp32_cam.ino).

Falls dein Code in mehreren .cpp-Dateien organisiert ist, sollte die Funktion in die Datei eingefügt werden, die loop() enthält.

Ich habe das Board aktuell im Keller schon verbaut. Ich Teste den Code, wenn ich anderen Boards ankommen. Jetzt wieder in Keller in die hinterste ecke kriechen und da herum testen .. dann lieber hier am Desktoprechner wo es nicht so staubig ist ;)

Das wird in der CAM-Software nicht funktionieren, da dann deine Website und weiteres nicht sauber läuft, weil blockiert. Da musst du millis() (siehe BlinkWithoutDelay in den Beispielen) einsetzen.

Ich könnte doch das Delay für den WLAN-Check rausnehmen, da die Funktion bzw. der Reconnect ja nur läuft, wenn das WLAN nicht verbunden ist. Ansonsten läuft die Funktion, wenn ich das richtig sehe, einfach nur durch.

Morgen kommen die anderen ESP Boards, ich werde einfach mal ein wenig herumprobieren. ChatGPT hat mir schon ein wenig geholfen, die default Werte für LED Helligkeit, Graustufenbilder, den H und V Flip zu konfigurieren.

Ja, das kannst du versuchen und sollte auch funktionieren.
Nur da kann man sehen, dass ChatGPT doch nicht so schlau ist.
Und beim selbst programmieren lernt man mehr.

Das stimmt, aber er sagt mir recht gut wo und wie den code ändern kann bzw. wo ich ansetzen könnte. Wenn man von der Syntax (noch) keine Ahnung hat, hilft das enorm. Bisher habe ich alles in der Bash gemacht und dort Programmieren gelernt. Gute Logik in Programmen ist essentiell, aber mit der Syntax von C++ (arduino = C++ ? ) hab ich noch so meine Schwierigkeiten.

Selbst nachdenken ersetzt KI noch lange nicht und das ist auch gut so :wink:

Sorry, aber das ist totaler Quatsch.
Bevor es die KI gab, haben es die Programmierer auch sehr gut ohne KI gelernt. Da muss man halt sein Gehirn anstrengen und lernen.

Du hast mich missverstanden. Selbst nachdenken und lernen nimmt KI einem nicht ab, das wollte ich damit sagen. KI hilft das Problem schneller zu lokalisieren und liefert ggf. direkt ein paar Ansätze. Nachdenken muss man dann schon noch selbst.

Ok, stimmt....sorry.
Da habe ich dich tatsächlich falsch verstanden.

du könntest im (sonstigen nicht blockiertem) loop mit einem

if (WiFi.status() != WL_CONNECTED)

prüfen ob deine Verbindung unterbrochen ist - und wenn - dann machst den reconnect.

Genau so hatte ich mir das gedacht :wink:

Die Boards mit den USB-Adaptern sind angekommen. Allerdings musste ich feststellen, dass es nicht der CH341-USB-Chip, sondern der CP210x-Chip ist. Ich dachte schon, das Board oder der USB-zu-Serial-Controller sei defekt, bis ich auf verschiedene Kombinationen aus Drücken der Reset- oder anderer Knöpfe am Board oder Controller stieß – die allerdings allesamt nicht funktionierten.

Nachdem ich mir dann aber die Info mit dem IOB-Bridge-Button noch einmal ins Gedächtnis rief – nämlich dass beim Upload des Sketches die Brücke geschlossen und beim Starten dann geöffnet werden muss –, kombinierte ich diese Erkenntnis mit den Informationen aus dem Forum/Netz folgendermaßen:

Wenn der Sketch-Upload beginnt, muss der IOB-Kontakt/Button geschlossen bzw. gedrückt und gehalten werden. Gleichzeitig muss nach dem Schließen/Drücken/Halten der IOB-Brücke am USB-zu-Serial-Controller das ESP32-Board durch Drücken des Reset-Buttons (nicht der Reset Button des USB-zu-Serial Adapters) neu gestartet werden. Sprich: IOB-Button drücken und halten, dann Reset-Button am ESP-Board drücken – und das Ganze, während die "Connecting"-Statusmeldung im IDE-Interface erscheint. Nach dem Upload muss das Board dann per Restbutton oder Trennen der Stromversorgung neu gestartet werden. Da muss man erst mal drauf kommen.

Mit dem CH341-USB-zu-Serial-Adapter war das nicht nötig. Die Sketches können ohne weiteres Drücken hochgeladen werden, das Board bootet nach dem Upload automatisch neu – und fertig.

Demovideo : https://www.youtube.com/watch?v=i9vrU-PSxQo

#include "esp_camera.h"
#include <WiFi.h>


// preconfiguration => Line 141 anf following

//
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
//            Ensure ESP32 Wrover Module or other board with PSRAM is selected
//            Partial images will be transmitted if image exceeds buffer size
//
//            You must select partition scheme from the board menu that has at least 3MB APP space.
//            Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
//            seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well

// ===================
// Select camera model
// ===================
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
//#define CAMERA_MODEL_ESP_EYE  // Has PSRAM
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
//#define CAMERA_MODEL_M5STACK_CAMS3_UNIT  // Has PSRAM
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
// ** Espressif Internal Boards **
//#define CAMERA_MODEL_ESP32_CAM_BOARD
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
#include "camera_pins.h"

// ===========================
// Enter your WiFi credentials
// ===========================
const char *ssid = "WLAN SSID";
const char *password = "WLAN PASSWORD";

void checkWiFiConnection() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi connection lost! Attempting reconnect...");
    WiFi.disconnect();
    WiFi.reconnect();
    unsigned long startAttemptTime = millis();
    while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
      delay(500);
      Serial.print(".");
    }
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("\nWiFi reconnected successfully!");
    } else {
      Serial.println("\nWiFi reconnect failed.");
    }
  }
}

void startCameraServer();
void setupLedFlash(int pin);

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_UXGA;
  config.pixel_format = PIXFORMAT_JPEG;  // for streaming  ORIGINAL
  //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  if (config.pixel_format == PIXFORMAT_JPEG) {
    if (psramFound()) {
      config.jpeg_quality = 10;
      config.fb_count = 2;
      config.grab_mode = CAMERA_GRAB_LATEST;
    } else {
      // Limit the frame size when PSRAM is not available
      config.frame_size = FRAMESIZE_SVGA;
      config.fb_location = CAMERA_FB_IN_DRAM;
    }
  } else {
    // Best option for face detection/recognition
    config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
    config.fb_count = 2;
#endif
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t *s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);        // flip it back
    s->set_brightness(s, 1);   // up the brightness just a bit
    s->set_saturation(s, -2);  // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  if (config.pixel_format == PIXFORMAT_JPEG) {
    s->set_framesize(s, FRAMESIZE_QVGA);
  }

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

#if defined(CAMERA_MODEL_ESP32S3_EYE)
  s->set_vflip(s, 1);
#endif

// Setup LED FLash if LED pin is defined in camera_pins.h
#if defined(LED_GPIO_NUM)
  setupLedFlash(LED_GPIO_NUM);
#endif

//#######################################################################################
// PRECONFIG MANUALLY
// set fixed camera resolution and other camera parameters
// configure LED brightness in file "app_httpd.cpp" with parameter "int led_duty" in line 36
s->set_framesize(s, FRAMESIZE_SVGA);
s->set_vflip(s,1);
s->set_hmirror(s,1);
s->set_special_effect(s, 2); // 2 = Graustufenmodus
//#######################################################################################


  WiFi.begin(ssid, password);
  WiFi.setSleep(false);

  Serial.print("WiFi connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

void loop() {
  // Do nothing. Everything is done in another task by the web server
  checkWiFiConnection();  // WLAN-Verbindung regelmäßig prüfen
  delay(10000);
}

Und welche USB-Adapter sind das jetzt genau ?
Kannst du mal einen Link posten ?

CP210X => APKLVSR ESP32 CAM Development Board, ESP32 USB C WiFi/Bluetooth ESP32 DC 5V Dual-Core Development Board with OV2640 Camera TF Card Module for Arduino: Amazon.de: Computer & Accessories
CH341G => ESP32-CAM-MB 2640 Camera Module WiFi Bluetooth Development Board, USB to Serial Port Automatic Download: Amazon.de: Computer & Accessories

Man kann es leider nicht wirklich erkennen welcher Chip es ist. Auf dem CH341 ist ch341 aufgedruckt, auf dem CP210 steht nichts.

Ich hatte ja extra die PCBs genau verglichen und die zweite Bestellung gleicht der ersten optisch zu 100%, aber technisch eben nicht ;/

Übrigens, die "void checkWiFiConnection" Funktion hat ChatGPT verfasst und funktionierte auf Anhieb :wink:

EDIT : Grad gefunden => ESP32-CAM-MB WIFI Bluetooth Development Board With OV2640/OV3660 Camera CH340G | eBay
Das scheint explizit der CH340G USB2Serial Adapter zu sein

Der CH341 ist rechteckig, der CP210 ist quadratisch.
Nur warum zeigst du in Post #15 ein Board (vermutlich FTDI) was nicht dazu passt ?

Weil man dort den IOB Pin sieht, der beim CP210 Controller durch Drücken des IOB Buttons geöffnet/geschlossen wird

Sorry, aber das verstehe ich nicht.
Was ist IOB Pin und IOB Button ?