#include "esp_camera.
h"
#include <WiFi.h>
// Select camera model
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
#include "camera_pins.h"
// WiFi credentials
const char* ssid = "P403/31/491delathanh";
const char* password = "BMCBMC403";
WiFiServer server(80);
// HTML/CSS content
const char* htmlContent = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Hoc Ky Thuat Channel</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}
h1 { color: #333; }
.button {
padding: 15px 30px;
margin: 10px;
font-size: 16px;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
}
.button:hover { background-color: #45a049; }
#camImage { max-width: 100%; height: auto; margin-top: 20px; }
</style>
</head>
<body>
<h1>Hoc Ky Thuat Channel</h1>
<button class="button" onclick="capturePhoto()">Capture</button>
<br>
<img id="camImage" src="">
<script>
function capturePhoto() {
fetch('/capture')
.then(response => [Link]())
.then(data => {
[Link]('camImage').src = '/photo?' + new
Date().getTime();
});
}
</script>
</body>
</html>
)rawliteral";
void setup() {
[Link](115200);
[Link](true);
[Link]();
// Camera configuration
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.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_VGA; // 640x480
config.jpeg_quality = 12;
config.fb_count = 1;
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
// Check for PSRAM
if (psramFound()) {
config.jpeg_quality = 10;
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
// Initialize camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
[Link]("Camera init failed with error 0x%x", err);
return;
}
// Configure sensor
sensor_t *s = esp_camera_sensor_get();
if (s->[Link] == OV3660_PID) {
s->set_vflip(s, 1); // Flip image vertically
s->set_brightness(s, 1); // Increase brightness
s->set_saturation(s, -2); // Decrease saturation
}
s->set_framesize(s, FRAMESIZE_VGA); // Set frame size again
// Connect to WiFi
[Link](ssid, password);
[Link](false);
[Link]("WiFi connecting");
while ([Link]() != WL_CONNECTED) {
delay(500);
[Link](".");
}
[Link]("");
[Link]("WiFi connected");
[Link]([Link]());
// Start the server
[Link]();
}
void loop() {
WiFiClient client = [Link]();
if (client) {
String currentLine = "";
while ([Link]()) {
if ([Link]()) {
char c = [Link]();
if (c == '\n') {
if ([Link]() == 0) {
[Link]("HTTP/1.1 200 OK");
[Link]("Content-type:text/html");
[Link]();
[Link](htmlContent);
break;
} else if ([Link]("GET /capture")) {
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
[Link]("HTTP/1.1 500 Internal Server Error");
break;
}
esp_camera_fb_return(fb);
[Link]("HTTP/1.1 200 OK");
[Link]("Content-type:text/plain");
[Link]();
[Link]("Photo captured");
break;
} else if ([Link]("GET /photo")) {
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
[Link]("HTTP/1.1 500 Internal Server Error");
break;
}
[Link]("HTTP/1.1 200 OK");
[Link]("Content-type:image/jpeg");
[Link]("Content-Length: " + String(fb->len));
[Link]();
[Link](fb->buf, fb->len);
esp_camera_fb_return(fb);
break;
}
currentLine = "";
} else if (c != '\r') {
currentLine += c;
}
}
}
[Link]();
}
}