Set it up
Build your own Blue Bird
Parts
What you need
- ESP32 dev board2.4 GHz Wi-Fi — it cannot join 5 GHz networks
- INMP441 I2S MEMS microphonedigital output, so no external ADC
- LED + resistor (optional)lights while recording
- 100 nF ceramic capacitordecoupling, close to the mic; 10 µF optional
- Breadboard + jumper wires
- Laptop with a webcamruns the detector and the BirdNET server
Wiring
INMP441 → ESP32
| Mic pin | ESP32 | Note |
|---|---|---|
| VDD | 3V3 | 3.3 V only |
| GND | GND | |
| SCK | GPIO 26 | I2S bit clock |
| WS | GPIO 25 | I2S word select |
| SD | GPIO 33 | I2S data |
| L/R | GND | left channel (see troubleshooting) |
| LED + | GPIO 27 | through a resistor |
Step by step
From zero to CAPTURE
- 1
Start the BirdNET server
In the
birnetfolder, create a Python 3.12 environment and install the requirements.PowerShell — birnet/python -m venv .venv .\.venv\Scripts\Activate.ps1 pip install -r requirements.txtCheck which BirdNET label each target resolved to (anything marked MISSING can never be detected):
PowerShell — birnet/.\.venv\Scripts\python.exe -m scripts.check_speciesRun it on all interfaces so the ESP32 can reach it. The first start downloads the BirdNET model. Interactive docs live at
http://127.0.0.1:8000/docs.PowerShell — birnet/.\run.ps1Optional: put your location in
birnet/.envso BirdNET's range filter can cut false positives.birnet/.envBIRDNET_LATITUDE=26.14 BIRDNET_LONGITUDE=91.79 - 2
Flash the ESP32
Open
esp32/birdnet_trigger/birdnet_trigger.inoin the Arduino IDE with the ESP32 board package (v3.x, which providesESP_I2S.h). Edit the block at the top:birdnet_trigger.inoconst char* WIFI_NAME = "your-2.4GHz-network"; const char* WIFI_PASSWORD = "your-password"; const char* BIRDNET_HOST = "192.168.x.x"; // the laptop running the server const uint16_t BIRDNET_PORT = 8000;Upload, then open the Serial Monitor at 115200 baud. It prints the ESP32's IP address once it joins Wi-Fi.
- 3
Fire a test trigger
Make a sound near the mic and call the trigger by hand. The LED lights for the 5-second recording; the request stays open until BirdNET answers, so allow up to a minute.
PowerShellcurl.exe -m 60 http://<esp32-ip>/triggerYou get
CAPTUREwhen a target bird is confirmed (score ≥ 0.70) andIGNOREotherwise. The Serial Monitor shows which species scored what. - 4
Run the bird detector
In
yolo_bird, install the CPU build of PyTorch first, then the rest. The first run downloadsyolov8n.pt(~6 MB).PowerShell — yolo_bird/python -m venv .venv .\.venv\Scripts\Activate.ps1 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu pip install -r requirements.txt python bird_detect.pyKeys:
ssaves the frame tocaptures/,ccycles the confidence threshold,qquits. Try--imgsz 320on a slow laptop.Today the detector doesn't call
/triggerby itself yet — wiring that up (with a cooldown so one bird triggers one recording) is the next step. - 5
Run this website (optional)
The site and its S3 image gallery are a Next.js app in
app/. Copy.env.exampleto.env.localand fill in the bucket for the gallery.terminal — app/npm install npm run dev
Troubleshooting
If something's off
Recordings are silent
Change I2S_STD_SLOT_LEFT to I2S_STD_SLOT_RIGHT in setup(), or tie the mic's L/R pin to 3.3 V instead of GND.
Too quiet or clipping
Adjust GAIN_SHIFT: 16 is quietest; each step lower doubles the volume.
“Cannot reach the BirdNET server”
Check BIRDNET_HOST is the laptop's LAN IP, the server runs with --host 0.0.0.0, and the firewall allows port 8000.
Wi-Fi never connects
The ESP32 only supports 2.4 GHz. Check the network name and password.