esp32s3 嘉立创实战派GC0308摄像头传输显示
·
#include <esp_camera.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Wire.h>
const char* ssid = "";
const char* password = "";
WebServer server(80);
// ==============================================
// 引脚定义
// ==============================================
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 5
#define SIOD_GPIO_NUM 1
#define SIOC_GPIO_NUM 2
#define Y9_GPIO_NUM 9
#define Y8_GPIO_NUM 4
#define Y7_GPIO_NUM 6
#define Y6_GPIO_NUM 15
#define Y5_GPIO_NUM 17
#define Y4_GPIO_NUM 8
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 16
#define VSYNC_GPIO_NUM 3
#define HREF_GPIO_NUM 46
#define PCLK_GPIO_NUM 7
// PCA9557
#define PCA9557_ADDR 0x19
#define PCA9557_OUTPUT_PORT 0x01
#define PCA9557_CONFIG_PORT 0x03
#define DVP_PWDN_GPIO (1 << 2)
// ==============================================
// PCA9557 初始化
// ==============================================
void pca9557_init() {
Wire.beginTransmission(PCA9557_ADDR);
Wire.write(PCA9557_OUTPUT_PORT);
Wire.write(0x05);
Wire.endTransmission();
delay(10);
Wire.beginTransmission(PCA9557_ADDR);
Wire.write(PCA9557_CONFIG_PORT);
Wire.write(0xF8);
Wire.endTransmission();
delay(10);
}
// ==============================================
// 打开摄像头电源
// ==============================================
void dvp_pwdn(uint8_t level) {
uint8_t data;
Wire.beginTransmission(PCA9557_ADDR);
Wire.write(PCA9557_OUTPUT_PORT);
Wire.endTransmission();
Wire.requestFrom(PCA9557_ADDR, 1);
data = Wire.read();
if (level) data |= DVP_PWDN_GPIO;
else data &= ~DVP_PWDN_GPIO;
Wire.beginTransmission(PCA9557_ADDR);
Wire.write(PCA9557_OUTPUT_PORT);
Wire.write(data);
Wire.endTransmission();
delay(10);
}
// ==============================================
// 视频流(使用 sendContent 自动分块)
// ==============================================
void handleStream() {
camera_fb_t *fb = NULL;
uint8_t *jpg_buf = NULL;
size_t jpg_len = 0;
// 发送 HTTP 响应头
server.sendHeader("Content-Type", "multipart/x-mixed-replace;boundary=frame");
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200);
while (true) {
// 检查客户端是否断开
if (!server.client().connected()) {
break;
}
// 获取帧
fb = esp_camera_fb_get();
if (!fb) {
delay(10);
continue;
}
// 转换 RGB565 到 JPEG
bool ok = frame2jpg(fb, 12, &jpg_buf, &jpg_len);
if (ok && jpg_buf != NULL) {
// 发送帧头
String head = "--frame\r\nContent-Type: image/jpeg\r\nContent-Length: " + String(jpg_len) + "\r\n\r\n";
server.sendContent(head);
// 发送 JPEG 数据
server.sendContent_P((const char*)jpg_buf, jpg_len);
// 发送帧尾
server.sendContent("\r\n");
// 释放 JPEG 缓冲
free(jpg_buf);
jpg_buf = NULL;
}
// 释放摄像头帧
esp_camera_fb_return(fb);
}
}
// ==============================================
// 主页
// ==============================================
void handleRoot() {
String html = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>ESP32-S3 摄像头</title></head>";
html += "<body style='text-align:center; margin-top:20px;'>";
html += "<h1>立创 ESP32-S3 GC0308 摄像头</h1>";
html += "<img src='/stream' width='320' style='border:2px solid #333; border-radius:5px;'>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n--- 启动视频流系统 ---");
// 1. I2C
Wire.begin(SIOD_GPIO_NUM, SIOC_GPIO_NUM);
delay(100);
// 2. PCA9557
pca9557_init();
// 3. 打开电源
dvp_pwdn(0);
delay(300);
// 4. 摄像头配置
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_1;
config.ledc_timer = LEDC_TIMER_1;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.xclk_freq_hz = 16000000;
config.pixel_format = PIXFORMAT_RGB565;
config.frame_size = FRAMESIZE_QVGA;
config.jpeg_quality = 12;
config.fb_count = 3;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.grab_mode = CAMERA_GRAB_LATEST;
// 5. 初始化摄像头
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera Fail: 0x%x\n", err);
return;
}
// 6. 镜像
sensor_t *s = esp_camera_sensor_get();
if (s->id.PID == GC0308_PID) {
s->set_hmirror(s, 1);
}
Serial.println("[OK] 摄像头初始化成功");
// 7. WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n[OK] WiFi 连接成功");
Serial.print("[OK] 访问地址:http://");
Serial.println(WiFi.localIP());
// 8. 网页路由
server.on("/", handleRoot);
server.on("/stream", handleStream);
server.begin();
Serial.println("[OK] Web 服务器已启动");
Serial.println("==================================");
Serial.println("视频流系统已就绪!");
Serial.println("==================================");
}
void loop() {
server.handleClient();
}
更多推荐


所有评论(0)