Sentra — the Smartest DIY CCTV Camera

by The Spanner in Circuits > Cameras

1236 Views, 13 Favorites, 0 Comments

Sentra — the Smartest DIY CCTV Camera

Sentra.png

Hi Makers, I love building projects that combine engineering, embedded systems, and product design into something both useful and visually refined.

In this project, I created Sentra — The Smartest DIY CCTV Camera, a fully battery-powered smart surveillance system built around the ESP32-S3. Sentra combines live Wi-Fi video streaming, continuous SD card recording, motion detection, automatic night vision, real-time sound monitoring, and even robotic voice announcements into a compact custom-built device.

The entire enclosure and interface were designed in Autodesk Fusion 360 with a strong focus on clean aesthetics, portability, and a futuristic user experience. Alongside the hardware, I also developed a custom real-time dashboard that works directly in any browser — no apps, subscriptions, or cloud services required.

What makes this project special to me is that everything runs locally on the device itself. From motion analysis and adaptive infrared control to real-time voice synthesis and sensor monitoring, Sentra was designed to show how far modern DIY hardware can go when thoughtful engineering and creativity come together.

This project is my attempt to create a smart camera system that feels less like a typical DIY build and more like a real next-generation product.


Sponsored By NextPCB

Building a hardware project can get expensive, but NextPCB makes it easier for makers, startups, and engineers. Right now, you can get up to $200 OFF on professional turnkey PCB assembly for orders of 10 units or less.

From PCB manufacturing and component sourcing to full assembly and testing, NextPCB handles everything in one place with reliable quality and fast service. Whether you're building an IoT device, robotics project, or custom electronics product, this offer is a great way to prototype professionally while saving money.

Try it out using my link to unlock a huge discount and claim your $200 OFF on PCBA orders!

Supplies

5.png
6.png
7.png
24.png
25.png

Components

  1. DFRobot ESP32 S3 Camera
  2. Battery Charging Module
  3. DFRobot ESP32 S3 Spekar
  4. Rechargable Battery (3.6v)

Tools

  1. Soldring Iron
  2. Super Glue
  3. Screwdriver
  4. 3D Printer

CAD Design

Sentra 03.png
Sentra 02.png
Sentra 01.png

The first step of this project was designing the complete enclosure and internal structure of Sentra. I created all the parts from scratch in Autodesk Fusion 360, focusing on clean curves, compact dimensions, proper component clearances, and easy assembly.

Since this camera is designed to be portable and battery-powered, I wanted the body to feel minimal, modern, and product-like rather than looking like a typical DIY electronics project, while keeping the overall design slim and clean.

For inspiration and reference during the design process, I also took ideas from this excellent project by Mukesh Sankhla https://www.instructables.com/Build-a-Voice-Controlled-AI-Assistant-on-ESP32-Usi/

I highly recommend checking it out as well — it’s a beautifully designed and well-documented build.

3D Printing

1.png
2.png
3.png
4.png

Once the CAD design was completed, the next step was printing all the enclosure parts. The design consists of three main printed components:

  1. Main Housing
  2. Top Cover
  3. Button Extension

For this build, I chose a gray PLA filament because it gives the camera a clean and modern product-like appearance while still being easy to print with high dimensional accuracy. PLA is a good choice for achieving smooth surface quality and maintaining the tight tolerances needed for proper assembly.

Spekar Assembly

10.png
11.png

The next step was installing the speaker inside the enclosure. I first trimmed the speaker wires to a suitable length and added a little extra wire to make the final assembly easier and cleaner.

After that, I removed the adhesive backing from the speaker and carefully placed it into the dedicated mounting area inside the main housing. I applied a small amount of pressure to secure it properly in position.

Battery Assembly

8.png
9.png

The next step was installing the battery into the enclosure. First, I soldered two wires to the battery terminals to make the power connection easier during the final electronics assembly.

The top cover was already designed with a dedicated battery compartment in Autodesk Fusion 360, so the battery fits neatly into place without wasting internal space. After positioning it inside the slot, I used a small amount of glue to secure it firmly.

Charging Module Connection

Sentra connection.png
14.png
15.png
16.png

The next step was connecting the battery to the charging module. First, I soldered the battery wires to the correct positive and negative terminals on the module, making sure the polarity was connected properly to avoid damaging the circuit.

After that, I soldered another pair of wires to the 5V output terminals of the charging module. These output wires will later be used to power the main ESP32-S3 board inside Sentra.

System Architecture

Before diving into the code, it's important to understand how Sentra works internally.

The firmware is divided into multiple FreeRTOS tasks, allowing video streaming, motion detection, sensor monitoring, audio playback, and dashboard communication to run independently. This prevents one feature from slowing down another and keeps the entire system responsive.

xTaskCreatePinnedToCore(streamTask, "stream", 8192, nullptr, 5, nullptr, 0);
xTaskCreatePinnedToCore(sensorTask, "sensor", 6144, nullptr, 3, nullptr, 0);
xTaskCreatePinnedToCore(spkTask, "speaker", 6144, nullptr, 2, nullptr, 1);

Instead of running everything inside a single Arduino loop, each major subsystem gets its own dedicated task:

  1. Stream Task → Live video streaming
  2. Sensor Task → Motion detection, microphone, light sensor
  3. Speaker Task → Voice announcements and siren

This architecture allows Sentra to stream video while simultaneously recording footage, detecting motion, and playing alerts.

Wi-Fi and Network Configuration

The first thing the firmware does is connect to the local Wi-Fi network.

#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your PASS"

WiFi.begin(WIFI_SSID, WIFI_PASS);

while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}

Once connected, the ESP32-S3 receives an IP address that is used by the dashboard and video streaming system.

The dashboard is hosted online: https://thespannerio.github.io/Sentra/

Simply open the dashboard, enter the camera IP address, and connect. No app installation is required.

Camera Initialization

The camera is configured for JPEG image capture and optimized for streaming.

camera_config_t config;

config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 12;

config.fb_location = CAMERA_FB_IN_PSRAM;
config.fb_count = 2;

esp_camera_init(&config);

The OV3660 camera sensor compresses images directly into JPEG format before sending them to the ESP32-S3.

This provides several advantages:

  1. Lower memory usage
  2. Faster Wi-Fi streaming
  3. Reduced CPU load
  4. Better battery life

Using PSRAM allows larger frame buffers without consuming valuable internal RAM.

Live Video Streaming

One of the core features of Sentra is its ability to stream live video directly over Wi-Fi. The ESP32-S3 continuously captures JPEG images from the camera and serves them as an MJPEG stream that can be viewed from any web browser.

camera_fb_t *fb = esp_camera_fb_get();

if (!fb) {
return;
}

client.write(fb->buf, fb->len);

esp_camera_fb_return(fb);

The camera captures a frame and stores it in a frame buffer. The firmware then sends the JPEG image over the network to connected clients before releasing the buffer back to the camera driver for the next capture.

Because the camera outputs JPEG images directly, the ESP32-S3 does not need to perform additional image compression, which significantly reduces CPU usage and memory consumption.

Why MJPEG?

MJPEG streaming is lightweight and works on almost any device without special software. Each frame is transmitted as an individual JPEG image, making it ideal for microcontrollers and embedded systems.

Benefits
  1. Real-time live video monitoring
  2. Low latency
  3. Works in any modern browser
  4. No mobile app required
  5. Optimized for ESP32-S3 hardware

This streaming system forms the foundation of Sentra, allowing users to monitor their surroundings remotely through the online dashboard.

Motion Detection Engine

To make Sentra more than just a camera, We implemented a lightweight motion detection system that runs entirely on the ESP32-S3 without requiring cloud processing or dedicated AI hardware.

The firmware continuously compares consecutive camera frames and calculates a motion score based on the amount of change detected between them.

float motion = motionCalc(fb->buf, fb->len);

runEngine(motion, lux, sound);

if (motion >= THRESH_ALERT)
{
evLog("ALERT: High motion");
qSpk(BEEP_ALERT);
}
How It Works

Each time a new frame is captured, the firmware compares it with the previous frame. If significant differences are detected, the motion score increases.

Unlike traditional computer vision systems that decode and analyze every pixel, Sentra uses a lightweight JPEG-based comparison technique that dramatically reduces processor load while still providing reliable motion detection.

float motionCalc(const uint8_t* cur, size_t clen)
{
long diff = 0;

for (int i = 0; i < N; i++)
{
int d = (int)cur[idx] - (int)g_prev[idx];
diff += abs(d);
}

float p = (float)diff / 80.0f;

return p > 100.0f ? 100.0f : p;
}
Why This Approach?

Most DIY security cameras rely on cloud AI services or powerful processors to detect movement. While effective, those methods increase complexity, cost, and power consumption.

By using a lightweight frame-difference algorithm, Sentra can:

  1. Detect movement in real time
  2. Run entirely on the ESP32-S3
  3. Maintain smooth video streaming
  4. Reduce CPU usage
  5. Extend battery life
Motion-Based Actions

When motion exceeds predefined thresholds, Sentra can automatically:

  1. Trigger motion alerts
  2. Play voice announcements
  3. Activate the siren
  4. Record events
  5. Update the dashboard in real time

This transforms Sentra from a simple streaming camera into an intelligent smart surveillance system capable of responding to activity automatically.

Automatic Night Vision System

To ensure Sentra can operate reliably during both day and night, We implemented an automatic night vision system using the LTR-308 ambient light sensor and an infrared illumination LED.

The firmware continuously monitors the surrounding light level and automatically adjusts the IR brightness depending on how dark the environment becomes.

if (lux < NIGHT_LUX)
{
g_night = true;
}

if (lux > NIGHT_LUX * 1.5f)
{
g_night = false;
}
How It Works

The LTR-308 sensor constantly measures ambient light levels in lux. When the measured brightness falls below the predefined threshold, Sentra automatically switches to night mode.

Once night mode is active, the infrared LED turns on and provides additional illumination for the camera.

if (g_autoIR)
{
int duty = g_night ? luxToDuty(lux) : 0;

if (duty != g_irDuty)
{
irSetDuty(duty);
}
}
Smart IR Brightness Control

Instead of simply turning the IR LED fully ON or OFF, Sentra automatically adjusts the brightness based on ambient lighting conditions.

int luxToDuty(float lux)
{
if (lux >= NIGHT_LUX * 1.5f)
return 0;

if (lux <= 5.0f)
return IR_MAX_DUTY;

float ratio =
(NIGHT_LUX * 1.5f - lux) /
(NIGHT_LUX * 1.5f - 5.0f);

return (int)(ratio * IR_MAX_DUTY);
}

As darkness increases:

  1. IR brightness increases automatically
  2. Camera visibility improves
  3. Power consumption remains optimized

This creates a much smoother transition between day and night compared to simple threshold-based systems.

PWM-Based IR Control

The infrared LED brightness is controlled using the ESP32-S3 hardware PWM controller.

void irSetDuty(int duty)
{
ledcWrite(PIN_IR, duty);

g_irDuty = duty;
g_irOn = (duty > 0);
}

Using PWM allows Sentra to precisely control the IR intensity rather than operating at full brightness all the time.

This allows Sentra to operate continuously throughout the day while automatically adapting to changing lighting conditions.

Sound Monitoring System

In addition to video surveillance, Sentra also monitors the surrounding audio environment using the onboard PDM microphone. This allows the system to detect changes in ambient noise levels and provide real-time sound monitoring through the dashboard.

The microphone continuously samples audio data while the firmware calculates a stable sound intensity value that can be displayed and used by the system.

float readMicLevel()
{
const int N = 512;

int16_t buf[N];

size_t got =
i2s.readBytes((char*)buf, N * 2);

if (got < 2)
return g_sndSmooth;
How It Works

The ESP32-S3 reads audio samples from the PDM microphone using its hardware I2S peripheral. These samples are collected in a buffer and processed to determine the overall sound level.

Unlike a simple peak detector, Sentra uses RMS (Root Mean Square) calculations to provide a more accurate representation of actual sound intensity.

double sum = 0.0;

for (int i = 0; i < n; i++)
{
sum +=
(double)buf[i] *
(double)buf[i];
}

float rms =
sqrt(sum / (double)n);
Why RMS?

RMS measurement is commonly used in professional audio systems because it reflects the actual energy of a sound signal rather than just measuring peak values.

This produces more realistic and stable sound level readings.

Noise Smoothing

Raw microphone data can fluctuate rapidly, causing unstable readings. To solve this, Sentra applies exponential smoothing before updating the dashboard.

g_sndSmooth =
g_sndSmooth * 0.75f +
pct * 0.25f;

return g_sndSmooth;

This filtering technique helps eliminate sudden spikes while keeping the readings responsive to real environmental changes.

Dashboard Integration

The processed sound level is continuously sent to the dashboard, allowing users to monitor environmental activity in real time.

float sound =
readMicLevel();

runEngine(
motion,
lux,
sound
);

The sound level bar updates automatically and provides a quick visual indication of noise activity around the camera.

By combining video monitoring with sound analysis, Sentra becomes more aware of its surroundings and provides a richer monitoring experience than a camera alone.

Voice Announcements & Smart Audio Engine

One of the most unique features of Sentra is its built-in voice announcement system. Instead of using prerecorded audio files or cloud-based text-to-speech services, the ESP32-S3 generates speech-like audio entirely in real time using mathematical waveform synthesis.

This means Sentra can produce alerts and announcements completely offline while remaining lightweight and responsive.

Audio Task System

To prevent audio playback from affecting video streaming and motion detection, all sound generation runs inside a dedicated FreeRTOS task.

xTaskCreatePinnedToCore(
spkTask,
"speaker",
6144,
nullptr,
2,
nullptr,
1
);

Whenever an announcement or alert is triggered, it is placed into a queue for processing.

qSpk(
SPK_ANNOUNCE,
"Motion detected"
);

This keeps the system responsive even while audio is playing.

Real-Time Speech Generation

The announcement engine converts text into a unique robotic voice using generated waveforms.

float f0 =
120.0f +
(float)(cs % 120);

float f1 = f0 * 3.0f;
float f2 = f0 * 5.0f;

Each word receives its own calculated frequency, allowing different words to sound distinct while maintaining a consistent robotic voice style.

Unlike traditional TTS systems:

  1. No audio files are stored
  2. No internet connection is required
  3. No external APIs are used
  4. Everything runs directly on the ESP32-S3
Sound Synthesis

The firmware generates audio samples mathematically and writes them directly to the speaker.

float s =
(2.0f*p0-1.0f)*0.55f +
(2.0f*p1-1.0f)*0.28f +
(2.0f*p2-1.0f)*0.17f;

pcm[pos++] =
(int16_t)(
s * env * 22000.0f
);

This creates a distinctive robotic voice effect that sounds completely different from simple beeps or tones.

Built-In Alert Sounds

In addition to speech, Sentra can generate several alert sounds:

case BEEP_BOOT:
doBeepBoot();
break;

case BEEP_ALERT:
doBeepAlert();
break;

case BEEP_MOTION:
doBeepMotion();
break;

These audio cues help quickly identify different system events.

Siren Mode

For security alerts, Sentra includes a powerful siren function.

float f =
800.0f +
400.0f *
(float)i /
(float)N;

The siren performs a frequency sweep from 800 Hz to 1200 Hz over several seconds, producing a loud warning sound that can easily be heard across a room.

By generating all audio directly on the ESP32-S3, Sentra delivers advanced voice and alert capabilities while remaining compact, efficient, and completely self-contained.

Battery Monitoring System

Since Sentra is designed to be completely portable, battery monitoring plays an important role in the system. The firmware continuously measures the battery voltage and converts it into an easy-to-understand percentage value that is displayed on the dashboard.

This allows users to monitor the remaining battery life in real time and recharge the device before it runs out of power.

Reading Battery Voltage

The battery voltage is measured using the ESP32-S3's ADC through a voltage divider connected to GPIO44.

#define BAT_PIN 44
#define BAT_DIV 0.3197f

float v =
(float)(sum / 64) /
4095.0f *
3.3f /
BAT_DIV;

The voltage divider safely reduces the battery voltage to a level that can be measured by the ESP32-S3 ADC.

Noise Reduction

To improve accuracy, the firmware takes multiple readings and averages them together.

long sum = 0;

for (int i = 0; i < 64; i++)
{
sum += analogRead(BAT_PIN);
delayMicroseconds(200);
}

This helps eliminate ADC noise and produces much more stable voltage measurements.

Battery Percentage Calculation

Instead of using a simple linear calculation, Sentra uses a LiPo discharge curve approximation to provide more realistic battery percentages.

if (v >= 4.15f)
p = 90 +
(v - 4.15f) /
0.05f * 10;

else if (v >= 3.90f)
p = 60 +
(v - 3.90f) /
0.25f * 30;

else if (v >= 3.70f)
p = 30 +
(v - 3.70f) /
0.20f * 30;

This method more closely matches how lithium batteries actually discharge, resulting in more accurate battery readings throughout the entire charge cycle.

Dashboard Integration

The calculated battery percentage and voltage are continuously updated on the dashboard.

g_vbat = v;
g_batPct = p;

Users can instantly check:

  1. Battery percentage
  2. Actual battery voltage
  3. Remaining operating time

directly from the web interface.

Why This Matters

Because Sentra is completely battery-powered, knowing the battery status is essential for reliable operation. Real-time battery monitoring helps prevent unexpected shutdowns and makes the camera much more practical for portable deployments.

This battery management system allows Sentra to operate as a truly portable smart CCTV camera without sacrificing usability.

SD Card Recording Engine

While live streaming is useful for real-time monitoring, Sentra also records footage directly to an SD card for later review. Every frame captured by the camera can be stored as part of an AVI video file, allowing the system to function as a complete standalone CCTV solution.

Unlike many DIY camera projects that only provide live streaming, Sentra combines both live viewing and local video recording simultaneously.

Creating the Recording File

When recording starts, the firmware creates a new AVI file on the SD card and writes the required video headers.

startAVI();

g_recording = true;
g_aviFr = 0;

The AVI format was chosen because it is widely supported and can be opened directly on most computers without requiring special software.

Saving Camera Frames

Every time a new frame is captured, it is written directly to the AVI file.

g_avi.write(
fb->buf,
fb->len
);

g_aviFr++;

Each frame is stored as a JPEG image inside the AVI container, creating a lightweight MJPEG video file.

Recording While Streaming

One of the advantages of the multi-task architecture is that recording happens alongside live video streaming.

camera_fb_t* fb =
esp_camera_fb_get();

recFrame(
fb->buf,
fb->len
);

esp_camera_fb_return(fb);

This allows users to:

  1. View live footage
  2. Record footage
  3. Monitor sensors

all at the same time without interrupting one another.

Automatic File Management

To prevent the SD card from filling up with extremely large files, Sentra automatically creates a new recording once the current file reaches a predefined size.

if (
g_avi.size() >
(uint32_t)
SD_ROLL_MB *
1024UL *
1024UL
)
{
stopAVI();
startAVI();
}

By default, a new AVI file is created every 400 MB.

This makes:

  1. File management easier
  2. Playback smoother
  3. Data transfer faster

while avoiding extremely large recordings.

Video Index Generation

When recording stops, Sentra finalizes the AVI file and generates the required index information.

aviClose(
g_avi,
g_aviFr,
STREAM_FPS
);

This ensures the video can be played back correctly in standard media players.

With this system, Sentra functions as a true standalone security camera, capable of recording footage locally while still providing live remote access through the dashboard.

Web Server & Dashboard Communication

To make Sentra easy to use, We built a lightweight web server directly on the ESP32-S3. This server acts as the bridge between the hardware and the online dashboard, allowing real-time monitoring and control from any device on the network.

Instead of requiring a dedicated mobile application, all communication happens through simple web requests, making the system platform-independent and easy to access.

Creating the Web Server

The firmware creates an HTTP server that listens for incoming requests from the dashboard.

WebServer server(80);

server.begin();

Once the server starts, it becomes responsible for handling live video streams, sensor data requests, and user commands.

Live Video Endpoint

The camera feed is delivered through a dedicated streaming endpoint.

server.on(
"/stream",
HTTP_GET,
handleStream
);

Whenever the dashboard requests /stream, the ESP32-S3 begins transmitting MJPEG frames in real time.

This is what powers the live video feed visible in the browser.

Sensor Data Endpoint

The dashboard also needs access to real-time sensor information.

server.on(
"/data",
HTTP_GET,
handleData
);

This endpoint provides information such as:

  1. Motion level
  2. Battery percentage
  3. Sound intensity
  4. Ambient light level
  5. SD card usage
  6. Recording status
  7. Night vision status

The dashboard continuously polls this endpoint to keep everything updated.

Control Endpoint

User actions from the dashboard are sent back to the ESP32-S3 through a control endpoint.

server.on(
"/control",
HTTP_GET,
handleControl
);

This endpoint is responsible for handling commands such as:

  1. Start recording
  2. Stop recording
  3. Trigger siren
  4. Play announcements
  5. Toggle IR mode
Processing Commands

When a command arrives, the firmware updates the corresponding subsystem.

if (cmd == "siren")
{
qSpk(BEEP_SIREN);
}

if (cmd == "record")
{
startAVI();
}

This creates a direct connection between the dashboard controls and the hardware running inside Sentra.

Continuous Communication

The server continuously processes incoming requests inside the main loop.

void loop()
{
server.handleClient();

delay(1);
}

This allows the dashboard to remain responsive while other tasks such as streaming, motion detection, recording, and audio playback continue running in the background.

Why This Approach?

Using a built-in web server offers several advantages:

  1. No mobile application required
  2. Cross-platform compatibility
  3. Simple browser access
  4. Lightweight communication
  5. Easy customization
  6. Works on phones, tablets, and computers

By exposing simple web endpoints, the ESP32-S3 can communicate seamlessly with the online dashboard while remaining lightweight and efficient.

Dashboard Architecture

While the ESP32-S3 handles video streaming, recording, motion detection, and sensor processing, We wanted the user experience to feel modern, intuitive, and accessible from any device. To achieve this, We developed a completely custom web dashboard that acts as the control center for Sentra.

Unlike traditional applications, the dashboard is built as a single self-contained HTML file with no external frameworks, no installation process, and no dependencies beyond the browser itself. This makes deployment incredibly simple while keeping the system lightweight and fast.

Why a Web Dashboard?

Instead of creating a dedicated Android or iOS application, We chose a browser-based approach because it offers several advantages:

  1. Works on phones, tablets, and computers
  2. No app installation required
  3. Platform independent
  4. Easy to update and maintain
  5. Accessible from any modern browser

The dashboard is hosted online and can be accessed here: https://thespannerio.github.io/Sentra/

System Architecture

The dashboard communicates directly with the ESP32-S3 over Wi-Fi using simple HTTP requests.

┌─────────────┐
│ Dashboard │
│ (Browser) │
└──────┬──────┘
│ HTTP Requests
┌─────────────┐
│ ESP32-S3 │
│ Sentra │
└─────────────┘
├── Live Video Stream
├── Motion Detection
├── SD Recording
├── Night Vision
├── Audio Engine
└── Sensor Monitoring

The dashboard continuously receives live data from the camera while also sending user commands such as:

  1. Start or stop recording
  2. Activate the siren
  3. Trigger voice announcements
  4. Control night vision
  5. Monitor system status
Single State Architecture

One design decision I am particularly proud of is using a centralized state-driven architecture.

let S = {
motion:0,
activity:'idle',
lux:500,
sound:0,
recording:false,
batPct:0
};

Every piece of information displayed on the screen comes from this single state object.

When new data arrives from the ESP32-S3:

S = {
...S,
...await r.json()
};

renderUI();

The dashboard updates automatically.

This approach keeps the interface organized, predictable, and easy to maintain while ensuring every widget always displays the latest device status.

UI Design & Glassmorphism Interface

Since Sentra is designed to feel like a modern smart security product rather than a traditional DIY project, We spent considerable time designing a clean, responsive, and visually polished user interface.

The entire dashboard was built using plain HTML, CSS, and JavaScript without relying on external UI frameworks. This keeps the dashboard lightweight while providing complete control over the design and user experience.

Design Philosophy

Our goal was to create an interface that feels modern, professional, and easy to understand at a glance.

The design takes inspiration from modern operating systems and smart home applications, featuring:

  1. Clean typography
  2. Soft shadows
  3. Rounded corners
  4. Glassmorphism effects
  5. Smooth animations
  6. Responsive layouts

This helps make even complex information feel approachable and organized.

Design Tokens & Theme System

To keep the design consistent throughout the dashboard, We created a centralized theme system using CSS variables.

:root {
--bg: #F2F4F7;

--blue: #007AFF;
--green: #34C759;
--amber: #FF9F0A;
--red: #FF3B30;

--r16:16px;
--r24:24px;

--shadow-sm:
0 2px 8px rgba(0,0,0,0.05);
}

Instead of assigning random colors throughout the code, every component references these variables. This makes future customization and maintenance significantly easier.

Creating Depth Without Images

Rather than using background images, the dashboard creates depth using layered gradients.

body::before {
background-image:
radial-gradient(
ellipse 80% 60%
at 20% -10%,
rgba(0,122,255,0.04),
transparent 60%
);
}

These subtle gradients add visual interest while keeping the interface lightweight and fast.

Glassmorphism Cards

One of the most distinctive elements of the dashboard is the glass-style card design.

.card {
background:
rgba(255,255,255,0.78);

backdrop-filter:
blur(24px)
saturate(1.8);

border:
1px solid
rgba(255,255,255,0.9);
}

This combination creates the frosted-glass appearance seen throughout the dashboard.

The effect is achieved using:

  1. Semi-transparent backgrounds
  2. Background blur
  3. Saturation enhancement
  4. Soft shadows
  5. Thin highlight borders

Together these elements create a modern premium appearance without requiring any images.

Smooth Animations

To improve the overall feel of the interface, custom animation curves are used throughout the dashboard.

:root {
--ease:
cubic-bezier(
0.22,
1,
0.36,
1
);
}

These transitions are applied to:

  1. Buttons
  2. Toggles
  3. Status indicators
  4. Dashboard cards
  5. Progress animations

The result feels noticeably smoother and more refined than default browser animations.

Live Video Interface & HUD Overlay

The live camera feed is the centerpiece of the Sentra dashboard. Rather than simply displaying a raw video stream, We wanted the experience to feel closer to a professional security system, so We designed a custom HUD (Heads-Up Display) overlay that provides important information directly on top of the video feed.

This allows users to quickly understand the camera's status without needing to look away from the live stream.

Live Camera View

The dashboard receives an MJPEG stream directly from the ESP32-S3 and displays it inside a dedicated viewport.

img.src =
'http://' +
IP +
'/stream';

As new frames arrive, the browser automatically updates the image, creating a smooth live video feed with minimal latency.

HUD Overlay System

Instead of placing all information in separate panels, key indicators are displayed directly on top of the video.

.hud {
position:absolute;
inset:0;

pointer-events:none;

display:none;
}

The overlay sits above the camera stream while remaining completely transparent to user interactions.

Camera Frame Indicators

To create a more professional surveillance-style appearance, custom corner markers are rendered around the viewport.

.hud-corner.tl {
top:12px;
left:12px;

border-top:
1.5px solid
rgba(255,255,255,0.22);

border-left:
1.5px solid
rgba(255,255,255,0.22);
}

These subtle corner accents help frame the camera image without distracting from the content itself.

Motion Detection Status

One of the most important HUD elements is the activity indicator.

.hud-detect.motion {
background:
rgba(255,159,10,0.18);

border-color:
rgba(255,159,10,0.4);

color:#FFD060;
}

The badge automatically changes depending on the system state:

  1. Idle
  2. Motion Detected
  3. Person Activity
  4. Alert State

This allows users to immediately understand what the camera is seeing.

Dynamic Status Updates

The activity badge updates automatically whenever new sensor data arrives.

const act =
S.activity ||
'idle';

abt.className =
'hud-detect' +
(act !== 'idle'
? ' ' + act
: '');

This creates a responsive interface where visual feedback changes in real time.

Recording Indicators

When recording is active, visual indicators appear directly on the camera feed.

if (S.recording)
{
showREC();
}

This makes it immediately obvious when footage is being saved to the SD card.

Real-Time Camera Information

The HUD continuously updates important system information such as:

  1. Motion activity
  2. Recording status
  3. Detection state
  4. Night vision mode
  5. Camera status

All of this information is displayed without blocking or obscuring the live video feed.

Why Use a HUD?

Traditional dashboards often force users to switch between multiple panels to find information.

The HUD approach keeps the most important details directly within the camera view itself, making monitoring faster and more intuitive.

This design was inspired by professional CCTV systems, security monitoring software, and modern surveillance interfaces.

Combined with the rest of the dashboard, the HUD helps transform Sentra from a simple DIY camera into a polished smart surveillance platform.

Real-Time Monitoring Widgets

While the live camera feed provides visual awareness, We also wanted users to have instant access to important system information. To achieve this, the dashboard includes a collection of real-time monitoring widgets that continuously display the health and status of the entire system.

These widgets update automatically and provide a quick overview of what is happening inside Sentra without requiring users to navigate through menus or settings pages.

Motion Activity Indicator

One of the most important widgets is the motion activity monitor.

const m =
Math.round(
S.motion
);

const mc =
m > 70 ?
'var(--red)' :
m > 40 ?
'var(--amber)' :
'var(--blue)';

The dashboard continuously receives motion data from the ESP32-S3 and visualizes it using color-coded indicators.

Motion levels are displayed as:

  1. Blue → Low Activity
  2. Amber → Moderate Activity
  3. Red → High Activity

This allows users to instantly understand the level of activity detected by the camera.

Circular Motion Gauge

To make motion information easier to interpret, I created an animated circular progress ring.

const C = 282;

const off =
C -
(m / 100) * C;

$('rp')
.style
.strokeDashoffset =
off;

As motion increases, the ring fills smoothly, creating a visually intuitive representation of activity levels.

Ambient Light Monitoring

The dashboard continuously displays light levels measured by the LTR-308 sensor.

const ld =
lux < 10 ?
'Night — very dark' :

lux < 50 ?
'Night — dim' :

lux < 150 ?
'Dusk / indoor' :

'Full daylight';

Instead of only showing a raw lux value, the dashboard translates the reading into human-friendly descriptions.

This helps users quickly understand environmental lighting conditions.

Sound Level Monitoring

Audio activity is displayed using a dedicated sound-level indicator.

sound =
Math.round(
S.sound
);

The widget updates in real time and reflects changes detected by the onboard microphone.

This provides an additional layer of environmental awareness beyond video monitoring.

Battery Status Widget

Because Sentra is battery-powered, battery monitoring is displayed prominently on the dashboard.

$('batPct')
.textContent =
S.batPct +
'%';

The battery widget displays:

  1. Battery percentage
  2. Voltage level
  3. Charging status
  4. Remaining power

This allows users to quickly determine when the device needs recharging.

SD Card Storage Monitoring

The dashboard also monitors available storage space.

$('sd')
.textContent =
S.sdFreeGB +
' GB Free';

Users can instantly see:

  1. Remaining storage
  2. Total capacity
  3. Recording availability

without needing to remove the SD card.

Device Controls & Voice Announcements

Beyond monitoring, Sentra also allows users to actively interact with the camera through a collection of real-time controls. These controls are integrated directly into the dashboard, making it possible to manage recordings, activate alerts, control night vision, and broadcast voice announcements from any connected device.

The goal was to make Sentra feel like a complete smart security system rather than just a passive monitoring camera.

Real-Time Control System

Every button and toggle on the dashboard communicates directly with the ESP32-S3 through the control API.

async function cmd(c)
{
const r =
await fetch(
'http://' +
IP +
'/control?cmd=' +
encodeURIComponent(c)
);
}

Whenever a user presses a button, a command is sent instantly to the device.

This allows the dashboard to control hardware features in real time.

Recording Controls

The dashboard includes controls for managing video recording.

cmd('record_on');

cmd('record_off');

Users can start or stop recording directly from the dashboard without needing physical access to the camera.

This is especially useful when monitoring the camera remotely.

Siren Activation

For security alerts, Sentra includes a built-in siren mode.

cmd('siren');

When triggered, the ESP32-S3 generates a loud frequency sweep through the onboard speaker.

This can be used to:

  1. Deter intruders
  2. Draw attention
  3. Respond to motion events
  4. Test the audio system
Night Vision Controls

The dashboard also provides manual and automatic night vision options.

cmd('ir_on');

cmd('ir_off');

cmd('ir_auto');

Users can:

  1. Force IR ON
  2. Force IR OFF
  3. Enable automatic mode

Automatic mode allows Sentra to manage infrared illumination based on ambient light levels.

Voice Announcement System

One of my favorite features is the announcement panel.

Users can type a custom message directly into the dashboard and have Sentra speak it through the onboard speaker.

sendAnn();

The message is sent to the ESP32-S3 where it is converted into robotic speech using the real-time audio engine described earlier.

No internet connection, cloud service, or audio files are required.

Character Validation

To ensure reliable operation, the dashboard validates message length before transmission.

const rem =
95 -
textarea.value.length;

charCount.textContent =
rem + ' left';

This mirrors the firmware limitations and prevents invalid announcements from being sent.

Quick Announcement Buttons

For convenience, several pre-configured announcement buttons are included.

qa("Motion Detected");

qa("Recording Enabled");

qa("Stay Away");

These allow users to trigger common messages with a single click.

Demo Mode Simulation Engine

One of the most unique features of the Sentra dashboard is its built-in Demo Mode. We wanted anyone visiting the dashboard to be able to explore the interface and test all its features even without owning the hardware.

Instead of displaying static placeholder values, the dashboard generates a fully simulated camera system that behaves like a real Sentra device.

Why Demo Mode?

Normally, testing a dashboard requires:

  1. A powered camera
  2. Wi-Fi connection
  3. Active sensors
  4. Live video stream

With Demo Mode, none of these are required.

Users can immediately explore the dashboard and experience how the system behaves in real-world scenarios.

Scenario-Based Simulation

Rather than generating completely random values, the simulator follows predefined scenarios that mimic real activity.

const SC = [
{
act:'idle',
dur:7000
},
{
act:'motion',
dur:5000
},
{
act:'person',
dur:4500
}
];

These scenarios automatically cycle through:

  1. Idle monitoring
  2. Motion events
  3. Person detection
  4. Low-light conditions
  5. Alert situations

This creates a much more realistic demonstration experience.

Simulated Sensor Data

The simulator continuously generates realistic values for:

S.motion
S.lux
S.sound
S.batPct
S.activity

Every value updates automatically, just like it would on a real device.

The dashboard doesn't know whether the data is coming from the ESP32-S3 or the simulator — it simply displays the current system state.

Smooth Sensor Transitions

To make the simulation feel natural, sensor values are gradually updated instead of jumping abruptly.

S.motion =
S.motion +
(dTm - S.motion)
* 0.38;

S.lux =
S.lux +
(dLux - S.lux)
* 0.22;

This creates realistic transitions that resemble actual sensor behavior.

Simulated Battery Drain

The demo system even simulates battery usage.

bv -= 0.00012;

if (bv < 3.0)
{
bv = 4.2;
}

As time passes:

  1. Battery voltage decreases
  2. Battery percentage updates
  3. Dashboard widgets react accordingly

Once the battery reaches a low level, it automatically resets and begins a new cycle.

Procedural Camera Feed

Perhaps the most impressive part of Demo Mode is the simulated camera feed.

Instead of using prerecorded video files, the dashboard generates a live surveillance scene directly inside the browser.

const id =
c.createImageData(
W,
H
);

The system dynamically creates:

  1. Camera noise
  2. Motion effects
  3. Simulated subjects
  4. Night vision effects
  5. Recording overlays
  6. Timestamps

All in real time.

Simulated Motion Events

When activity increases, moving objects are generated inside the virtual camera scene.

if (ml > .1)
{
blobs.push({
x:R(.1,.85),
y:R(.3,.58)
});
}

These moving shapes create the appearance of people or objects passing through the camera's field of view.

As motion increases, more simulated activity appears.

Night Vision Simulation

The demo system also reproduces night-time operation.

const night =
S.ir ||
S.lux < 50;

When the environment becomes dark:

  1. Night mode activates
  2. IR indicators appear
  3. Camera noise changes
  4. A realistic surveillance-style effect is applied

This helps demonstrate exactly how Sentra behaves after sunset.

Using the Same Dashboard Logic

One of the biggest advantages of the simulator is that it uses the exact same dashboard code as the real hardware.

renderUI();

The only difference is where the data comes from:

  1. Real Camera → ESP32-S3
  2. Demo Mode → Simulator

Everything else remains identical.

This ensures the demo accurately represents the behavior of the actual device.

Final Dashboard Experience & System Integration

At this point, all the individual components of Sentra come together to form a complete smart surveillance system. While each feature is useful on its own, the real power of the project comes from how seamlessly the hardware, firmware, and dashboard work together.

Bringing Everything Together

The ESP32-S3 acts as the brain of the system, continuously managing multiple tasks at the same time:

  1. Live video streaming
  2. Motion detection
  3. Automatic night vision
  4. Sound monitoring
  5. SD card recording
  6. Battery management
  7. Voice announcements
  8. Dashboard communication

All of this runs simultaneously while maintaining smooth performance and low power consumption.

End-to-End Data Flow

The complete system follows a simple but powerful workflow:

Camera & Sensors
ESP32-S3 Firmware
├── Motion Detection
├── Audio Processing
├── Night Vision Logic
├── Battery Monitoring
└── SD Recording
Web Server API
Sentra Dashboard
Real-Time Monitoring & Device Control

Every sensor reading, motion event, and system status update is processed by the ESP32-S3 and instantly reflected on the dashboard.

Likewise, every user action from the dashboard is transmitted back to the device, creating a fully interactive monitoring experience.

Configure Code

Code 01.png
Sentra Github Repositorie

Before uploading the code, you need to configure your Wi-Fi credentials and timezone inside the source Code. Simply replace the placeholder values with your own Wi-Fi network name and password:

#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Pass"
#define TZ_OFFSET_SEC -28800 // UTC-8 Pacific Standard Time (PST)

The timezone value is used for timestamps, recordings, and system time synchronization. You can change it depending on your region.

Uploading Code

Before uploading, make sure the following board settings are selected correctly inside the Arduino IDE:

  1. Board: ESP32S3 Dev Module
  2. PSRAM: OPI PSRAM
  3. Flash Size: 16MB (128Mb)
  4. Partition Scheme: Huge APP (3MB No OTA / 1MB SPIFFS)
  5. USB CDC On Boot: Enabled
  6. CPU Frequency: 240 MHz
  7. Upload Speed: 921600

The PSRAM and Flash Size settings are especially important because Sentra uses large buffers for video streaming, SD recording, and real-time processing. Incorrect settings may cause crashes, boot loops, or camera initialization failures.

Once everything is configured, connect the ESP32-S3 board using a USB cable, select the correct COM port, and upload the code. After flashing successfully, open the Serial Monitor to view the device IP address and system status.

Control Dashboard

Sentra Dashboard.png
Sentra Dashboard

Simply open the dashboard, enter the camera's IP address, and connect instantly. The interface works seamlessly across smartphones, tablets, and desktops, giving Sentra a polished and professional user experience.

You can view the live camera feed and monitor important information such as motion activity, battery level, ambient light, sound level, recording status, SD card usage, and night vision status in real time.

The dashboard also provides quick access to features like recording control, voice announcements, siren mode, and infrared lighting, making it easy to manage the camera from anywhere on your local network.

ESP32 S3 Camera Assembly

12.png
13.png

The next step was installing the ESP32-S3 camera board into the main housing. I placed the board into the dedicated mounting position, and after positioning the board, I connected the speaker using its JST connector

The enclosure was designed to support standard screw mounting using 4 small screws for a secure installation. Since I did not have the screws available at the moment, I used a small amount of super glue to hold the board carefully in place for now.

Charging Module Assembly

17.png
19.png
18.png

After preparing the charging module earlier, I carefully placed the module into its dedicated position and aligned the USB Type-C connector with the cutout on the side of the housing so the camera can be charged easily from outside.

Once the module was positioned properly, I connected the two 5V output wires from the charging module to the main board’s power input terminal, making sure the polarity was correct before powering the system.

Button Extension Assembly

20.png
21.png

Now installing the small button extension piece. Since the ESP32-S3 board’s onboard button sits inside the enclosure, I designed this separate extension part to make it accessible from outside the case.

I simply aligned the printed button extension with the side opening and inserted it into its dedicated slot on the top cover. Once assembled, it presses directly against the internal push button, allowing easy access without opening the enclosure.

Final Assembly

22.png
23.png

The final step is closing the enclosure and completing the assembly. I carefully aligned the top cover with the main housing, making sure the camera lens, button extension, and internal wiring were positioned properly before closing the case. To secure everything firmly together, I used 3 screws from the back side of the enclosure.

Testing

Before using Sentra, fully charge the battery through the USB Type-C port. Once the battery is charged, the camera is ready to use.

After startup, open the control dashboard in your browser using the ESP32-S3 IP address to access the live camera feed and all smart features.

Since Sentra is completely battery-powered and compact, you can easily carry it anywhere or mount it on a wall, desk, shelf, or any location you want to monitor. During testing, I verified live video streaming, SD card recording, motion detection, automatic night vision, sound monitoring, voice announcements, and dashboard controls to ensure everything worked smoothly together.

Seeing the entire system finally operate as a complete smart camera felt incredibly satisfying and really brought the whole project to life.

Conclusion

Building Sentra was a really fun and rewarding experience for me. I wanted to create a DIY CCTV camera that not only works well, but also feels modern, portable, and polished. From designing the enclosure in Autodesk Fusion 360 to building the dashboard and integrating all the electronics, every part of this project was designed and assembled from scratch.

What I enjoyed most was seeing all the different features come together into one compact device — live video streaming, motion detection, automatic night vision, sound monitoring, SD card recording, and even voice announcements, all running on a battery-powered ESP32-S3 system.

This project also helped me learn a lot about embedded systems, product design, and real-time software optimization. It showed me how powerful and capable small development boards can be when combined with creativity and careful design.

I hope this project inspires others to build their own smart devices and experiment with DIY technology.

Thank you for checking out Sentra!