Skip to content

Commit

Permalink
Merge pull request #200 from ueckoken/esp-cam-udp
Browse files Browse the repository at this point in the history
Esp cam udpを生やした
  • Loading branch information
McbeEringi authored Nov 8, 2023
2 parents 8914c21 + 9ed1b45 commit 56882db
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 0 deletions.
1 change: 1 addition & 0 deletions hardware/esp32-cam-udp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.pio
5 changes: 5 additions & 0 deletions hardware/esp32-cam-udp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ESP-CAM-UDP

ESP32→(UDP)→NodeJS→(WebSocket)→browser

800x600 30fps 200ms
32 changes: 32 additions & 0 deletions hardware/esp32-cam-udp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions hardware/esp32-cam-udp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"ws": "^8.14.2"
}
}
11 changes: 11 additions & 0 deletions hardware/esp32-cam-udp/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[env:main]
platform=espressif32
framework=arduino
board=esp32cam
; board_build.filesystem=littlefs
targets=upload
lib_deps=
esp32-camera
; https://github.com/dvarrel/AsyncTCP.git
; https://github.com/dvarrel/ESPAsyncWebSrv.git

60 changes: 60 additions & 0 deletions hardware/esp32-cam-udp/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiUDP.h>
#include <ESPmDNS.h>
#include <esp_camera.h>

#define HOST "toko-minibookx"
#define PORT 3333
#define SIZE 1024

WiFiUDP udp;
IPAddress host;

static camera_config_t cam_cfg={// https://github.com/espressif/esp-who/blob/master/docs/en/Camera_connections.md
.pin_pwdn=-1,.pin_reset=-1,
.pin_xclk=4,.pin_sccb_sda=18,.pin_sccb_scl=23,

.pin_d7=36,.pin_d6=37,.pin_d5=38,.pin_d4=39,.pin_d3=35,.pin_d2=14,.pin_d1=13,.pin_d0=34,
.pin_vsync=5,.pin_href=27,.pin_pclk=25,

.xclk_freq_hz=20000000,//EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
.ledc_timer=LEDC_TIMER_0,.ledc_channel=LEDC_CHANNEL_0,

.pixel_format=PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG
.frame_size=FRAMESIZE_VGA,//QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.

.jpeg_quality=12, //0-63, for OV series camera sensors, lower number means higher quality
.fb_count=2, //When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode.
.grab_mode=CAMERA_GRAB_WHEN_EMPTY//CAMERA_GRAB_LATEST. Sets when buffers should be filled
};

void setup(){
psramInit();pinMode(21,OUTPUT);pinMode(22,OUTPUT);

WiFi.begin();
for(uint8_t i=0;WiFi.status()!=WL_CONNECTED;i++){
if(i>20){
digitalWrite(21,HIGH);
WiFi.beginSmartConfig();while(!WiFi.smartConfigDone());
}
delay(500);
}
MDNS.begin("udp-cam");
host=MDNS.queryHost(HOST);
digitalWrite(21,LOW);
esp_camera_init(&cam_cfg);
digitalWrite(22,HIGH);
}

void loop(){
camera_fb_t *fb=esp_camera_fb_get();
const uint8_t *t=(uint8_t*)(&fb->timestamp.tv_usec);
uint8_t n=(fb->len+SIZE-1)/SIZE;

udp.beginPacket(host,PORT);udp.printf("STRT");udp.write(t,4);udp.write(n);udp.endPacket();
for(uint8_t i=0;i<n;i++){
udp.beginPacket(host,PORT);udp.printf("DATA");udp.write(t,4);udp.write(i);udp.write(fb->buf+SIZE*i,i+1==n?fb->len-SIZE*i:SIZE);udp.endPacket();
}
esp_camera_fb_return(fb);
}
68 changes: 68 additions & 0 deletions hardware/esp32-cam-udp/svr.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as DGRAM from 'dgram';
import * as HTTP from 'http';
import * as WS from 'ws';

const
udp=DGRAM.createSocket('udp4'),
svr=HTTP.createServer((req,res)=>(
res.writeHead(200,{'Content-Type':'text/html'}),
res.end(`
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>video</title>
</head>
<body>
<style>:root,body,#img{width:100%;height:100%;margin:0;background-color:#00f;object-fit:contain;vertical-align:top;}</style>
<img id="img">
<script>
'use strict';
let ws={},t;
const
main=_=>(
ws=Object.assign(new WebSocket(\`ws://\${location.hostname}/ws\`),{
binaryType:'arraybuffer',
onopen:_=>console.log('Opened'),
onclose:_=>console.log('Closed',main()),
onmessage:e=>img.src='data:image/jpeg;base64,'+btoa(String.fromCharCode(...new Uint8Array(e.data)))
})
);
img.onload=_=>console.log(Math.round(1000/(-t+(t=performance.now()))));
document.onvisibilitychange=_=>ws.send('');
onload=main;
</script>
</body>
</html>
`)
)),
ws=new Set(),
wss=new WS.WebSocketServer({server:svr,path:'/ws'});

wss.on('connection',_=>ws.add(_));
wss.on('close',_=>ws.delete(_));

let fb={},t;
udp.on('message',(x,i)=>(
x={
tag:x.subarray(0,4)+'',
t:x.readUInt32LE(4),
i:x[8],
x:x.subarray(9)
},
({
STRT:_=>(fb[x.t]=[...Array(x.i)],setTimeout(_=>delete fb[x.t],500)),
DATA:_=>fb[x.t]&&(
fb[x.t][x.i]=x.x,
fb[x.t].every(_=>_)&&(
_=Buffer.concat(fb[x.t]),delete fb[x.t],ws.forEach(x=>x.send(_)),
console.log({fps:Math.round(1000/(-t+(t=Date.now()))),size:_.length,t:x.t})
)
),
}[x.tag])()
// console.log(x+'',i.address,i.port)
));
udp.on('listening',_=>console.log(`port ${udp.address().port} ...`));
udp.bind(3333);
svr.listen(80);

0 comments on commit 56882db

Please sign in to comment.