Initial design: ESP32-S3 presence sensor with camera, mmWave, PIR, temp/humidity, light

- KiCad schematic and PCB layout (45x35mm board)
- Full BOM with JLCPCB part numbers
- ESPHome firmware configuration
- 3D-printable wall-mount enclosure (OpenSCAD + STL)
- Pin mapping and power budget documentation
This commit is contained in:
root
2026-03-29 12:53:54 -05:00
commit 0240020cd2
12 changed files with 15072 additions and 0 deletions

43
BOM.csv Normal file
View File

@@ -0,0 +1,43 @@
Reference,Value,Footprint,JLCPCB_Part,Quantity,Description,Unit_Price_Est
U3,ESP32-S3-WROOM-1-N16R8,RF_Module:ESP32-S3-WROOM-1,C2913202,1,WiFi+BLE MCU 16MB Flash 8MB PSRAM,$2.80
U2,AMS1117-3.3,Package_TO_SOT_SMD:SOT-223-3_TabPin2,C6186,1,3.3V LDO Regulator 1A,$0.08
U4,AP2112K-1.8,Package_TO_SOT_SMD:SOT-23-5,C51118,1,1.8V LDO for camera DOVDD,$0.10
U5,AP2112K-2.8,Package_TO_SOT_SMD:SOT-23-5,C51114,1,2.8V LDO for camera AVDD,$0.10
U6,SHT41,Sensirion_DFN-4-1EP_1.5x1.5mm,C2911456,1,Temp/Humidity ±0.2°C I2C,$1.20
U7,BH1750FVI,Package_SO:WSOF-6_1.4x1.7mm,C78960,1,Ambient Light 1-65535 lux I2C,$0.50
U1,USBLC6-2SC6,Package_TO_SOT_SMD:SOT-23-6,C7519,1,USB ESD Protection,$0.15
J1,USB_C_16P,Connector_USB:USB_C_Receptacle_GCT_USB4125,C2765186,1,USB-C 16pin receptacle,$0.30
J2,FPC_24P_OV5640,Connector_FFC-FPC:Molex_503480-2400,C2856805,1,24-pin 0.5mm FPC connector,$0.20
J3,LD2410C,Connector_PinHeader_1.27mm:PinHeader_1x05_P1.27mm,N/A,1,1.27mm 5-pin header for LD2410C,$0.05
J4,AM312_PIR,Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm,N/A,1,2.54mm 3-pin header for AM312,$0.03
D1,LED_Blue,LED_SMD:LED_0402_1005Metric,C2286,1,Blue status LED 0402,$0.02
R1,1K,Resistor_SMD:R_0402_1005Metric,C11702,1,LED current limit,$0.01
R2,10K,Resistor_SMD:R_0402_1005Metric,C25744,1,PIR pulldown,$0.01
R3,4.7K,Resistor_SMD:R_0402_1005Metric,C25900,1,I2C SDA pull-up,$0.01
R4,4.7K,Resistor_SMD:R_0402_1005Metric,C25900,1,I2C SCL pull-up,$0.01
C1,10uF,Capacitor_SMD:C_0805_2012Metric,C15850,1,LDO input cap,$0.02
C2,22uF,Capacitor_SMD:C_0805_2012Metric,C45783,1,LDO output cap,$0.03
C3,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,LDO decoupling,$0.01
C4,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,ESP32 decoupling,$0.01
C5,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,ESP32 decoupling,$0.01
C6,10uF,Capacitor_SMD:C_0805_2012Metric,C15850,1,ESP32 bulk cap,$0.02
C7,10uF,Capacitor_SMD:C_0805_2012Metric,C15850,1,Camera power filter,$0.02
C8,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,Camera decoupling,$0.01
C9,10uF,Capacitor_SMD:C_0805_2012Metric,C15850,1,LD2410C decoupling,$0.02
C10,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,SHT41 decoupling,$0.01
C11,100nF,Capacitor_SMD:C_0402_1005Metric,C1525,1,BH1750 decoupling,$0.01
SW1,BOOT,Button_Switch_SMD:SW_SPST_PTS810,C116501,1,Boot button (GPIO0),$0.05
SW2,RESET,Button_Switch_SMD:SW_SPST_PTS810,C116501,1,Reset button (EN),$0.05
H1,MountingHole,MountingHole:MountingHole_2.2mm_M2_Pad,N/A,1,M2 mounting hole,$0.00
H2,MountingHole,MountingHole:MountingHole_2.2mm_M2_Pad,N/A,1,M2 mounting hole,$0.00
,,,,,,
,,,MODULES (not on PCB - plug in),,,,
MOD1,OV5640,Camera Module 5MP 120° wide-angle,N/A,1,24-pin FPC OV5640 module,$3.50
MOD2,HLK-LD2410C,24GHz mmWave Radar Module,N/A,1,5-pin presence radar,$2.50
MOD3,AM312,Mini PIR Sensor Module,N/A,1,3-pin PIR sensor,$0.50
,,,,,,
,,,TOTAL PCB COMPONENTS,,28,~$5.50
,,,TOTAL WITH MODULES,,31,~$12.00
,,,PCB FABRICATION (5pcs JLCPCB),,,~$8.00
,,,SMD ASSEMBLY (per board),,,~$12.00
,,,TOTAL PER BOARD (assembled),,,"~$32.00"
1 Reference Value Footprint JLCPCB_Part Quantity Description Unit_Price_Est
2 U3 ESP32-S3-WROOM-1-N16R8 RF_Module:ESP32-S3-WROOM-1 C2913202 1 WiFi+BLE MCU 16MB Flash 8MB PSRAM $2.80
3 U2 AMS1117-3.3 Package_TO_SOT_SMD:SOT-223-3_TabPin2 C6186 1 3.3V LDO Regulator 1A $0.08
4 U4 AP2112K-1.8 Package_TO_SOT_SMD:SOT-23-5 C51118 1 1.8V LDO for camera DOVDD $0.10
5 U5 AP2112K-2.8 Package_TO_SOT_SMD:SOT-23-5 C51114 1 2.8V LDO for camera AVDD $0.10
6 U6 SHT41 Sensirion_DFN-4-1EP_1.5x1.5mm C2911456 1 Temp/Humidity ±0.2°C I2C $1.20
7 U7 BH1750FVI Package_SO:WSOF-6_1.4x1.7mm C78960 1 Ambient Light 1-65535 lux I2C $0.50
8 U1 USBLC6-2SC6 Package_TO_SOT_SMD:SOT-23-6 C7519 1 USB ESD Protection $0.15
9 J1 USB_C_16P Connector_USB:USB_C_Receptacle_GCT_USB4125 C2765186 1 USB-C 16pin receptacle $0.30
10 J2 FPC_24P_OV5640 Connector_FFC-FPC:Molex_503480-2400 C2856805 1 24-pin 0.5mm FPC connector $0.20
11 J3 LD2410C Connector_PinHeader_1.27mm:PinHeader_1x05_P1.27mm N/A 1 1.27mm 5-pin header for LD2410C $0.05
12 J4 AM312_PIR Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm N/A 1 2.54mm 3-pin header for AM312 $0.03
13 D1 LED_Blue LED_SMD:LED_0402_1005Metric C2286 1 Blue status LED 0402 $0.02
14 R1 1K Resistor_SMD:R_0402_1005Metric C11702 1 LED current limit $0.01
15 R2 10K Resistor_SMD:R_0402_1005Metric C25744 1 PIR pulldown $0.01
16 R3 4.7K Resistor_SMD:R_0402_1005Metric C25900 1 I2C SDA pull-up $0.01
17 R4 4.7K Resistor_SMD:R_0402_1005Metric C25900 1 I2C SCL pull-up $0.01
18 C1 10uF Capacitor_SMD:C_0805_2012Metric C15850 1 LDO input cap $0.02
19 C2 22uF Capacitor_SMD:C_0805_2012Metric C45783 1 LDO output cap $0.03
20 C3 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 LDO decoupling $0.01
21 C4 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 ESP32 decoupling $0.01
22 C5 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 ESP32 decoupling $0.01
23 C6 10uF Capacitor_SMD:C_0805_2012Metric C15850 1 ESP32 bulk cap $0.02
24 C7 10uF Capacitor_SMD:C_0805_2012Metric C15850 1 Camera power filter $0.02
25 C8 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 Camera decoupling $0.01
26 C9 10uF Capacitor_SMD:C_0805_2012Metric C15850 1 LD2410C decoupling $0.02
27 C10 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 SHT41 decoupling $0.01
28 C11 100nF Capacitor_SMD:C_0402_1005Metric C1525 1 BH1750 decoupling $0.01
29 SW1 BOOT Button_Switch_SMD:SW_SPST_PTS810 C116501 1 Boot button (GPIO0) $0.05
30 SW2 RESET Button_Switch_SMD:SW_SPST_PTS810 C116501 1 Reset button (EN) $0.05
31 H1 MountingHole MountingHole:MountingHole_2.2mm_M2_Pad N/A 1 M2 mounting hole $0.00
32 H2 MountingHole MountingHole:MountingHole_2.2mm_M2_Pad N/A 1 M2 mounting hole $0.00
33
34 MODULES (not on PCB - plug in)
35 MOD1 OV5640 Camera Module 5MP 120° wide-angle N/A 1 24-pin FPC OV5640 module $3.50
36 MOD2 HLK-LD2410C 24GHz mmWave Radar Module N/A 1 5-pin presence radar $2.50
37 MOD3 AM312 Mini PIR Sensor Module N/A 1 3-pin PIR sensor $0.50
38
39 TOTAL PCB COMPONENTS 28 ~$5.50
40 TOTAL WITH MODULES 31 ~$12.00
41 PCB FABRICATION (5pcs JLCPCB) ~$8.00
42 SMD ASSEMBLY (per board) ~$12.00
43 TOTAL PER BOARD (assembled) ~$32.00

67
PIN_MAPPING.md Normal file
View File

@@ -0,0 +1,67 @@
# ESP32-S3 Pin Mapping - Presence Sensor
## GPIO Assignments
| GPIO | Function | Peripheral | Direction | Notes |
|------|----------|-----------|-----------|-------|
| GPIO0 | BOOT button | - | Input | Pull-up, hold low to enter bootloader |
| GPIO1 | Camera D0 | OV5640 DVP | Input | Camera data bus |
| GPIO2 | Camera D1 | OV5640 DVP | Input | Camera data bus |
| GPIO3 | I2C SDA | SHT41 + BH1750 | Bidir | 4.7K pull-up to 3.3V |
| GPIO4 | I2C SCL | SHT41 + BH1750 | Bidir | 4.7K pull-up to 3.3V |
| GPIO5 | Camera D2 | OV5640 DVP | Input | Camera data bus |
| GPIO6 | Camera D3 | OV5640 DVP | Input | Camera data bus |
| GPIO7 | Camera D4 | OV5640 DVP | Input | Camera data bus |
| GPIO8 | Camera D5 | OV5640 DVP | Input | Camera data bus |
| GPIO9 | Camera D6 | OV5640 DVP | Input | Camera data bus |
| GPIO10 | Camera D7 | OV5640 DVP | Input | Camera data bus |
| GPIO11 | Camera XCLK | OV5640 | Output | 20MHz clock via LEDC PWM |
| GPIO12 | Camera PCLK | OV5640 | Input | Pixel clock |
| GPIO13 | Camera VSYNC | OV5640 | Input | Vertical sync |
| GPIO14 | Camera HREF | OV5640 | Input | Horizontal reference |
| GPIO15 | Camera SIOD | OV5640 SCCB | Bidir | Camera I2C data (separate bus) |
| GPIO16 | Camera SIOC | OV5640 SCCB | Output | Camera I2C clock (separate bus) |
| GPIO17 | mmWave UART TX | LD2410C RX | Output | 256000 baud |
| GPIO18 | mmWave UART RX | LD2410C TX | Input | 256000 baud |
| GPIO19 | USB D- | USB-C | Bidir | Native USB (programming) |
| GPIO20 | USB D+ | USB-C | Bidir | Native USB (programming) |
| GPIO21 | Camera PWDN | OV5640 | Output | Camera power down (active high) |
| GPIO38 | PIR output | AM312 | Input | Digital HIGH on motion |
| GPIO39 | mmWave OUT | LD2410C | Input | Digital presence output |
| GPIO40 | Status LED | Blue LED | Output | Via 1K resistor |
| GPIO41 | Camera RESET | OV5640 | Output | Camera reset (active low) |
| GPIO47 | (Reserved) | - | - | PSRAM (if using octal) |
| GPIO48 | (Reserved) | - | - | PSRAM (if using octal) |
## I2C Bus (GPIO3/GPIO4)
| Device | Address | Function |
|--------|---------|----------|
| SHT41 | 0x44 | Temperature + Humidity |
| BH1750 | 0x23 | Ambient Light (ADDR pin LOW) |
## UART1 (GPIO17/GPIO18)
| Device | Baud | Function |
|--------|------|----------|
| LD2410C | 256000 | mmWave presence radar |
## Power Rails
| Rail | Source | Load |
|------|--------|------|
| 5V (VBUS) | USB-C | LD2410C, AMS1117 input |
| 3.3V | AMS1117 | ESP32-S3, SHT41, BH1750, AM312, Camera digital |
| 2.8V | AP2112K | OV5640 AVDD (analog) |
| 1.8V | AP2112K | OV5640 DOVDD (digital I/O) |
## Power Budget
| Component | Voltage | Current (typical) | Current (peak) |
|-----------|---------|-------------------|----------------|
| ESP32-S3 (WiFi active) | 3.3V | 240mA | 500mA |
| OV5640 (streaming) | 2.8V+1.8V | 140mA | 200mA |
| LD2410C | 5V | 60mA | 150mA |
| AM312 | 3.3V | 0.01mA | 0.01mA |
| SHT41 | 3.3V | 0.4mA | 2mA |
| BH1750 | 3.3V | 0.12mA | 0.2mA |
| Status LED | 3.3V | 2mA | 2mA |
| **Total** | - | **~445mA** | **~855mA** |
USB-C provides 500mA default, 900mA with USB 3.0. Board should work fine on any USB charger (1A+).

113
README.md Normal file
View File

@@ -0,0 +1,113 @@
# ESP32-S3 Presence Sensor
Compact wall-mount presence sensor with camera, mmWave radar, PIR, temperature/humidity, and ambient light sensing. Designed for Home Assistant via ESPHome.
## Features
- **5MP Camera** (OV5640, 120° wide-angle) - video stream to HA
- **24GHz mmWave Radar** (LD2410C) - presence detection even when still
- **PIR Sensor** (AM312) - instant motion trigger
- **Temp/Humidity** (SHT41) - ±0.2°C accuracy
- **Light Sensor** (BH1750) - 1-65535 lux
- **USB-C powered** - any 1A+ charger
- **~45x35mm PCB** - wall mountable
## How Detection Works
```
Motion event:
PIR (AM312) ──→ instant trigger (ms response)
mmWave (LD2410C) ──→ sustained presence tracking
│ (detects breathing/typing)
Combined "Occupancy" ──→ true if either sensor active
30s delay before "unoccupied"
```
PIR catches fast motion immediately. mmWave confirms someone is still in the room even when sitting perfectly still. The combined sensor gives zero false-offs.
## Project Files
| File | Description |
|------|-------------|
| `presence-sensor.kicad_pro` | KiCad project file |
| `presence-sensor.kicad_sch` | Schematic |
| `PIN_MAPPING.md` | GPIO assignments and power budget |
| `BOM.csv` | Bill of materials with JLCPCB part numbers |
| `esphome-presence-sensor.yaml` | ESPHome firmware config |
## Build Instructions
### 1. Order PCBs
- Open project in KiCad 8+
- Complete PCB layout (place components, route traces)
- Generate Gerbers: File → Plot → Gerber
- Upload to [JLCPCB](https://jlcpcb.com)
- Enable SMD assembly, upload BOM.csv
### 2. Order Modules (plug-in, not soldered by JLCPCB)
- OV5640 camera module (24-pin 0.5mm FPC, wide-angle 120°)
- HLK-LD2410C mmWave radar module
- AM312 mini PIR sensor
### 3. Assembly
- Solder LD2410C to 1.27mm header
- Solder AM312 to 2.54mm header
- Connect OV5640 via FPC cable
### 4. Flash Firmware
```bash
# Install ESPHome
pip install esphome
# Create secrets.yaml
cat > secrets.yaml << EOF
wifi_ssid: "your-wifi"
wifi_password: "your-password"
api_key: "generate-a-key"
ota_password: "your-ota-password"
fallback_password: "your-fallback"
EOF
# Flash via USB-C (hold BOOT, press RESET, release BOOT)
esphome run esphome-presence-sensor.yaml
```
### 5. Add to Home Assistant
- ESPHome auto-discovers the device
- Settings → Devices & Services → ESPHome → Configure
## Cost Per Board
| Item | Cost |
|------|------|
| PCB fabrication (5pcs) | ~$8 total |
| SMD assembly | ~$12/board |
| Components on PCB | ~$5.50/board |
| OV5640 camera module | ~$3.50 |
| LD2410C radar | ~$2.50 |
| AM312 PIR | ~$0.50 |
| **Total per board** | **~$32** |
## Design Notes
### Antenna Clearance
- ESP32-S3 antenna extends past board edge
- No copper pour under antenna area (top or bottom)
- Keep antenna away from LD2410C radar module
### Thermal
- SHT41 placed on board edge, away from ESP32 heat
- -1.5°C offset in ESPHome config (calibrate after testing)
- Enclosure should have ventilation slots near SHT41
### mmWave Orientation
- LD2410C mounted perpendicular to wall for widest room coverage
- Detection cone is ~60° in each direction
- Optimal height: 1.2-1.5m from floor
### Camera
- OV5640 connects via 24-pin FPC flex cable
- Camera module sits at top of enclosure, angled slightly down
- 120° wide-angle lens covers most of a room from wall mount

11762
enclosure/body.stl Normal file

File diff suppressed because it is too large Load Diff

2
enclosure/body_only.scad Normal file
View File

@@ -0,0 +1,2 @@
include <enclosure.scad>;
// Only body is rendered (default render includes both)

185
enclosure/enclosure.scad Normal file
View File

@@ -0,0 +1,185 @@
// ============================================
// Presence Sensor Wall-Mount Enclosure
// ESP32-S3 + OV5640 + LD2410C + AM312 + SHT41 + BH1750
// Board: 45 x 35 mm
// ============================================
// Dimensions (mm)
pcb_w = 45; // PCB width
pcb_h = 35; // PCB height
pcb_t = 1.6; // PCB thickness
wall = 1.8; // Wall thickness
tolerance = 0.3; // Fit tolerance
bottom_gap = 3; // Space below PCB for solder joints
top_gap = 12; // Space above PCB for components + modules
lid_lip = 1.5; // Lid overlap lip
// Derived
inner_w = pcb_w + tolerance * 2;
inner_h = pcb_h + tolerance * 2;
inner_d = bottom_gap + pcb_t + top_gap;
outer_w = inner_w + wall * 2;
outer_h = inner_h + wall * 2;
outer_d = inner_d + wall; // Open top (lid covers)
// Screw post dimensions
post_d = 4.5; // Post outer diameter
screw_d = 2.2; // M2 screw hole
post_h = bottom_gap; // Height to PCB level
// Component positions (from bottom-left of PCB)
cam_x = pcb_w / 2; // Camera centered horizontally
cam_y = pcb_h - 5; // Camera near top
cam_hole_w = 10; // Camera lens window
cam_hole_h = 10;
pir_x = 12; // PIR left of center
pir_y = pcb_h - 20;
pir_hole_d = 10; // AM312 dome diameter
light_x = 30; // BH1750 right of center
light_y = pcb_h - 20;
light_hole_d = 4; // Small window for light sensor
mmwave_x = pcb_w / 2; // LD2410C centered
mmwave_y = 8; // Near bottom
mmwave_slot_w = 8; // Slot for radar signal
mmwave_slot_h = 36;
usbc_x = pcb_w / 2; // USB-C centered bottom
usbc_w = 10;
usbc_h = 4;
vent_slot_w = 1.5;
vent_slot_h = 8;
// ============================================
// Main body
// ============================================
module body() {
difference() {
// Outer shell
rounded_box(outer_w, outer_h, outer_d, 3);
// Inner cavity
translate([wall, wall, wall])
rounded_box(inner_w, inner_h, inner_d + 1, 2);
// Camera window (front face - top)
translate([wall + tolerance + cam_x - cam_hole_w/2,
wall + tolerance + cam_y - cam_hole_h/2,
-1])
rounded_box(cam_hole_w, cam_hole_h, wall + 2, 2);
// PIR window (front face)
translate([wall + tolerance + pir_x,
wall + tolerance + pir_y,
-1])
cylinder(h=wall+2, d=pir_hole_d, $fn=32);
// Light sensor window (front face)
translate([wall + tolerance + light_x,
wall + tolerance + light_y,
-1])
cylinder(h=wall+2, d=light_hole_d, $fn=32);
// USB-C cutout (bottom edge)
translate([wall + tolerance + usbc_x - usbc_w/2,
-1,
wall + bottom_gap - 1])
cube([usbc_w, wall + 2, usbc_h + 2]);
// Ventilation slots (sides - for SHT41 airflow)
for (i = [0:3]) {
// Left side
translate([-1,
wall + 5 + i * (vent_slot_h + 2),
wall + bottom_gap + pcb_t + 2])
cube([wall + 2, vent_slot_h, vent_slot_w]);
// Right side
translate([outer_w - wall - 1,
wall + 5 + i * (vent_slot_h + 2),
wall + bottom_gap + pcb_t + 2])
cube([wall + 2, vent_slot_h, vent_slot_w]);
}
// mmWave radar slot (through back wall for better signal)
translate([wall + tolerance + mmwave_x - mmwave_slot_w/2,
wall + tolerance + mmwave_y - mmwave_slot_h/2,
outer_d - wall - 0.5])
rounded_box(mmwave_slot_w, mmwave_slot_h, wall + 1, 1);
// Wall mount screw slots (keyhole on back)
translate([outer_w/2, outer_h * 0.3, outer_d - wall - 1])
wall_mount_keyhole();
translate([outer_w/2, outer_h * 0.7, outer_d - wall - 1])
wall_mount_keyhole();
}
// PCB support posts
for (pos = [[wall + tolerance + 2.5, wall + tolerance + 2.5],
[wall + tolerance + pcb_w - 2.5, wall + tolerance + 2.5],
[wall + tolerance + 2.5, wall + tolerance + pcb_h - 2.5],
[wall + tolerance + pcb_w - 2.5, wall + tolerance + pcb_h - 2.5]]) {
translate([pos[0], pos[1], wall])
difference() {
cylinder(h=post_h, d=post_d, $fn=20);
cylinder(h=post_h + 1, d=screw_d, $fn=20);
}
}
}
// ============================================
// Lid (snap-fit)
// ============================================
module lid() {
difference() {
union() {
// Lid plate
rounded_box(outer_w, outer_h, wall, 3);
// Inner lip for alignment
translate([wall - lid_lip/2, wall - lid_lip/2, wall])
rounded_box(inner_w + lid_lip, inner_h + lid_lip, 2, 2);
}
// Status LED window (small hole)
translate([wall + tolerance + 40, wall + tolerance + 25, -1])
cylinder(h=wall+2, d=2, $fn=16);
}
}
// ============================================
// Helper modules
// ============================================
module rounded_box(w, h, d, r) {
hull() {
translate([r, r, 0]) cylinder(h=d, r=r, $fn=20);
translate([w-r, r, 0]) cylinder(h=d, r=r, $fn=20);
translate([r, h-r, 0]) cylinder(h=d, r=r, $fn=20);
translate([w-r, h-r, 0]) cylinder(h=d, r=r, $fn=20);
}
}
module wall_mount_keyhole() {
// Large hole (screw head)
cylinder(h=wall+2, d=7, $fn=24);
// Slot (slide down to lock)
translate([0, -5, 0])
hull() {
cylinder(h=wall+2, d=4, $fn=24);
translate([0, 5, 0]) cylinder(h=wall+2, d=4, $fn=24);
}
}
// ============================================
// Render
// ============================================
// Body
body();
// Lid (offset for viewing - move to origin for printing)
translate([outer_w + 10, 0, 0])
lid();

1766
enclosure/lid.stl Normal file

File diff suppressed because it is too large Load Diff

2
enclosure/lid_only.scad Normal file
View File

@@ -0,0 +1,2 @@
use <enclosure.scad>;
lid();

View File

@@ -0,0 +1,202 @@
substitutions:
name: presence-sensor
friendly_name: Presence Sensor
esphome:
name: ${name}
friendly_name: ${friendly_name}
platformio_options:
board_build.flash_mode: dio
board_build.arduino.memory_type: qio_opi
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
flash_size: 16MB
psram:
mode: octal
speed: 80MHz
# Enable logging
logger:
level: INFO
# Enable Home Assistant API
api:
encryption:
key: !secret api_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "${name}-fallback"
password: !secret fallback_password
# ==========================================
# I2C Bus - SHT41 + BH1750
# ==========================================
i2c:
sda: GPIO3
scl: GPIO4
scan: true
frequency: 400kHz
# ==========================================
# UART - LD2410C mmWave Radar
# ==========================================
uart:
id: uart_ld2410
tx_pin: GPIO17
rx_pin: GPIO18
baud_rate: 256000
parity: NONE
stop_bits: 1
# ==========================================
# Camera - OV5640 5MP
# ==========================================
esp32_camera:
name: Camera
external_clock:
pin: GPIO11
frequency: 20MHz
i2c_pins:
sda: GPIO15
scl: GPIO16
data_pins: [GPIO1, GPIO2, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10]
vsync_pin: GPIO13
href_pin: GPIO14
pixel_clock_pin: GPIO12
power_down_pin: GPIO21
reset_pin: GPIO41
resolution: 800x600
max_framerate: 15fps
idle_framerate: 0.2fps
jpeg_quality: 12
vertical_flip: false
horizontal_mirror: false
esp32_camera_web_server:
- port: 8080
mode: stream
# ==========================================
# LD2410C mmWave Presence Radar
# ==========================================
ld2410:
uart_id: uart_ld2410
id: ld2410_radar
binary_sensor:
# mmWave presence (stays on while someone is in room, even if still)
- platform: ld2410
has_target:
name: Presence
has_moving_target:
name: Moving Target
has_still_target:
name: Still Target
# PIR motion (fast initial trigger)
- platform: gpio
pin:
number: GPIO38
mode: INPUT
name: Motion
device_class: motion
filters:
- delayed_off: 10s
# Combined: PIR for instant trigger, mmWave for sustained presence
- platform: template
name: Occupancy
device_class: occupancy
lambda: |-
if (id(pir_motion).state || id(ld2410_presence).state) {
return true;
}
return false;
filters:
- delayed_off: 30s
sensor:
# mmWave detection distance
- platform: ld2410
moving_distance:
name: Moving Distance
still_distance:
name: Still Distance
moving_energy:
name: Moving Energy
still_energy:
name: Still Energy
detection_distance:
name: Detection Distance
# Temperature & Humidity - SHT41
- platform: sht4x
temperature:
name: Temperature
accuracy_decimals: 1
filters:
- offset: -1.5 # Compensate for ESP32 heat, adjust after testing
humidity:
name: Humidity
accuracy_decimals: 1
address: 0x44
update_interval: 30s
heater_max_duty: 0.0
# Ambient Light - BH1750
- platform: bh1750
name: Illuminance
address: 0x23
measurement_duration: 69
update_interval: 10s
# WiFi signal
- platform: wifi_signal
name: WiFi Signal
update_interval: 60s
# Uptime
- platform: uptime
name: Uptime
# ==========================================
# Status LED
# ==========================================
light:
- platform: status_led
name: Status LED
pin: GPIO40
# ==========================================
# Buttons
# ==========================================
button:
- platform: restart
name: Restart
- platform: factory_reset
name: Factory Reset
disabled_by_default: true
# ==========================================
# Diagnostic
# ==========================================
text_sensor:
- platform: wifi_info
ip_address:
name: IP Address
ssid:
name: Connected SSID
- platform: version
name: ESPHome Version

380
presence-sensor.kicad_pcb Normal file
View File

@@ -0,0 +1,380 @@
(kicad_pcb
(version 20221018)
(generator "custom_generator")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(title_block
(title "ESP32-S3 Presence Sensor")
(date "2026-03-29")
(rev "1.0")
)
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user "B.Mask")
(39 "F.Mask" user "F.Mask")
(44 "Edge.Cuts" user)
)
(setup
(pad_to_mask_clearance 0.05)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext no)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "gerbers/")
)
)
;; =====================================================
;; BOARD OUTLINE - 45mm x 35mm with rounded corners
;; =====================================================
(gr_arc (start 3 0) (mid 0.879 0.879) (end 0 3) (layer "Edge.Cuts") (width 0.15))
(gr_line (start 3 0) (end 42 0) (layer "Edge.Cuts") (width 0.15))
(gr_arc (start 45 3) (mid 44.121 0.879) (end 42 0) (layer "Edge.Cuts") (width 0.15))
(gr_line (start 45 3) (end 45 32) (layer "Edge.Cuts") (width 0.15))
(gr_arc (start 42 35) (mid 44.121 34.121) (end 45 32) (layer "Edge.Cuts") (width 0.15))
(gr_line (start 42 35) (end 3 35) (layer "Edge.Cuts") (width 0.15))
(gr_arc (start 0 32) (mid 0.879 34.121) (end 3 35) (layer "Edge.Cuts") (width 0.15))
(gr_line (start 0 32) (end 0 3) (layer "Edge.Cuts") (width 0.15))
;; =====================================================
;; COMPONENT PLACEMENT (all coordinates in mm from top-left)
;; Front = component side (facing room)
;; Back = wall side
;; =====================================================
;; --- BACK SIDE (facing wall) ---
;; ESP32-S3-WROOM-1 - center of board, back side
;; Module is 18x25.5mm, antenna at top extending past board edge
(footprint "RF_Module:ESP32-S3-WROOM-1"
(layer "B.Cu")
(at 22.5 18 0)
(property "Reference" "U3")
(property "Value" "ESP32-S3-WROOM-1-N16R8")
(property "JLCPCB" "C2913202")
)
;; AMS1117-3.3 LDO - bottom right, back side
(footprint "Package_TO_SOT_SMD:SOT-223-3_TabPin2"
(layer "B.Cu")
(at 38 30 0)
(property "Reference" "U2")
(property "Value" "AMS1117-3.3")
(property "JLCPCB" "C6186")
)
;; AP2112K-1.8 (camera DOVDD) - top right, back side
(footprint "Package_TO_SOT_SMD:SOT-23-5"
(layer "B.Cu")
(at 38 5 0)
(property "Reference" "U4")
(property "Value" "AP2112K-1.8")
(property "JLCPCB" "C51118")
)
;; AP2112K-2.8 (camera AVDD) - top right, back side
(footprint "Package_TO_SOT_SMD:SOT-23-5"
(layer "B.Cu")
(at 38 10 0)
(property "Reference" "U5")
(property "Value" "AP2112K-2.8")
(property "JLCPCB" "C51114")
)
;; USB ESD Protection
(footprint "Package_TO_SOT_SMD:SOT-23-6"
(layer "B.Cu")
(at 22.5 32 0)
(property "Reference" "U1")
(property "Value" "USBLC6-2SC6")
(property "JLCPCB" "C7519")
)
;; --- FRONT SIDE (facing room) ---
;; USB-C connector - bottom center, front side
(footprint "Connector_USB:USB_C_Receptacle_GCT_USB4125"
(layer "F.Cu")
(at 22.5 35 180)
(property "Reference" "J1")
(property "Value" "USB_C_16P")
(property "JLCPCB" "C2765186")
)
;; FPC camera connector - top center, front side
(footprint "Connector_FFC-FPC:Molex_503480-2400_1x24-1MP_P0.50mm_Horizontal"
(layer "F.Cu")
(at 22.5 2 0)
(property "Reference" "J2")
(property "Value" "FPC_24P_OV5640")
(property "JLCPCB" "C2856805")
)
;; LD2410C header - right side, front
(footprint "Connector_PinHeader_1.27mm:PinHeader_1x05_P1.27mm_Vertical"
(layer "F.Cu")
(at 42 17.5 90)
(property "Reference" "J3")
(property "Value" "LD2410C")
)
;; AM312 PIR header - left side, front
(footprint "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical"
(layer "F.Cu")
(at 3 15 90)
(property "Reference" "J4")
(property "Value" "AM312_PIR")
)
;; SHT41 - left edge, front (away from ESP32 heat)
(footprint "Sensor_Humidity:Sensirion_DFN-4-1EP_1.5x1.5mm_P0.8mm_EP0.5x0.5mm"
(layer "F.Cu")
(at 4 28 0)
(property "Reference" "U6")
(property "Value" "SHT41")
(property "JLCPCB" "C2911456")
)
;; BH1750 - left of center, front
(footprint "Package_SO:WSOF-6_1.4x1.7mm_P0.5mm"
(layer "F.Cu")
(at 12 22 0)
(property "Reference" "U7")
(property "Value" "BH1750FVI")
(property "JLCPCB" "C78960")
)
;; Status LED - front side, visible
(footprint "LED_SMD:LED_0402_1005Metric"
(layer "F.Cu")
(at 40 28 0)
(property "Reference" "D1")
(property "Value" "LED_Blue")
(property "JLCPCB" "C2286")
)
;; --- PASSIVE COMPONENTS (back side, near their ICs) ---
;; Input cap - near AMS1117
(footprint "Capacitor_SMD:C_0805_2012Metric"
(layer "B.Cu")
(at 33 30 0)
(property "Reference" "C1")
(property "Value" "10uF")
)
;; Output cap - near AMS1117
(footprint "Capacitor_SMD:C_0805_2012Metric"
(layer "B.Cu")
(at 33 33 0)
(property "Reference" "C2")
(property "Value" "22uF")
)
;; Decoupling caps - near ESP32
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "B.Cu")
(at 15 8 0)
(property "Reference" "C3")
(property "Value" "100nF")
)
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "B.Cu")
(at 15 10 0)
(property "Reference" "C4")
(property "Value" "100nF")
)
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "B.Cu")
(at 15 12 0)
(property "Reference" "C5")
(property "Value" "100nF")
)
(footprint "Capacitor_SMD:C_0805_2012Metric"
(layer "B.Cu")
(at 15 14 0)
(property "Reference" "C6")
(property "Value" "10uF")
)
;; Camera power caps
(footprint "Capacitor_SMD:C_0805_2012Metric"
(layer "B.Cu")
(at 35 3 0)
(property "Reference" "C7")
(property "Value" "10uF")
)
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "B.Cu")
(at 35 7 0)
(property "Reference" "C8")
(property "Value" "100nF")
)
;; LD2410C decoupling
(footprint "Capacitor_SMD:C_0805_2012Metric"
(layer "B.Cu")
(at 40 15 0)
(property "Reference" "C9")
(property "Value" "10uF")
)
;; SHT41 decoupling
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "F.Cu")
(at 7 28 0)
(property "Reference" "C10")
(property "Value" "100nF")
)
;; BH1750 decoupling
(footprint "Capacitor_SMD:C_0402_1005Metric"
(layer "F.Cu")
(at 15 22 0)
(property "Reference" "C11")
(property "Value" "100nF")
)
;; Resistors
(footprint "Resistor_SMD:R_0402_1005Metric"
(layer "F.Cu")
(at 38 28 0)
(property "Reference" "R1")
(property "Value" "1K")
(property "Description" "LED resistor")
)
(footprint "Resistor_SMD:R_0402_1005Metric"
(layer "F.Cu")
(at 5 15 0)
(property "Reference" "R2")
(property "Value" "10K")
(property "Description" "PIR pulldown")
)
(footprint "Resistor_SMD:R_0402_1005Metric"
(layer "F.Cu")
(at 8 24 0)
(property "Reference" "R3")
(property "Value" "4.7K")
(property "Description" "I2C SDA pull-up")
)
(footprint "Resistor_SMD:R_0402_1005Metric"
(layer "F.Cu")
(at 10 24 0)
(property "Reference" "R4")
(property "Value" "4.7K")
(property "Description" "I2C SCL pull-up")
)
;; Buttons - back side, accessible via pinhole
(footprint "Button_Switch_SMD:SW_SPST_PTS810"
(layer "B.Cu")
(at 5 33 0)
(property "Reference" "SW1")
(property "Value" "BOOT")
)
(footprint "Button_Switch_SMD:SW_SPST_PTS810"
(layer "B.Cu")
(at 10 33 0)
(property "Reference" "SW2")
(property "Value" "RESET")
)
;; Mounting holes
(footprint "MountingHole:MountingHole_2.2mm_M2_Pad"
(layer "F.Cu")
(at 2.5 2.5 0)
(property "Reference" "H1")
(property "Value" "MountingHole")
)
(footprint "MountingHole:MountingHole_2.2mm_M2_Pad"
(layer "F.Cu")
(at 42.5 2.5 0)
(property "Reference" "H2")
(property "Value" "MountingHole")
)
;; =====================================================
;; SILKSCREEN LABELS
;; =====================================================
(gr_text "Presence Sensor v1.0"
(at 22.5 17.5 0)
(layer "F.SilkS")
(effects (font (size 1.2 1.2) (thickness 0.2)) (justify center))
)
(gr_text "github.com/chrisryn"
(at 22.5 19.5 0)
(layer "F.SilkS")
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify center))
)
(gr_text "CAM"
(at 22.5 4 0)
(layer "F.SilkS")
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify center))
)
(gr_text "PIR"
(at 3 12 0)
(layer "F.SilkS")
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify center))
)
(gr_text "mmWave"
(at 42 14 0)
(layer "F.SilkS")
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify center))
)
(gr_text "USB-C"
(at 22.5 33 0)
(layer "F.SilkS")
(effects (font (size 0.8 0.8) (thickness 0.15)) (justify center))
)
;; =====================================================
;; ANTENNA KEEP-OUT ZONE
;; ESP32-S3 antenna at top of module - no copper
;; =====================================================
(gr_rect (start 13 0) (end 32 6)
(layer "F.SilkS") (width 0.15) (fill none)
)
(gr_text "ANTENNA KEEP-OUT"
(at 22.5 3 0)
(layer "B.SilkS")
(effects (font (size 0.6 0.6) (thickness 0.1)) (justify center))
)
)

