Set it up

Build your own Blue Bird

About an afternoon with a breadboard. Get each stage working on its own first — mic, then server, then trigger, then camera — and only then connect them.

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 pinESP32
VDD3V3
GNDGND
SCKGPIO 26
WSGPIO 25
SDGPIO 33
L/RGND
LED +GPIO 27

Step by step

From zero to CAPTURE

  1. 1

    Start the BirdNET server

    In the birnet folder, create a Python 3.12 environment and install the requirements.

    PowerShell — birnet/
    python -m venv .venv
    .\.venv\Scripts\Activate.ps1
    pip install -r requirements.txt

    Check which BirdNET label each target resolved to (anything marked MISSING can never be detected):

    PowerShell — birnet/
    .\.venv\Scripts\python.exe -m scripts.check_species

    Run 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.ps1

    Optional: put your location in birnet/.env so BirdNET's range filter can cut false positives.

    birnet/.env
    BIRDNET_LATITUDE=26.14
    BIRDNET_LONGITUDE=91.79
  2. 2

    Flash the ESP32

    Open esp32/birdnet_trigger/birdnet_trigger.ino in the Arduino IDE with the ESP32 board package (v3.x, which provides ESP_I2S.h). Edit the block at the top:

    birdnet_trigger.ino
    const 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. 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.

    PowerShell
    curl.exe -m 60 http://<esp32-ip>/trigger

    You get CAPTURE when a target bird is confirmed (score ≥ 0.70) and IGNORE otherwise. The Serial Monitor shows which species scored what.

  4. 4

    Run the bird detector

    In yolo_bird, install the CPU build of PyTorch first, then the rest. The first run downloads yolov8n.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.py

    Keys: s saves the frame to captures/, c cycles the confidence threshold, q quits. Try --imgsz 320 on a slow laptop.

    Today the detector doesn't call /trigger by itself yet — wiring that up (with a cooldown so one bird triggers one recording) is the next step.

  5. 5

    Run this website (optional)

    The site and its S3 image gallery are a Next.js app in app/. Copy .env.example to .env.local and 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.