diff --git a/esp32-cam-webserver.ino b/esp32-cam-webserver.ino index 2ca4b7a..a39b514 100644 --- a/esp32-cam-webserver.ino +++ b/esp32-cam-webserver.ino @@ -6,6 +6,7 @@ #include #include "src/parsebytes.h" #include "time.h" +#include /* This sketch is a extension/expansion/reork of the 'official' ESP32 Camera example @@ -16,7 +17,7 @@ * greater feedback via a status LED, and the HTML contents are present in plain text * for easy modification. * - * A camera name can now be configured, and wifi details can be stored in an optional + * A camera name can now be configured, and wifi details can be stored in an optional * header file to allow easier updated of the repo. * * The web UI has had changes to add the lamp control, rotation, a standalone viewer, @@ -26,7 +27,7 @@ */ -/* +/* * FOR NETWORK AND HARDWARE SETTINGS COPY OR RENAME 'myconfig.sample.h' TO 'myconfig.h' AND EDIT THAT. * * By default this sketch will assume an AI-THINKER ESP-CAM and create @@ -42,7 +43,7 @@ #warning "Using Defaults: Copy myconfig.sample.h to myconfig.h and edit that to use your own settings" #define WIFI_AP_ENABLE #define CAMERA_MODEL_AI_THINKER - struct station { const char ssid[65]; const char password[65]; const bool dhcp;} + struct station { const char ssid[65]; const char password[65]; const bool dhcp;} stationList[] = {{"ESP32-CAM-CONNECT","InsecurePassword", true}}; #endif @@ -103,7 +104,7 @@ int stationCount = sizeof(stationList)/sizeof(stationList[0]); // If we have AP mode enabled, ignore first entry in the stationList[] #if defined(WIFI_AP_ENABLE) - int firstStation = 1; + int firstStation = 1; #else int firstStation = 0; #endif @@ -158,7 +159,7 @@ int myRotation = CAM_ROTATION; #else int lampVal = 0; //default to off #endif -#else +#else int lampVal = -1; // no lamp pin assigned #endif @@ -234,7 +235,7 @@ void handleSerial() { while (Serial.available()) Serial.read(); // chomp the buffer } -// Notification LED +// Notification LED void flashLED(int flashtime) { #ifdef LED_PIN // If we have it; flash it. digitalWrite(LED_PIN, LED_ON); // On at full power. @@ -297,7 +298,7 @@ void WifiSetup() { flashLED(300); Serial.println("Starting WiFi"); - // Disable power saving on WiFi to improve responsiveness + // Disable power saving on WiFi to improve responsiveness // (https://github.com/espressif/arduino-esp32/issues/1484) WiFi.setSleep(false); @@ -311,13 +312,13 @@ void WifiSetup() { byte mac[6] = {0,0,0,0,0,0}; WiFi.macAddress(mac); Serial.printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - + int bestStation = -1; long bestRSSI = -1024; char bestSSID[65] = ""; uint8_t bestBSSID[6]; if (stationCount > firstStation) { - // We have a list to scan + // We have a list to scan Serial.printf("Scanning local Wifi Networks\r\n"); int stationsFound = WiFi.scanNetworks(); Serial.printf("%i networks found\r\n", stationsFound); @@ -330,7 +331,7 @@ void WifiSetup() { Serial.printf("%3i : [%s] %s (%i)", i + 1, thisBSSID.c_str(), thisSSID.c_str(), thisRSSI); // Scan our list of known external stations for (int sta = firstStation; sta < stationCount; sta++) { - if ((strcmp(stationList[sta].ssid, thisSSID.c_str()) == 0) || + if ((strcmp(stationList[sta].ssid, thisSSID.c_str()) == 0) || (strcmp(stationList[sta].ssid, thisBSSID.c_str()) == 0)) { Serial.print(" - Known!"); // Chose the strongest RSSI seen @@ -338,7 +339,7 @@ void WifiSetup() { bestStation = sta; strncpy(bestSSID, thisSSID.c_str(), 64); // Convert char bssid[] to a byte array - parseBytes(thisBSSID.c_str(), ':', bestBSSID, 6, 16); + parseBytes(thisBSSID.c_str(), ':', bestBSSID, 6, 16); bestRSSI = thisRSSI; } } @@ -348,11 +349,11 @@ void WifiSetup() { } } else { // No list to scan, therefore we are an accesspoint - accesspoint = true; + accesspoint = true; } if (bestStation == -1) { - if (!accesspoint) { + if (!accesspoint) { #if defined(WIFI_AP_ENABLE) Serial.println("No known networks found, entering AccessPoint fallback mode"); accesspoint = true; @@ -363,14 +364,14 @@ void WifiSetup() { Serial.println("AccessPoint mode selected in config"); } } else { - Serial.printf("Connecting to Wifi Network %d: [%02X:%02X:%02X:%02X:%02X:%02X] %s \r\n", - bestStation, bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], + Serial.printf("Connecting to Wifi Network %d: [%02X:%02X:%02X:%02X:%02X:%02X] %s \r\n", + bestStation, bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestSSID); // Apply static settings if necesscary if (stationList[bestStation].dhcp == false) { #if defined(ST_IP) Serial.println("Applying static IP settings"); - #if !defined (ST_GATEWAY) || !defined (ST_NETMASK) + #if !defined (ST_GATEWAY) || !defined (ST_NETMASK) #error "You must supply both Gateway and NetMask when specifying a static IP address" #endif IPAddress staticIP(ST_IP); @@ -400,7 +401,7 @@ void WifiSetup() { WiFi.begin(bestSSID, stationList[bestStation].password, 0, bestBSSID); // Wait to connect, or timeout - unsigned long start = millis(); + unsigned long start = millis(); while ((millis() - start <= WIFI_WATCHDOG) && (WiFi.status() != WL_CONNECTED)) { delay(500); Serial.print('.'); @@ -495,7 +496,7 @@ void setup() { Serial.println("\r\nFatal Error; Halting"); while (true) { Serial.println("No wifi details have been configured; we cannot connect to existing WiFi or start our own AccessPoint, there is no point in proceeding."); - delay(5000); + delay(5000); } } @@ -504,7 +505,7 @@ void setup() { digitalWrite(LED_PIN, LED_ON); #endif - // Create camera config structure; and populate with hardware and other defaults + // Create camera config structure; and populate with hardware and other defaults camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; @@ -560,7 +561,7 @@ void setup() { critERR += "

