#include <Arduino.h>
#include "esp_camera.h"
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
HardwareSerial UNOSerial(2);
#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
#define LIGHT_PIN 4
const int PWMLightChannel = 4;
// Camera-related constants
camera_config_t config;
const char* ssid = "LLLLLLLLLLLLLL";
const char* password = "59615330";
IPAddress staticIP(192, 168, 1, 150);
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);
AsyncWebServer server(80);
AsyncWebSocket wsCamera("/Camera");
AsyncWebSocket wsData("/Data");
uint32_t cameraClientId = 0;
const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.container {
display: flex;
}
.video-container {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.data-container {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 20px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 40px;
height: 40px;
border-radius: 50%;
background: red;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 40px;
height: 40px;
border-radius: 50%;
background: red;
cursor: pointer;
}
</style>
</head>
<body class="noselect" style="background-color:white">
<div class="container">
<div class="video-container">
<img id="cameraImage" src="" style="width:400px;height:250px">
</div>
<div class="data-container">
<div id="dataDisplay" style="text-align: right;"></div>
<div>
<b>Light:</b>
<div class="slidecontainer">
<input type="range" min="0" max="255" value="0" class="slider" id="Light" oninput='sendButtonInput("Light", value)'>
</div>
</div>
</div>
</div>
<script>
const dataDisplay = document.getElementById("dataDisplay");
// Function to append data to the display element
function appendData(data) {
dataDisplay.innerText += data + "\n"; // Append the data and a line break
}
// Create a WebSocket connection for data
const dataSocket = new WebSocket("ws://" + location.host + "/Data");
// Handle WebSocket messages
dataSocket.onmessage = function (event) {
const receivedData = event.data;
appendData(receivedData);
}
// Function to send data to the server
function sendButtonInput(name, value) {
// Implement this function to send data to the server
// For example, you can use dataSocket.send() to send data to the Arduino
}
</script>
</body>
</html>
)HTMLHOMEPAGE";
void handleRoot(AsyncWebServerRequest *request) {
request->send_P(200, "text/html", htmlHomePage);
}
void handleNotFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "File Not Found");
}
void onDataWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
// Handle data WebSocket events
}
void onCameraWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
cameraClientId = client->id();
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
cameraClientId = 0;
break;
case WS_EVT_DATA:
// Handle WebSocket data here
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
default:
break;
}
}
void setupCamera()
{
Serial.begin(115200);
UNOSerial.begin(115200, SERIAL_8N1, 12, 13);
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_HD;
config.jpeg_quality = 15;
config.fb_count = 1;
// Camera initialization
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK)
{
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
}
void sendCameraPicture()
{
if (cameraClientId == 0)
{
return;
}
unsigned long startTime1 = millis();
// Capture a frame
camera_fb_t *fb = esp_camera_fb_get();
if (!fb)
{
Serial.println("Frame buffer could not be acquired");
return;
}
unsigned long startTime2 = millis();
wsCamera.binary(cameraClientId, fb->buf, fb->len);
esp_camera_fb_return(fb);
// Wait for the message to be delivered
while (true)
{
AsyncWebSocketClient *clientPointer = wsCamera.client(cameraClientId);
if (!clientPointer || !(clientPointer->queueIsFull()))
{
break;
}
}
unsigned long startTime3 = millis();
Serial.printf("Time taken Total: %d|%d|%d\n", startTime3 - startTime1, startTime2 - startTime1, startTime3 - startTime2);
}
void setup(void) {
Serial.begin(115200);
UNOSerial.begin(115200, SERIAL_8N1, 12, 13);
if (WiFi.config(staticIP, gateway, subnet) == false) {
Serial.println("Configuration failed.");
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("Connecting...\n\n");
}
Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP());
server.on("/", HTTP_GET, handleRoot);
server.onNotFound(handleNotFound);
// Set event handlers for both WebSockets
wsCamera.onEvent(onCameraWebSocketEvent);
wsData.onEvent(onDataWebSocketEvent);
server.addHandler(&wsCamera);
server.addHandler(&wsData);
server.begin();
Serial.println("HTTP server started");
setupCamera();
}
void loop() {
wsCamera.cleanupClients();
sendCameraPicture();
while (UNOSerial.available()) {
char c = UNOSerial.read();
Serial.write(c);
wsData.text(0, String(c));
}
// Handle data WebSocket events here
wsData.cleanupClients();
// Add your data processing logic for wsData here
}
YAY i finnaly got it, and the next thing is to fix the webstreaming idk why it gave me white sscreen i can see the empty box tho can you help check this code for me, and also the software serial doesnt work for me i take a look from another forum that has same problem "[HELP] out of ports interfacing GPS with ESP32CAM over serial - #7 by jremington"