‹ All builds

Hardware build // weekend project

The bottle stand that logs the 3am feed.

A load cell under a 3D-printed stand weighs the bottle, you tap a button at the start and end of a feed, and it writes the volume, time, and duration to Notion, with an optional Telegram ping. Set it down full, feed, set it back down. Done.

Jun 2026
  • ESP32
  • Load cell
  • Notion API
  • 3D printed
  • Parenting

A 3D-printed stand with a load cell weighs the bottle. You tap once when a feed starts and again when it ends: it works out the volume consumed (weight before minus weight after) and the duration, then logs every feed to a Notion database. A small OLED shows live weight and the last feed; real wall-clock timestamps come from NTP, so "started 2:42am" is actually accurate.

Difficulty
Beginner–Int.

one fiddly mount + a calibration

Cost
~$15

USD in core electronics

Build time
A weekend

a single day if parts are on hand

Logs to
Notion

+ optional Telegram ping

What you need

Parts

  • ESP32 DevKit V1 The Wi-Fi brains
    ×1 $5–8
  • Load cell, 1 kg bar type The weighing sensor
    ×1 $2–5
  • HX711 amplifier board Reads the load cell
    ×1 $1–2
  • Momentary push button Start/stop; optional 2nd for tare
    ×1–2 $0.50
  • SSD1306 0.96" OLED (I2C) Live weight + last feed
    ×1 $4–7
  • Breadboard + jumper wires Prototyping
    ×1 set $5
  • USB power adapter Mains power
    ×1 $5
  • 3D-printed stand MakerWorld load-cell scale remix
    ×1 ~$1

Tools

  • Soldering iron + solder Load-cell wires to the HX711
  • Computer + USB data cable Flashing the ESP32
  • PlatformIO (VS Code) or Arduino IDE Compile + upload
  • Breadboard + Dupont jumpers Prototyping the wiring
  • A known weight (250 mL water = 250 g) One-time calibration
  • 3D printer or print service The stand

The build

Step through it

10 steps. Scroll to move through them one at a time , or jump around with the arrows, the rail, or your / keys.