We will continue to reboot once per minute since this error sometimes clears automatically.

"; // Start a 60 second watchdog timer esp_task_wdt_init(60,true); - esp_task_wdt_add(NULL); + esp_task_wdt_add(NULL); } else { Serial.println("Camera init succeeded"); @@ -607,7 +608,7 @@ void setup() { /* * Add any other defaults you want to apply at startup here: * uncomment the line and set the value as desired (see the comments) - * + * * these are defined in the esp headers here: * https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h#L149 */ @@ -675,7 +676,7 @@ void setup() { // Start OTA once connected Serial.println("Setting up OTA"); // Port defaults to 3232 - // ArduinoOTA.setPort(3232); + // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] ArduinoOTA.setHostname(myName); // No authentication by default @@ -712,8 +713,17 @@ void setup() { ArduinoOTA.begin(); } else { Serial.println("OTA is disabled"); + + if (!MDNS.begin(myName)) { + Serial.println("Error setting up MDNS responder!"); + } + Serial.println("mDNS responder started"); } + //MDNS Config -- note that if OTA is NOT enabled this needs prior steps! + MDNS.addService("http", "tcp", 80); + Serial.println("Added HTTP service to MDNS server"); + // Set time via NTP server when enabled if (haveTime) { Serial.print("Time: "); @@ -758,7 +768,7 @@ void setup() { } void loop() { - /* + /* * Just loop forever, reconnecting Wifi As necesscary in client mode * The stream and URI handler processes initiated by the startCameraServer() call at the * end of setup() will handle the camera and UI processing from now on. @@ -774,12 +784,12 @@ void loop() { if (captivePortal) dnsServer.processNextRequest(); } } else { - // client mode can fail; so reconnect as appropriate + // client mode can fail; so reconnect as appropriate static bool warned = false; if (WiFi.status() == WL_CONNECTED) { // We are connected, wait a bit and re-check if (warned) { - // Tell the user if we have just reconnected + // Tell the user if we have just reconnected Serial.println("WiFi reconnected"); warned = false; } diff --git a/myconfig.sample.h b/myconfig.sample.h index e463e4b..2a368f4 100644 --- a/myconfig.sample.h +++ b/myconfig.sample.h @@ -1,17 +1,20 @@ -/* +/* * Rename this example to 'myconfig.h' and fill in your details. - * + * * The local config is in the '.gitignore' file, which helps to keep details secret. */ -/* Give the camera a name for the web interface */ +/* Give the camera a name for the web interface + * A word of warning: This name is also used for OTA updates and MDNS addressing. + * Pick something convenient! + */ #define CAM_NAME "ESP32 camera server" /* * WiFi Settings - * + * * For the simplest connection to an existing network * just replace your ssid and password in the line below. */ @@ -31,18 +34,18 @@ struct station stationList[] = {{"ssid1", "pass1", true}, * it will be used for the AccessPoint ssid and password. See the comments there for more. * * The 'dhcp' setting controls whether the station uses DHCP or static IP settings; if in doubt leave 'true' - * + * * You can also use a BSSID (eg: "2F:67:94:F5:BB:6A", a colon separated mac address string) in place of * the ssid to force connections to specific networks even when the ssid's collide, */ /* Extended WiFi Settings */ -/* +/* * Hostname. Optional, uncomment and set if desired * - used in DHCP request when connecting to networks, not used in AP mode * - Most useful when used with a static netwrk config, not all routers respect this setting - * + * * The URL_HOSTNAME will be used in place of the IP address in internal URL's */ @@ -51,22 +54,22 @@ struct station stationList[] = {{"ssid1", "pass1", true}, /* * Static network settings for client mode - * + * * Note: The same settings will be applied to all client connections where the dhcp setting is 'false' * You must define all three: IP, Gateway and NetMask */ // warning - IP addresses must be separated with commas (,) and not decimals (.) // #define ST_IP 192,168,0,123 -// #define ST_GATEWAY 192,168,0,2 +// #define ST_GATEWAY 192,168,0,2 // #define ST_NETMASK 255,255,255,0 // One or two DNS servers can be supplied, only the NTP code currently uses them // #define ST_DNS1 192,168,0,2 // #define ST_DNS2 8,8,8,8 -/* - * AccessPoint; +/* + * AccessPoint; * - * Uncomment to enable AP mode; + * Uncomment to enable AP mode; * */ // #define WIFI_AP_ENABLE @@ -79,7 +82,7 @@ struct station stationList[] = {{"ssid1", "pass1", true}, * if they are found. AP then works as a fallback mode for when there are no 'real' networks available. * * Setting the 'dhcp' field to true for the AP enables a captive portal and attempts to send - * all visitors to the webcam page, with varying degrees of success depending on the visitors + * all visitors to the webcam page, with varying degrees of success depending on the visitors * browser and other settings. */ // Optionally change the AccessPoint ip address (default = 192.168.4.1) @@ -185,7 +188,7 @@ struct station stationList[] = {{"ssid1", "pass1", true}, // #define CAMERA_MODEL_ARDUCAM_ESP32S_UNO // Camera module bus communications frequency, setting too high can cause visual artifacts. -// Currently defaults to 16.5MHz, but some (non-clone) modules may be able to use the +// Currently defaults to 16.5MHz, but some (non-clone) modules may be able to use the // original frequency of 20MHz for to allow higher framerates etc. // #define XCLK_FREQ_HZ 20000000; // For clone modules that have camera module artifacts and SPIFFS issues; try setting this very low: