介绍
ESP32-CAM 采集图像,并通过wed服务器转发到esp32上播放
效果图:
服务器转发的数据长度

实现逻辑
通过node.js搭建wed服务器,esp32-cam通过WebsocketsClient进行图像发送到服务器,服务器再转发到esp32上,并显示到触摸屏上
esp32-cam代码
#include "esp_camera.h"
#include <WiFi.h>
#include <ArduinoWebsockets.h>
#include "camera_pins.h"
const char* ssid = "*********";
const char* password = "*********";
const char* websockets_server_host = "电脑ip地址";
const uint16_t websockets_server_port = 8888;
websockets::WebsocketsClient client;
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
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 = 10000000;
config.pixel_format = PIXFORMAT_JPEG;
//init with high specs to pre-allocate larger buffers
if(psramFound()){
config.frame_size = FRAMESIZE_QVGA; // 320x240
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Ready! Use ip:");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
while(!client.connect(websockets_server_host,websockets_server_port,"/")){
delay(500);
Serial.print(".");
}
Serial.println("Socket Connected!");
}
void loop() {
if (client.available()) {
Serial.println("' send to photo");
// 拍摄图片
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
Serial.println(fb->len);
// 发送图片
client.sendBinary((const char *)fb->buf, fb->len);
esp_camera_fb_return(fb);
}
}
esp32(屏幕配置在TFT_eSPI库的User_Setup.h配置,这里不介绍)
#include <SPI.h>
#include <ArduinoWebsockets.h>
#include <WiFi.h>
#include <TJpg_Decoder.h>
#include <TFT_eSPI.h>
const char* ssid = "**********";
const char* password = "************";
const char* websockets_server_host = "电脑ip"; // 替换为你电脑上WebSocket服务器的本地IP地址
const uint16_t websockets_server_port = 8888; // 替换为你的服务器端口号
using namespace websockets;
WebsocketsClient client;
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
if ( y >= tft.height() ) return 0;
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
void setup() {
Serial.begin(115200);
delay(1000);
tft.begin();
tft.setRotation(3);
tft.setTextColor(0xFFFF, 0x0000);
tft.fillScreen(TFT_BLUE);
tft.setSwapBytes(true);
// The jpeg image can be scaled by a factor of 1, 2, 4, or 8
TJpgDec.setJpgScale(1);
// The decoder must be given the exact name of the rendering function above
TJpgDec.setCallback(tft_output);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Ready! Use ip:");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
if(client.connect(websockets_server_host, websockets_server_port, "/")) {
Serial.println("Connected to WebSocket server");
} else {
Serial.println("WebSocket connect failed.");
while(1) {
delay(1000); // 重连失败则循环等待
}
}
}
void loop() {
if(client.poll()){
WebsocketsMessage msg = client.readBlocking();
uint16_t w = 0, h = 0;
TJpgDec.getJpgSize(&w, &h, (const uint8_t*)msg.c_str(), msg.length());
Serial.print("Width = ");
Serial.print(w);
Serial.print(", height = ");
Serial.println(h);
//绘制jpg图片
TJpgDec.drawJpg(0, 0, (const uint8_t*)msg.c_str(), msg.length());
}
}
node.js服务器
使用:
安装node.js(https://nodejs.cn/)
mkdir my-websocket-server
cd my-websocket-server
npm init -y
npm install ws
code server.js
node server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8888 });
wss.on('connection', function connection(ws) {
console.log('A new client Connected!');
ws.send('Welcome New Client!');
ws.on('message', function incoming(data) {
//console.log('received: %s', data);
console.log('rec len: %d', data.length);
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
ws.on('close', function() {
console.log('Client has disconnected');
});
});
console.log('WebSocket server is running on ws://localhost:8888/');

3784

被折叠的 条评论
为什么被折叠?



