#include "esp_camera.h"
#include <WiFi.h>
#include "soc/soc.h" //disable brownout problems
#include "soc/rtc_cntl_reg.h" //disable brownout problems
#include "esp_timer.h"
#include "img_converters.h"
#include "fb_gfx.h"
#include <WebSocketsServer.h>
#include "driver/gpio.h"
#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
WebSocketsServer webSocket = WebSocketsServer(81);
WiFiServer server(80);
uint8_t cam_num;
bool connected = false;
String index_html = R"=====(
<html>
<head>
<title>Web Camera</title>
<script src='http://code.jquery.com/jquery-1.9.1.min.js'></script>
</head>
<body style ="text-align:center">
<img id='live' src='https://assets.onecompiler.app/42s9sq2zf/437ddumdw/abstract-dark-wallpaper-programming-web-development-related_941097-79543.jpg'
style="display: block;width:100%;height:auto;object-fit: cover;
margin-left: auto;margin-right: auto" height="600" width="800">
<button onclick="document.getElementById('fla').addEventListener('click', flash);
" id="fla" style="display: inline-block;
padding: 0.2em 0.1em;
font-size: 14px;
cursor: pointer;
height:4em;width:7em;
font-weight:bolder;font-size:3vw;
text-align: center;
text-decoration: none;
outline: none;
color: #fff;
background-color: #935cfb;
border: none;
border-radius: 30px;">Flash</button>
</body>
</html>
<script>
jQuery(function($) {
if (!('WebSocket' in window)) {
alert('Your browser does not support web sockets');
} else {
setup();
}
function setup() {
var host = 'ws://server_ip:81';
var socket = new WebSocket(host);
socket.binaryType = 'arraybuffer';
if (socket) {
socket.onopen = function() {
// Could add connection confirmation here
};
socket.onmessage = function(msg) {
var bytes = new Uint8Array(msg.data);
var binary = '';
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
var img = document.getElementById('live');
img.src = 'data:image/jpg;base64,' + window.btoa(binary);
};
socket.onclose = function() {
showServerResponse('The connection has been closed.');
};
}
}
});
function flash()
{
var btn = document.getElementById('fla')
var btnText = btn.textContent || btn.innerText;
if (btnText ==='Flash') https { btn.innerHTML = "Turn off "; sendText('1'); }
else { btn.innerHTML = "Flash"; sendText('0'); }
}
function sendText(data)
{
socket.send(data);
}
</script>
)=====";
void configCamera() {
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;
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
config.jpeg_quality = 10; //10-63 lower number means higher quality
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
}
void liveCam(uint8_t num) {
//capture a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Frame buffer could not be acquired");
return;
}
//replace this with your own function
webSocket.sendBIN(num, fb->buf, fb->len);
//return the frame buffer back to be reused
esp_camera_fb_return(fb);
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
switch (type) {
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED:
cam_num = num;
connected = true;
break;
case WStype_TEXT:
if (payload[0] == '0')
{
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
Serial.println("0");
}
else if (payload[0] == '1')
{
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
Serial.println("1");
}
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
break;
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
WiFi.begin("Galaxy F41CE38", "alen matthew");
Serial.println("");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
String IP = WiFi.localIP().toString();
Serial.print("IP address: " + IP);
index_html.replace("server_ip", IP);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
configCamera();
}
void http_resp() {
WiFiClient client = server.available();
if (client.connected() && client.available()) {
client.flush();
client.print(index_html);
client.stop();
}
}
void loop() {
http_resp();
webSocket.loop();
if (connected == true) {
liveCam(cam_num);
}
}