Je vous laisse découvrir …
CODE V1.8
//---------------------------------------------------------------------------------------------------------------------
// DOCS UTILES:
// ------------
// SERVEUR WEB CAM: https://community.jeedom.com/t/tuto-camera-a-focale-fixe-basee-sur-esp32/17587/49
// LED WIFI: https://techtutorialsx.com/2018/02/03/esp32-arduino-async-server-controlling-http-methods-allowed/
// Installing Asyncwebserver: https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/
// IMAGE PARAMS: https://randomnerdtutorials.com/esp32-cam-ov2640-camera-settings/
// @drs
// modified @olive v1.71 jeudi 21 mai 2020 21h27
//
// PARAMETRES A MODIFIER:
// ----------------------
// RESOLUTION: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA / QUALITY (10-63)
// WSPORT: port web (pour affichage images)
// ASYNCPORT: port AsyncWebServer (pour gestion LED)
// Paramètres image
//
// USAGE:
// ------
// http://ip-esp:WSPORT/ page d'accueil
// http://ip-esp:WSPORT/_ac page de config
// http://ip-esp:WSPORT/mjpg: stream
// http://ip-esp:WSPORT/snapshot.jpg image
//
// GESTION DE LA LED:
// ------------------
// http://ip-esp:ASYNCPORT/led Etat de la led (format binaire)
// http://ip-esp:ASYNCPORT/led/on Allume la LED
// http://ip-esp:ASYNCPORT/led/off Eteint la LED
// http://ip-esp:ASYNCPORT/led/toggle Allume/Eteint la LED
//
// GESTION DU GPIO12:
// ------------------
// http://ip-esp:ASYNCPORT/gpio12 Etat du gpio2 (format binaire)
// http://ip-esp:ASYNCPORT/gpio12/on Allume gpio12
// http://ip-esp:ASYNCPORT/gpio12/off Eteint gpio12
// http://ip-esp:ASYNCPORT/gpio12/toggle Allume/Eteint gpio12
//
// INTEGRATION JEEDOM:
// -------------------
// Plugin Camera:
// Laisser le type de camera sur "Aucun"
// Renseigner l'IP et le port (webserver)
// URL de snapshot: /snapshot.jpg
// URL de flux: /mjpg
//
// Script gestion led:
// Action/Default
// URL: voir ci-dessus
// Cocher "Pas d'erreurs"
// La réponse doit contenir: ok (en minuscule)
// Timeout: si besoin (pas nécessaire)
//
//---------------------------------------------------------------------------------------------------------------------
#include <WiFi.h>
#include <WebServer.h>
#include <ESPAsyncWebServer.h> //permet la connexion simultanee pour la gestion de la LED
#include <WiFiClient.h>
#include <AutoConnect.h> // Needs AutoConnect, PageBuilder libraries!
#include "soc/soc.h" //disable brownout problems
#include "soc/rtc_cntl_reg.h" //disable brownout problems
#include "esp_camera.h" // Pas sur de l'utilité. A vérifier
#define ENABLE_RTSPSERVER
#define ENABLE_WEBSERVER
#define RESOLUTION FRAMESIZE_CIF // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
#define QUALITY 10 // JPEG quality 10-63 (lower means better quality)
// PARAMETRES IMAGE
#define BRIGHT 1 // Brightness: -2 to 2
#define CONTRAST 0 // Contrast: -2 to 2
#define SATUR 0 // Color Saturation: -2 to 2
#define SPECIAL 0 // Special effects: 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
#define WHITEBAL 1 // White Balance: 0 = disable , 1 = enable
#define AWBGAIN 1 // White Balance Gain: 0 = disable , 1 = enable
#define AWBMODE 3 // White Balance Mode: 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
#define EXPOS 1 // Exposure Control: 0 = disable , 1 = enable
#define AEC2 0 // 0 = disable , 1 = enable
#define AELEV 0 // -2 to 2
#define AECVAL 300 // 0 to 1200
#define GAINCT 1 // 0 = disable , 1 = enable
#define GAINAGC 0 // 0 = disable , 1 = enable
#define GAINCELL 0 // 0 = disable , 1 = enable
#define BPC 0 // 0 = disable , 1 = enable
#define WPC 1 // 0 = disable , 1 = enable
#define RAWGMA 1 // 0 = disable , 1 = enable
#define LENC 1 // Lens Correction: 0 = disable , 1 = enable
#define MIRROR 0 // Horizontal Mirror: 0 = disable , 1 = enable
#define FLIP 0 // Vertical Flip: 0 = disable , 1 = enable
#define DCW 1 // 0 = disable , 1 = enable
#define CBAR 0 // Set a colorBar: 0 = disable , 1 = enable
#define LED_BUILTIN 4 // VA SERVIR POUR ALLUMER et ETEINDRE LA LED - NE PAS MODIFIER CETTE VALEUR (GPIO4)
#include "OV2640.h"
#ifdef ENABLE_RTSPSERVER
#include "OV2640Streamer.h"
#include "CRtspSession.h"
#endif
OV2640 cam;
boolean useRTSP = true;
#define WSPORT 80 // modifier le port pour Webserver Image
#define ASYNCPORT 81 // modifier le port pour Webserver LED
WebServer server(WSPORT);
AsyncWebServer serverasync(ASYNCPORT);
AutoConnect Portal(server);
AutoConnectConfig acConfig;
#ifdef ENABLE_RTSPSERVER
WiFiServer rtspServer(554);
CStreamer *streamer;
#endif
void handle_jpg_stream(void)
{
WiFiClient client = server.client();
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
server.sendContent(response);
while (1)
{
cam.run();
if (!client.connected())
break;
response = "--frame\r\n";
response += "Content-Type: image/jpeg\r\n\r\n";
server.sendContent(response);
client.write((char *)cam.getfb(), cam.getSize());
server.sendContent("\r\n");
if (!client.connected())
break;
}
}
void handle_jpg(void)
{
WiFiClient client = server.client();
cam.run();
if (!client.connected())
{
return;
}
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-disposition: inline; filename=snapshot.jpg\r\n";
response += "Content-type: image/jpeg\r\n\r\n";
server.sendContent(response);
client.write((char *)cam.getfb(), cam.getSize());
}
void handle_root(void)
{
String reply ="<!doctype html>\
<style type=text/css>\
body {\
background-color: #272727; \
}\
<style>\
th, td {\
border: 1px solid black;\
background-color: #FFFF00; \
}\
table {\
border-collapse: collapse;\
background-color: #00AA00; \
}\
a {\
color: red; \
}\
</style>";
reply +=F("<html><head><meta charset='UTF-8'></head><table><tr><td colspan='2'><H1>ESP32CAM</H1></td></tr>");
reply +=F("<tr><td>VERSION </td><td>1.8</td></tr>");
reply += F("<tr><td>Resolution</td>");
switch(RESOLUTION) {
case FRAMESIZE_QVGA:
reply += F("<td>QVGA (320x240)</td>");
break;
case FRAMESIZE_CIF:
reply += F("<td>CIF (400x296)</td>");
break;
case FRAMESIZE_VGA:
reply += F("<td>VGA (640x480)</td>");
break;
case FRAMESIZE_SVGA:
reply += F("<td>SVGA (800x600)</td>");
break;
case FRAMESIZE_XGA:
reply += F("<td>XGA (1024x768)</td>");
break;
case FRAMESIZE_SXGA:
reply += F("<td>SXGA (1280x1024)</td>");
break;
case FRAMESIZE_UXGA:
reply += F("<td>UXGA (1600x1200)</td>");
break;
default:
reply += F("<td>Unknown</td>");
break;
}
reply += F("</tr><tr><td>PSRAM found</td>");
if (psramFound()){
reply += F("<td>TRUE</td></tr>");
} else {
reply += F("<td>FALSE</td></tr></tr>");
}
String IP = WiFi.localIP().toString();
String IPH = "http://" + IP + ":" + WSPORT;
String IPA = "http://" + IP + ":" + ASYNCPORT;
String IPR = "rstp://" + IP + ":554";
String url = IPH + "/snapshot.jpg";
reply += "<tr><td>Snapshot URL</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPH + "/mjpg";
reply += "<tr><td>HTTP MJPEG URL</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPR + "/mjpeg/1";
reply += "<tr><td>RTSP MJPEG URL</td><td>" + url;
url = IPH + "/_ac";
reply += "<tr><td>WiFi settings page</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
//LED
url = IPA + "/led/on";
reply += "<tr><td>Led_on</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led/off";
reply += "<tr><td>Led_off</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led/toggle";
reply += "<tr><td>Led_toggle</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led";
reply += "<tr><td>Led_etat</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
//GPIO12
url = IPA + "/gpio12/on";
reply += "<tr><td>gpio12_on</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12/off";
reply += "<tr><td>gpio12_off</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12/toggle";
reply += "<tr><td>gpio12_toggle</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12";
reply += "<tr><td>gpio12_etat</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
reply += "</table><img src='"+IPH+"/mjpg'>\
</body></html>";
server.send(200, "text/html", reply);
}
void handleNotFound()
{
String message = "Server is running!\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
server.send(200, "text/plain", message);
}
void setup(){
pinMode(LED_BUILTIN, OUTPUT); // pour LED
digitalWrite(LED_BUILTIN, LOW); // pour LED
pinMode(12, OUTPUT); // pour RELAIS SUR GPIO12
digitalWrite(12, LOW); // pour RELAIS SUR GPIO12
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
// while (!Serial){;} // debug only
camera_config_t cconfig;
cconfig = esp32cam_aithinker_config;
if (psramFound()) {
cconfig.frame_size = RESOLUTION; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
cconfig.jpeg_quality = QUALITY;
cconfig.fb_count = 2;
} else {
if (RESOLUTION>FRAMESIZE_SVGA) {
cconfig.frame_size = FRAMESIZE_SVGA;
}
cconfig.jpeg_quality = 12;
cconfig.fb_count = 1;
}
cam.init(cconfig);
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, BRIGHT);
s->set_contrast(s, CONTRAST);
s->set_saturation(s, SATUR);
s->set_special_effect(s, SPECIAL);
s->set_whitebal(s, WHITEBAL);
s->set_awb_gain(s, AWBGAIN);
s->set_wb_mode(s, AWBMODE);
s->set_exposure_ctrl(s, EXPOS);
s->set_aec2(s, AEC2);
s->set_ae_level(s, AELEV);
s->set_aec_value(s, AECVAL);
s->set_gain_ctrl(s, GAINCT);
s->set_agc_gain(s, GAINAGC);
s->set_gainceiling(s, (gainceiling_t)GAINCELL);
s->set_bpc(s, BPC);
s->set_wpc(s, WPC);
s->set_raw_gma(s, RAWGMA);
s->set_lenc(s, LENC);
s->set_hmirror(s, MIRROR);
s->set_vflip(s, FLIP);
s->set_dcw(s, DCW);
s->set_colorbar(s, CBAR);
server.on("/", handle_root);
server.on("/mjpg", HTTP_GET, handle_jpg_stream);
server.on("/snapshot.jpg", HTTP_GET, handle_jpg);
Portal.onNotFound(handleNotFound);
acConfig.apid = "ESP-" + String((uint32_t)(ESP.getEfuseMac() >> 32), HEX);
acConfig.psk = "configesp";
acConfig.apip = IPAddress(192,168,4,1);
acConfig.hostName = acConfig.apid;
acConfig.autoReconnect = true;
Portal.config(acConfig);
Portal.begin();
Serial.println(" ");
Serial.println("Adresse IP: " + WiFi.localIP().toString() );
Serial.println(" ");
// POUR LED
serverasync.on("/led/off", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "ok");
digitalWrite(LED_BUILTIN, LOW);
Serial.println("LED TURNED OFF");
});
serverasync.on("/led/on", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("LED TURNED ON");
});
serverasync.on("/led/toggle", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("LED TURNED TOGGLE");
});
serverasync.on("/led", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(digitalRead(LED_BUILTIN)));
});
// POUR GPIO 12
serverasync.on("/gpio12/off", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "ok");
digitalWrite(12, LOW);
Serial.println("gpio12 TURNED OFF");
});
serverasync.on("/gpio12/on", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(12, HIGH);
Serial.println("gpio12 TURNED ON");
});
serverasync.on("/gpio12/toggle", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(12, !digitalRead(12));
Serial.println("gpio12 TURNED TOGGLE");
});
serverasync.on("/gpio12", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(digitalRead(12)));
});
serverasync.begin();
#ifdef ENABLE_RTSPSERVER
if (useRTSP) {
rtspServer.begin();
streamer = new OV2640Streamer(cam); // our streamer for UDP/TCP based RTP transport
}
#endif
}
void loop()
{
//server.handleClient();
Portal.handleClient();
#ifdef ENABLE_RTSPSERVER
if (useRTSP) {
uint32_t msecPerFrame = 100;
static uint32_t lastimage = millis();
// If we have an active client connection, just service that until gone
streamer->handleRequests(0); // we don't use a timeout here,
// instead we send only if we have new enough frames
uint32_t now = millis();
if (streamer->anySessions()) {
if (now > lastimage + msecPerFrame || now < lastimage) { // handle clock rollover
streamer->streamImage(now);
lastimage = now;
// check if we are overrunning our max frame rate
now = millis();
if (now > lastimage + msecPerFrame) {
printf("warning exceeding max frame rate of %d ms\n", now - lastimage);
}
}
}
WiFiClient rtspClient = rtspServer.accept();
if (rtspClient) {
Serial.print("client: ");
Serial.print(rtspClient.remoteIP());
Serial.println();
streamer->addSession(rtspClient);
}
}
#endif
}
@Theduck38 tu va devoir corriger le post 7 aussi