01/ 10
  1. The Notion 'Feed Log' database with Name, Start, End, Duration (min), Volume (mL) and Notes columns
    20 min

    Set up Notion first

    Do the cloud part before you touch hardware: it has the most unknowns, and
    you want the token + database ID in hand before you flash.

    1. Go to notion.so/my-integrations → New integration, name it "Feed Logger",
      copy the Internal Integration Secret (starts with ntn_ or secret_).
    2. Create a database called Feed Log with these properties:
    Property Type
    Name Title (auto)
    Start / End Date (include time)
    Duration (min) Number
    Volume (mL) Number
    Notes Text
    1. Open the database → •••Connections → add "Feed Logger".
    2. Copy the database ID, the 32-char hex chunk in the URL before ?.

    Run the optional curl test from software/README.md if you can, it isolates cloud problems from device problems before any soldering.

  2. Top: the 1 kg load cell and its four colored wires next to the HX711 board. Bottom: the HX711 held in hand with header pins soldered on, ready to plug into a breadboard
    15 min

    Connect the load cell to the HX711

    The load cell's four thin wires map to the HX711's input pads:

    Load-cell wire (typical) HX711 pad
    Red E+
    Black E−
    White A−
    Green A+

    Solder the wires straight to those pads, or do what I did: solder header
    pins to the HX711 and plug it into the breadboard, then run the load-cell
    wires in from there. Same mapping either way. Keep the joints clean, no
    bridges.

    Wire colors vary by manufacturer, so verify against your load cell's datasheet. If readings come out negative later, swap A+ and A−.

  3. Breadboard wiring of the HX711, SSD1306 OLED and push button to an ESP32 DevKit
    15 min

    Wire the HX711, OLED, and button to the ESP32

    All on the breadboard for now. Power both the HX711 and OLED from 3.3V.

    HX711 ESP32 OLED ESP32
    VCC 3.3V VCC 3.3V
    GND GND GND GND
    DT GPIO 16 SDA GPIO 21
    SCK GPIO 17 SCL GPIO 22

    Button: one leg to GPIO 25, the other to GND. Optional tare/calibrate
    button: GPIO 26 ↔ GND.

    The HX711 runs on 3.3V, never 5V.

  4. Annotated flashing diagram: the firmware config (Wi-Fi, HX711 pins, calibration factor) in the editor, an upload-complete bar, and HX711 Ready / WiFi OK / Time Synced / Ready checks Generated image, for reference only
    20 min

    Configure and flash the firmware

    Open firmware/ in PlatformIO, then:

    1. Copy the example config:
    cp firmware/src/config.h.example firmware/src/config.h
    
    1. Fill in your details:
    #define WIFI_SSID      "YourWiFi"
    #define WIFI_PASSWORD  "YourPassword"
    #define NOTION_TOKEN   "ntn_..."
    #define NOTION_DB_ID   "your32charhexid"
    #define GMT_OFFSET_SEC (-5 * 3600)   // your timezone (example: US Eastern)
    #define DST_OFFSET_SEC (3600)
    
    1. Build → Upload, open the serial monitor at 115200. You want:
      HX711 ready, WiFi OK, NTP time synced, Ready.
  5. Annotated calibration setup: hold the Tare/Cal button (GPIO 26), then press the ESP32's Reset button Generated image, for reference only
    10 min

    Calibrate once with a known weight

    The firmware can't know how your specific load cell + mount turn force into
    grams, so you teach it once.

    1. With the stand empty, hold the tare/cal button (GPIO 26) while
      pressing reset → it enters calibration mode and tares the empty platform.
    2. OLED: "Place weight: 250 g" → set your known weight down.
    3. It reads, computes the calibration factor, and saves it to flash.
    4. Back in normal mode: empty ≈ 0 g, your known weight ≈ 250 g.

    Calibration persists across reboots, so you only redo it if the mechanics change. Reading negative? Your signal pair is reversed: swap A+ and A−.

  6. Illustrated bench-test flow: tap to start, pour ~50 mL out, tap to stop, and the feed lands as a row in Notion Generated image, for reference only
    10 min

    Bench-test a fake feed

    Prove the whole loop before it ever touches a real bottle:

    1. Put a water bottle on the stand.
    2. Tap the button → OLED shows "Feeding…" with a live timer.
    3. Pour out ~50 mL of water (simulating what the baby drank).
    4. Put the bottle back, tap again → OLED shows "Fed ~50 mL".
    5. Check Notion: a new row with start / end / duration / volume should
      appear within a few seconds.

    Measure the poured water to confirm the volume lands within ±5 mL.

  7. print time

    Print the stand (in parallel)

    While you bench-test, print the stand. The one I designed is in
    Files & models
    below: download the STLs and print them. Or
    grab any load-cell scale-stand model on MakerWorld.

    Whatever model you pick, it must give the load cell a cantilever mount with
    an air gap
    so the beam can flex. Most scale-stand models already do.

  8. The finished stand: the round weighing platform on the 3D-printed case, with the start/stop buttons and OLED on the front
    30 min

    Mount everything onto the stand

    Per hardware/assembly.md: the load cell is cantilevered, one end bolted to
    the base and the other to the platform, with the HX711 close by and the ESP32,
    OLED, and button placed for one-handed use. Buttoned up, it looks like this.

    After mounting, re-verify an empty stand reads ≈ 0 and your known weight still
    reads right. The mechanical change can shift the tare, so just tap the tare button.

    The one detail that matters is a real air gap under the cantilevered load cell, so the beam can flex. No gap, no readings, so check it before you close the case up.

  9. The finished feed logger with its round weighing platform mounted, ready to use
    5 min

    Place it where bottles happen

    Counter, bottle station, or nightstand: somewhere flat, stable, and near
    power and Wi-Fi
    . Add a wipeable coaster on the platform for the inevitable
    milk drips.

  10. ongoing

    Use it for real

    Next bottle: set it down, tap, feed, set it down, tap. Open Notion, and your
    first real feed is logged, with the right time and volume. If you wired up
    Telegram, you'll also get a "🍼 Fed 165 mL in 18 min" ping.

    Because it logs start-minus-end weight, the bottle cancels out, so you never tare per bottle or tell it which one you're using.

Files & models

The stand I designed for this exact load cell and bottle. I plan to publish it on MakerWorld as a future v2; in the meantime, grab the STLs here and print them. Prefer something else? Any load-cell scale-stand model on MakerWorld works too.

  • Bottle Feeder stand (3 parts) STL · 3D model · 112 KB

    Base, top base, and bottle cover. Print in PLA or PETG. The print gives the load cell its cantilever mount with the all-important air gap.

    Download ZIP

If it misbehaves

Tuning & troubleshooting

  • Readings are jumpy
    Increase SAMPLES_PER_READING, kill surface vibration, and shorten the load-cell wires.
  • Volume is off by a constant factor
    Recalibrate with a more accurately measured known weight.
  • Tiny negative volumes on quick feeds
    Normal sensor noise; the MIN_FEED_ML guard already ignores them.
  • Empty stand drifts from 0 over hours
    Tap tare occasionally; per-feed subtraction makes the drift negligible anyway.
  • Wrong AM/PM or hour in Notion
    Check GMT_OFFSET_SEC / DST_OFFSET_SEC in config.h.

Make one

A weighing bottle stand that auto-logs how much your baby drank, when, and for how long, straight to Notion. No 3am phone tapping.