#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include "esp_camera.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
// WiFi credentials
const char* ssid = "ESP32-CAM";
const char* password = "12345678";
WebServer server(80);
// Camera pins for AI THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
void setupCamera() {
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_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_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;
config.jpeg_quality = 10; // 0-63, 越低质量越好
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
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();
if (s) {
s->set_framesize(s, FRAMESIZE_VGA);
s->set_quality(s, 10);
s->set_brightness(s, 0);
s->set_contrast(s, 0);
s->set_saturation(s, 0);
s->set_whitebal(s, 1);
s->set_awb_gain(s, 1);
s->set_wb_mode(s, 0);
s->set_exposure_ctrl(s, 1);
s->set_gain_ctrl(s, 1);
s->set_aec2(s, 0);
s->set_gainceiling(s, (gainceiling_t)0);
}
}
void handleRoot() {
const char *html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>ESP32 Camera</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
body {
margin: 0;
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: #f0f0f0;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
margin: 20px auto;
text-align: center;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.stream {
max-width: 100%;
width: auto;
border-radius: 10px;
}
.title {
font-weight: normal;
}
</style>
</head>
<body>
<div class='container'>
<h2 class='title'>ESP32摄像头</h2>
<img src='/stream' class='stream'>
</div>
</body>
</html>
)rawliteral";
server.send(200, "text/html; charset=utf-8", html);
}
void handleStream() {
WiFiClient client = server.client();
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: multipart/x-mixed-replace; boundary=frame");
client.println();
while (client.connected()) {
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
break;
}
client.println("--frame");
client.println("Content-Type: image/jpeg");
client.println("Content-Length: " + String(fb->len));
client.println();
client.write(fb->buf, fb->len);
client.println();
esp_camera_fb_return(fb);
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Serial.begin(115200);
setupCamera();
WiFi.softAP(ssid, password);
WiFi.setSleep(false);
IPAddress IP = WiFi.softAPIP();
Serial.println("AP IP address: " + IP.toString());
server.on("/", HTTP_GET, handleRoot);
server.on("/stream", HTTP_GET, handleStream);
server.begin();
}
void loop() {
server.handleClient();
}
ESP32摄像头优化后代码
于 2025-01-01 20:01:11 首次发布