Skip to content
Fugleramme
Build log

The parts list, the power, the timeline and the choices along the way

All ordinary parts. What took time was the power outside and the colours inside.

The frame on the wall, 24 September 2026.
The frame on the wall, 24 September 2026.
The box outside, on the fence post.
The box outside, on the fence post.
Inside: the battery, the charging module and the XIAO board.
Inside: the battery, the charging module and the XIAO board.

The parts list

  • Waveshare ESP32-S3-ePaper-13.3E6, 13.3" Spectra 6, six colours, 16 MB PSRAM
  • IKEA RÖDALM frame, 30×40 cm
  • Seeed XIAO ESP32-S3, 8 MB PSRAM
  • INMP441 I2S microphone, foam against wind
  • Waveshare Solar Power Manager (D), MPPT charging
  • 3.7 V LiPo, 10 Ah
  • Solar panel, 6 to 24 V in
  • An old PC running Linux, Python 3.12, two venvs
  • systemd for the services, cron for the day
  • Android phone with a telephoto lens in the window
  • Before: Raspberry Pi 3 B with the HQ camera, parked

Power outside

Deep sleep between sessions14 µA
Recording and upload, a few tens of seconds~100 mA
Raspberry Pi 3 B idle, for comparison~450 mA

The solar panel was net positive in August with 24 sessions a day. The plan steps down by itself when the voltage drops. The goal is for the box to survive November.

The timeline

21 July 2026
First image on the screen, sent from the Mac.
24 July
Daily push from cron on the home server.
28 July
Outdoor unit v1 on a Raspberry Pi dies from lack of power.
4 August
Outdoor unit v2 on a XIAO ESP32-S3 in service, solar powered.
28 August
The bird page takes over from the free AI image.
13 September
Cost brakes on the camera analysis.
September
The phone as camera. The repo is prepared for going public.

The choices along the way

Most of this was not decided in advance. We tried something, measured, and replaced what did not hold up. Each choice is listed with the problem, what was tried, what was measured and what was chosen.

A fixed layout, not a free image

The problem
A free AI image every day was pretty, unpredictable, and said little about what was actually heard.
Tried
A free image of the bird of the day, July to August 2026.
Measured
The wall showed a bird. Not which ones, not when, not how certain.
Chosen
The same layout every day: the species with names, times and confidence. The free image lives on as a fallback.

The code puts the birds on the branch

The problem
The text needs an empty area on the left. The model decided for itself where it drew.
Tried
Asking for an empty area in plain words, three times. Giving it a finished branch as reference.
Measured
0.1 % ink in the text zone on one attempt, 14.8 % on the next. With the branch as a template: 20.6 %, worse than without.
Chosen
The model draws one bird at a time. The code puts them on the branch. The text zone is measured, and anything unclean is rejected.

Only palette colours on the page

The problem
The panel has six colours. Everything else has to be made with dots, and dithered text is hard to read.
Tried
A semi-transparent white pad behind the text, for readability.
Measured
A muddy blotch. The colour does not exist, so the dithering guessed it.
Chosen
Everything is drawn in the six colours. A pure white pad when needed; it is not dithered at all.

Location filter and block list

The problem
BirdNET suggests species that exist in Norway, but not in a suburban garden.
Tried
Location and date as a filter, as BirdNET recommends.
Measured
Spotted crake in 80 recordings up to 19 September, with confidence up to 0.91.
Chosen
A block list for the classic mistakes. They are never drawn, but they appear in the footnote so it is visible that they were heard.

The listening plan follows the sun and the battery

The problem
A fixed plan hits the dawn chorus in June and pitch darkness in December.
Tried
A fixed morning round from four o'clock, as in the firmware.
Measured
Five hours' difference in sunrise through the year. 70 % of the confident detections hung on a single minute.
Chosen
Sunrise is calculated on the server, without network calls. A fine window around it, denser sampling, stepped down when the voltage drops.

An expensive model for what runs rarely

The problem
The bill grew without anyone seeing where.
Tried
The camera on a Raspberry Pi with a thinking model at 1280 px, every picture.
Measured
1,559 pictures in eight days were 80 to 90 % of the spend. Half of them without a bird.
Chosen
The best model for new species, once. The cheapest without thinking at 768 px for the camera, with a cap per hour and a pause after 429.

The watch looks for silence

The problem
The outdoor unit sat in the bootloader for fifteen hours. Nobody noticed.
Tried
A watch that reacted to new data.
Measured
No new files, no reaction. A watch that only looks at new data is blind to the data having stopped.
Chosen
The watch looks for what does not happen, and is otherwise completely quiet. One message when something is wrong.

07:07, not 07:00

The problem
The weather API is most overloaded on the hour.
Tried
Cron at 07:00.
Measured
Two days of 503 outages in July 2026.
Chosen
Seven past seven. And the weather never stops the page: three attempts, then it is drawn without a weather reference.

Tried and dropped

Outdoor unit v1 on a Raspberry Pi 3 B

Drew 450 mA idle, got undervoltage on solar power and died on 28 July 2026. The microphone and the design choices carried on.

The model composes the whole plate

It drew its own branch in the middle of the page no matter what the reference said. The code took over the composition.

Camera on a Raspberry Pi with the HQ camera

Worked, but cost too much in model calls. The phone with a telephoto lens took over in September 2026.

Plates from a 3D model in Blender

For species without a usable plate. The line work worked, the plumage did not, and each species cost more modelling than it was worth. Dropped on 20 September 2026.

The tools

Much of the code was written together with Claude Code. What was measured, chosen and dropped is under the choices above. The repo has an AGENTS.md with the conventions, so an agent works by the same rules a colleague would.