135
presence-sensor.kicad_pro Normal file
View File

@@ -0,0 +1,135 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"other_line_width": 0.15,
"silk_line_width": 0.15,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {
"min_copper_edge_clearance": 0.0,
"solder_mask_to_copper_clearance": 0.0
},
"track_widths": [0.0, 0.25, 0.5, 1.0],
"via_dimensions": []
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "presence-sensor.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
},
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Power",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.5,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"e63e39d7-6ac0-4ffd-8aa3-1841a4541b55",
"Root"
]
],
"text_variables": {}
}

415
presence-sensor.kicad_sch Normal file
View File

@@ -0,0 +1,415 @@
(kicad_sch
(version 20230121)
(generator "custom")
(uuid "e63e39d7-6ac0-4ffd-8aa3-1841a4541b55")
(paper "A3")
(title_block
(title "ESP32-S3 Presence Sensor")
(date "2026-03-29")
(rev "1.0")
(comment 1 "Wall-mount presence sensor with camera")
(comment 2 "ESP32-S3 + OV5640 + LD2410C + AM312 + SHT41 + BH1750")
)
;; =====================================================
;; POWER SECTION - USB-C Input + 3.3V Regulation
;; =====================================================
(text "USB-C Power Input + 3.3V LDO"
(at 25 25 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
;; USB-C Connector (USB4125-GF-A - 16 pin USB-C)
(symbol
(lib_id "Connector:USB_C_Receptacle_USB2.0")
(at 40 60 0)
(uuid "a1000001-0001-0001-0001-000000000001")
(property "Reference" "J1" (at 40 42 0))
(property "Value" "USB_C_16P" (at 40 44 0))
(property "Footprint" "Connector_USB:USB_C_Receptacle_GCT_USB4125" (at 40 60 0))
(property "JLCPCB" "C2765186" (at 40 60 0))
)
;; ESD Protection (USBLC6-2SC6)
(symbol
(lib_id "Power_Protection:USBLC6-2SC6")
(at 70 60 0)
(uuid "a1000001-0001-0001-0001-000000000002")
(property "Reference" "U1" (at 70 50 0))
(property "Value" "USBLC6-2SC6" (at 70 52 0))
(property "Footprint" "Package_TO_SOT_SMD:SOT-23-6" (at 70 60 0))
(property "JLCPCB" "C7519" (at 70 60 0))
)
;; AMS1117-3.3 LDO Regulator
(symbol
(lib_id "Regulator_Linear:AMS1117-3.3")
(at 100 55 0)
(uuid "a1000001-0001-0001-0001-000000000003")
(property "Reference" "U2" (at 100 47 0))
(property "Value" "AMS1117-3.3" (at 100 49 0))
(property "Footprint" "Package_TO_SOT_SMD:SOT-223-3_TabPin2" (at 100 55 0))
(property "JLCPCB" "C6186" (at 100 55 0))
)
;; Input capacitor 10uF
(symbol
(lib_id "Device:C")
(at 90 65 0)
(uuid "a1000001-0001-0001-0001-000000000004")
(property "Reference" "C1" (at 92 63 0))
(property "Value" "10uF" (at 92 67 0))
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (at 90 65 0))
(property "JLCPCB" "C15850" (at 90 65 0))
)
;; Output capacitor 22uF
(symbol
(lib_id "Device:C")
(at 110 65 0)
(uuid "a1000001-0001-0001-0001-000000000005")
(property "Reference" "C2" (at 112 63 0))
(property "Value" "22uF" (at 112 67 0))
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (at 110 65 0))
(property "JLCPCB" "C45783" (at 110 65 0))
)
;; Output capacitor 100nF decoupling
(symbol
(lib_id "Device:C")
(at 120 65 0)
(uuid "a1000001-0001-0001-0001-000000000006")
(property "Reference" "C3" (at 122 63 0))
(property "Value" "100nF" (at 122 67 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 120 65 0))
(property "JLCPCB" "C1525" (at 120 65 0))
)
;; =====================================================
;; MCU - ESP32-S3-WROOM-1 (N16R8)
;; =====================================================
(text "ESP32-S3-WROOM-1 (N16R8) - Main MCU"
(at 25 100 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
(symbol
(lib_id "RF_Module:ESP32-S3-WROOM-1")
(at 80 160 0)
(uuid "a1000001-0001-0001-0001-000000000010")
(property "Reference" "U3" (at 80 115 0))
(property "Value" "ESP32-S3-WROOM-1-N16R8" (at 80 117 0))
(property "Footprint" "RF_Module:ESP32-S3-WROOM-1" (at 80 160 0))
(property "JLCPCB" "C2913202" (at 80 160 0))
(property "Description" "ESP32-S3 WiFi+BLE module, 16MB Flash, 8MB PSRAM" (at 80 160 0))
)
;; Boot button (GPIO0)
(symbol
(lib_id "Switch:SW_Push")
(at 35 145 0)
(uuid "a1000001-0001-0001-0001-000000000011")
(property "Reference" "SW1" (at 35 140 0))
(property "Value" "BOOT" (at 35 150 0))
(property "Footprint" "Button_Switch_SMD:SW_SPST_PTS810" (at 35 145 0))
(property "JLCPCB" "C116501" (at 35 145 0))
)
;; Reset button (EN)
(symbol
(lib_id "Switch:SW_Push")
(at 35 160 0)
(uuid "a1000001-0001-0001-0001-000000000012")
(property "Reference" "SW2" (at 35 155 0))
(property "Value" "RESET" (at 35 165 0))
(property "Footprint" "Button_Switch_SMD:SW_SPST_PTS810" (at 35 160 0))
(property "JLCPCB" "C116501" (at 35 160 0))
)
;; ESP32-S3 decoupling caps (3x 100nF + 1x 10uF)
(symbol
(lib_id "Device:C")
(at 55 120 0)
(uuid "a1000001-0001-0001-0001-000000000013")
(property "Reference" "C4" (at 57 118 0))
(property "Value" "100nF" (at 57 122 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 55 120 0))
)
(symbol
(lib_id "Device:C")
(at 62 120 0)
(uuid "a1000001-0001-0001-0001-000000000014")
(property "Reference" "C5" (at 64 118 0))
(property "Value" "100nF" (at 64 122 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 62 120 0))
)
(symbol
(lib_id "Device:C")
(at 69 120 0)
(uuid "a1000001-0001-0001-0001-000000000015")
(property "Reference" "C6" (at 71 118 0))
(property "Value" "10uF" (at 71 122 0))
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (at 69 120 0))
)
;; Status LED
(symbol
(lib_id "Device:LED")
(at 130 140 0)
(uuid "a1000001-0001-0001-0001-000000000016")
(property "Reference" "D1" (at 132 138 0))
(property "Value" "LED_Blue" (at 132 142 0))
(property "Footprint" "LED_SMD:LED_0402_1005Metric" (at 130 140 0))
(property "JLCPCB" "C2286" (at 130 140 0))
)
;; LED resistor
(symbol
(lib_id "Device:R")
(at 130 130 0)
(uuid "a1000001-0001-0001-0001-000000000017")
(property "Reference" "R1" (at 132 130 0))
(property "Value" "1K" (at 134 130 0))
(property "Footprint" "Resistor_SMD:R_0402_1005Metric" (at 130 130 0))
(property "JLCPCB" "C11702" (at 130 130 0))
)
;; =====================================================
;; CAMERA - OV5640 via 24-pin FPC connector
;; =====================================================
(text "OV5640 5MP Camera Module (24-pin FPC)"
(at 170 25 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
;; 24-pin FPC connector for OV5640
(symbol
(lib_id "Connector_Generic:Conn_01x24")
(at 190 80 0)
(uuid "a1000001-0001-0001-0001-000000000020")
(property "Reference" "J2" (at 190 42 0))
(property "Value" "FPC_24P_OV5640" (at 190 44 0))
(property "Footprint" "Connector_FFC-FPC:Molex_503480-2400_1x24-1MP_P0.50mm_Horizontal" (at 190 80 0))
(property "JLCPCB" "C2856805" (at 190 80 0))
(property "Description" "24-pin 0.5mm FPC connector for OV5640 camera module" (at 190 80 0))
)
;; Camera power filter caps
(symbol
(lib_id "Device:C")
(at 175 50 0)
(uuid "a1000001-0001-0001-0001-000000000021")
(property "Reference" "C7" (at 177 48 0))
(property "Value" "10uF" (at 177 52 0))
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (at 175 50 0))
)
(symbol
(lib_id "Device:C")
(at 182 50 0)
(uuid "a1000001-0001-0001-0001-000000000022")
(property "Reference" "C8" (at 184 48 0))
(property "Value" "100nF" (at 184 52 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 182 50 0))
)
;; Camera 1.8V LDO (for DOVDD)
(symbol
(lib_id "Regulator_Linear:AP2112K-1.8")
(at 210 50 0)
(uuid "a1000001-0001-0001-0001-000000000023")
(property "Reference" "U4" (at 210 42 0))
(property "Value" "AP2112K-1.8" (at 210 44 0))
(property "Footprint" "Package_TO_SOT_SMD:SOT-23-5" (at 210 50 0))
(property "JLCPCB" "C51118" (at 210 50 0))
(property "Description" "1.8V LDO for camera DOVDD" (at 210 50 0))
)
;; Camera 2.8V LDO (for AVDD)
(symbol
(lib_id "Regulator_Linear:AP2112K-2.8")
(at 210 70 0)
(uuid "a1000001-0001-0001-0001-000000000024")
(property "Reference" "U5" (at 210 62 0))
(property "Value" "AP2112K-2.8" (at 210 64 0))
(property "Footprint" "Package_TO_SOT_SMD:SOT-23-5" (at 210 70 0))
(property "JLCPCB" "C51114" (at 210 70 0))
(property "Description" "2.8V LDO for camera AVDD" (at 210 70 0))
)
;; 24MHz crystal oscillator for camera XCLK (if not using ESP32 LEDC PWM)
;; Note: ESP32-S3 can generate XCLK via LEDC, so crystal is optional
;; Using LEDC output from GPIO15 instead
;; =====================================================
;; mmWave RADAR - HLK-LD2410C
;; =====================================================
(text "HLK-LD2410C 24GHz mmWave Presence Radar"
(at 170 120 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
;; LD2410C connector (5-pin: VCC, GND, TX, RX, OUT)
(symbol
(lib_id "Connector_Generic:Conn_01x05")
(at 200 145 0)
(uuid "a1000001-0001-0001-0001-000000000030")
(property "Reference" "J3" (at 200 135 0))
(property "Value" "LD2410C" (at 200 137 0))
(property "Footprint" "Connector_PinHeader_1.27mm:PinHeader_1x05_P1.27mm_Vertical" (at 200 145 0))
(property "Description" "HLK-LD2410C 24GHz mmWave radar module connector" (at 200 145 0))
(pin_names
(pin "1" "VCC_5V")
(pin "2" "GND")
(pin "3" "UART_TX")
(pin "4" "UART_RX")
(pin "5" "OUT")
)
)
;; LD2410C decoupling
(symbol
(lib_id "Device:C")
(at 215 140 0)
(uuid "a1000001-0001-0001-0001-000000000031")
(property "Reference" "C9" (at 217 138 0))
(property "Value" "10uF" (at 217 142 0))
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" (at 215 140 0))
)
;; =====================================================
;; PIR SENSOR - AM312
;; =====================================================
(text "AM312 PIR Motion Sensor"
(at 170 170 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
;; AM312 connector (3-pin: VCC, OUT, GND)
(symbol
(lib_id "Connector_Generic:Conn_01x03")
(at 200 190 0)
(uuid "a1000001-0001-0001-0001-000000000040")
(property "Reference" "J4" (at 200 182 0))
(property "Value" "AM312_PIR" (at 200 184 0))
(property "Footprint" "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" (at 200 190 0))
(property "Description" "AM312 mini PIR sensor, 3.3V, digital output" (at 200 190 0))
(pin_names
(pin "1" "VCC_3V3")
(pin "2" "OUT")
(pin "3" "GND")
)
)
;; PIR pulldown resistor
(symbol
(lib_id "Device:R")
(at 215 190 0)
(uuid "a1000001-0001-0001-0001-000000000041")
(property "Reference" "R2" (at 217 190 0))
(property "Value" "10K" (at 219 190 0))
(property "Footprint" "Resistor_SMD:R_0402_1005Metric" (at 215 190 0))
(property "JLCPCB" "C25744" (at 215 190 0))
)
;; =====================================================
;; I2C BUS - SHT41 + BH1750
;; =====================================================
(text "I2C Sensors: SHT41 (Temp/Humidity) + BH1750 (Light)"
(at 25 220 0)
(effects (font (size 3 3) (thickness 0.5)) (justify left))
)
;; SHT41 Temperature & Humidity Sensor
(symbol
(lib_id "Sensor:SHT4x")
(at 60 250 0)
(uuid "a1000001-0001-0001-0001-000000000050")
(property "Reference" "U6" (at 60 238 0))
(property "Value" "SHT41" (at 60 240 0))
(property "Footprint" "Sensor_Humidity:Sensirion_DFN-4-1EP_1.5x1.5mm_P0.8mm_EP0.5x0.5mm" (at 60 250 0))
(property "JLCPCB" "C2911456" (at 60 250 0))
(property "Description" "Digital temp/humidity sensor, ±0.2°C, I2C, 1.5x1.5mm" (at 60 250 0))
)
;; SHT41 decoupling
(symbol
(lib_id "Device:C")
(at 80 250 0)
(uuid "a1000001-0001-0001-0001-000000000051")
(property "Reference" "C10" (at 82 248 0))
(property "Value" "100nF" (at 82 252 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 80 250 0))
)
;; BH1750 Ambient Light Sensor
(symbol
(lib_id "Sensor_Optical:BH1750FVI")
(at 60 285 0)
(uuid "a1000001-0001-0001-0001-000000000052")
(property "Reference" "U7" (at 60 273 0))
(property "Value" "BH1750FVI" (at 60 275 0))
(property "Footprint" "Package_SO:WSOF-6_1.4x1.7mm_P0.5mm" (at 60 285 0))
(property "JLCPCB" "C78960" (at 60 285 0))
(property "Description" "Ambient light sensor, 1-65535 lux, I2C, 1.6x1.6mm" (at 60 285 0))
)
;; BH1750 decoupling
(symbol
(lib_id "Device:C")
(at 80 285 0)
(uuid "a1000001-0001-0001-0001-000000000053")
(property "Reference" "C11" (at 82 283 0))
(property "Value" "100nF" (at 82 287 0))
(property "Footprint" "Capacitor_SMD:C_0402_1005Metric" (at 80 285 0))
)
;; I2C pull-up resistors
(symbol
(lib_id "Device:R")
(at 40 235 0)
(uuid "a1000001-0001-0001-0001-000000000054")
(property "Reference" "R3" (at 42 235 0))
(property "Value" "4.7K" (at 44 235 0))
(property "Footprint" "Resistor_SMD:R_0402_1005Metric" (at 40 235 0))
(property "JLCPCB" "C25900" (at 40 235 0))
(property "Description" "I2C SDA pull-up" (at 40 235 0))
)
(symbol
(lib_id "Device:R")
(at 48 235 0)
(uuid "a1000001-0001-0001-0001-000000000055")
(property "Reference" "R4" (at 50 235 0))
(property "Value" "4.7K" (at 52 235 0))
(property "Footprint" "Resistor_SMD:R_0402_1005Metric" (at 48 235 0))
(property "JLCPCB" "C25900" (at 48 235 0))
(property "Description" "I2C SCL pull-up" (at 48 235 0))
)
;; =====================================================
;; MOUNTING HOLES
;; =====================================================
(symbol
(lib_id "Mechanical:MountingHole")
(at 250 260 0)
(uuid "a1000001-0001-0001-0001-000000000060")
(property "Reference" "H1" (at 252 258 0))
(property "Value" "MountingHole" (at 252 262 0))
(property "Footprint" "MountingHole:MountingHole_2.2mm_M2_Pad" (at 250 260 0))
)
(symbol
(lib_id "Mechanical:MountingHole")
(at 260 260 0)
(uuid "a1000001-0001-0001-0001-000000000061")
(property "Reference" "H2" (at 262 258 0))
(property "Value" "MountingHole" (at 262 262 0))
(property "Footprint" "MountingHole:MountingHole_2.2mm_M2_Pad" (at 260 260 0))
)
)