Skip to content

Scale Sense — ESP32-C3 PCB Design Brief

Revision: 1.3 (pre-layout) Branch: main Prepared for: Hardware / PCB fabrication handoff


1. Purpose

This document describes the custom PCB for the Scale Sense keg scale unit, targeting the Espressif ESP32-C3-MINI-1U module as the MCU. The -1U variant uses an external antenna via U.FL connector rather than an onboard PCB trace antenna. This is required for our deployment environment: scales mount inside metal walk-in coolers (Faraday cages) at bar locations. An external antenna on a short U.FL cable can be routed outside the enclosure or to the lid.

The design is derived from the Olimex ESP32-C3-DevKit-LiPo (reference schematic, Rev C) and adds the HX711 load cell amplifier, SSD1306 OLED display, and supporting power circuitry to produce a single, self-contained board.

Target volume: ~500 units (initial production run for US bar/restaurant market).


2. Functional block diagram

                    ┌─────────────────────────────────┐
USB-C (charge) ────►│  TP4056 (charge IC)              │
                    │  USB-C receptacle (5V/GND only)  │
                    └────────────┬────────────────────┘
                                 │ VBAT (3.7–4.2V nominal, 4.25V max)  ← always live when battery present
                    ┌────────────▼────────────────────┐
                    │  LiPo pouch cell (J1)            │◄──── TP4056 BAT pin charges here
                    │  3.7V 5000mAh, 10×54×60mm        │      regardless of SW2 position
                    └────────────┬────────────────────┘
                                 │ VBAT
                    ┌────────────▼────────────────────┐
                    │  SW2 — power switch (SPST)       │  OFF: load dead, charge still works
                    └────────────┬────────────────────┘  ON:  load powered
                                 │ VBAT (switched)
                    ┌────────────▼────────────────────┐
                    │  HT7333 LDO  →  3V3 rail         │
                    │  470kΩ/470kΩ divider → GPIO4     │
                    └────────────┬────────────────────┘
                                 │ 3V3
             ┌───────────────────▼───────────────────────────┐
             │           ESP32-C3-MINI-1U module              │
             │           (U.FL → external antenna)           │
             │                                               │
             │  GPIO0  ◄──── HX711 DOUT                      │
             │  GPIO10 ────► HX711 CLK                        │
             │  GPIO4  ◄──── BAT_ADC (divider midpoint)       │
             │  GPIO7  ◄───► SSD1306 SDA  (I2C)               │
             │  GPIO3  ────► SSD1306 SCL  (I2C)               │
             │  GPIO8  ────► STATUS LED (active high)          │
             │  GPIO18/19   USB D±  (programming only)        │
             │  GPIO20/21   UART0 RX/TX (debug header)        │
             └───────────────────────────────────────────────┘
                    ┌────────────▼────────────────────┐
                    │  HX711 breakout or onboard IC    │
                    │  E+/E−/A+/A− → 4-pin load cell   │
                    └─────────────────────────────────┘

3. Bill of materials (key components)

Ref Component Value / Part Notes
U1 MCU module Espressif ESP32-C3-MINI-1U-H4X External U.FL antenna — required for metal enclosure. 13.2×12.5×2.4 mm. Recommended SKU (−40~105°C, chip rev v1.1)
J5 Antenna connector U.FL (IPEX/MHF) SMD receptacle Molex 73412-0110 or equiv. Mates with pigtail to external 2.4GHz antenna
ANT1 External antenna 2.4GHz omnidirectional, U.FL pigtail e.g. Taoglas FXP73 (adhesive patch, fits enclosure lid) or rod antenna. Keep pigtail ≤150mm
U2 Load cell amp AVIA HX711 SOP-16
U3 LDO regulator Holtek HT7333-A SOT-23-3 3.3V, 250mA — NOT AMS1117 (wrong dropout/noise)
U4 LiPo charge IC TP4056 SOT-23-8 or TC4056 USB-C input, 1A max, Prog resistor for 500mA
J1 Battery connector JST PH 2.0mm 2-pin Design footprint with P+ on pin 1 (standard). Selected cell has reversed wiring — reseat wires before connecting (see constraint #11)
J2 Load cell connector 6-pin 2.54mm KK or screw terminal 4 cells wired in parallel: E+, E−, A+, A−, Shield, spare. All 4 cell E+ → pin 1, etc.
J3 USB-C receptacle 16-pin mid-mount 5V + GND only wired; D± to GPIO18/19 for JTAG/flashing
J4 Debug header 4-pin 2.54mm 3V3, GND, TX (GPIO20), RX (GPIO21)
D1 Charge indicator LED 0402 amber TP4056 CHRG pin — on while charging, off when complete
LED1 Status LED 0402 blue GPIO8, 1kΩ series
SW2 Power switch SPST slide or rocker, panel-mount, ≥0.5A 12V DC In series with VBAT → HT7333 path. Wires from PCB pad to panel-mount body. 2-pin PCB footprint on board edge
DISP1 OLED display SSD1306 128×32 I2C module 4-pin FPC or pin header — 3V3, GND, SDA, SCL
R1, R2 Battery divider 470kΩ 0402 1% VBAT → R1 → GPIO4 → R2 → GND
C1 Bulk cap 100µF electrolytic VBAT rail
C2 LDO bypass 10µF 0402 ceramic 3V3 rail
C3, C4 Decoupling 100nF 0402 ceramic U2 VCC, U1 3V3
C5 TP4056 Vcc bypass 100nF 0402 Per datasheet

Cost note: At volume, the ESP32-C3-MINI-1U is ~$2–3. HX711 ~$0.30. TP4056 ~$0.15. Total BOM target: < $12 (excluding LiPo cell, enclosure, and antenna).


4. Subcircuit details

4.1 Power — LiPo charge + regulation + switch

USB-C 5V ──► TP4056 IN
             TP4056 BAT ↔ LiPo cell (J1)   ← charge path, always active with USB

VBAT (from cell) ──► SW2 (power switch) ──► HT7333 IN ──► 3V3 rail

Switch truth table:

SW2 USB present System Charging
OFF No Off No
OFF Yes Off Yes — TP4056 charges cell through the BAT pin regardless of SW2
ON No Running on battery No
ON Yes Running Yes

The TP4056 BAT pin connects directly between the charger IC and the cell — it is not in the SW2 switched path. SW2 only interrupts current flowing into the HT7333 LDO. This is the key layout constraint: the cell, J1, and TP4056 form a loop that must remain intact independent of SW2.

Battery specs (selected cell):

Parameter Value
Chemistry Lithium Polymer (LiPo pouch)
Capacity 5000 mAh
Nominal voltage 3.7V
Max charge voltage 4.25V
Max charge current 2500mA (2.5A)
Physical (T×W×L) 10 × 54 × 60mm
Connector JST PH 2.0mm — CAUTION: polarity reversed (− on pin 1, + on pin 2). Reseat wires before connecting
Cable length 50mm

Runtime estimate: With power optimisations (HX711 sleep between readings, OLED on between updates, WiFi MAX_MODEM sleep, connect/disconnect MQTT pattern, delta publishing): ~15–20mA average. 5000mAh ÷ 17mA ≈ 290h ≈ ~12 days per charge. Without those optimisations (spinning loop, HX711/OLED always on, MIN_MODEM): ~100mA → 2 days. See firmware v0.3.8+ for the optimisations. Battery life test pending on dev hardware.

Charge rate: TP4056 at 1A (R_prog = 1.2kΩ) = 0.2C — well within cell's 2.5A max. Conservative and safe. Full charge from empty ≈ 5h.

Charge termination voltage: TP4056 terminates at 4.2V. Cell's max is 4.25V. TP4056 will stop at 4.2V — safe, slightly under-charges (~97% capacity), which is better for long-term cycle life. Do not modify the TP4056 to target 4.25V.

  • TP4056 charge current: set with R_prog = 1.2kΩ → 1A charge rate. Reduce to 2.4kΩ (500mA) if thermal headroom is tight in enclosure.
  • SW2 must be rated for battery current: ≥0.5A at 5V DC. System peak ~200mA (WiFi TX burst). A standard mini rocker or slide switch handles this easily.
  • SW2 wires: short as practical, 26AWG minimum. Place PCB pads on board edge adjacent to the enclosure cutout for the switch body.
  • HT7333: input cap 10µF + 100nF, output cap 10µF + 100nF. Place close to U1.
  • VBAT and 3V3 are separate rails. Do not connect them downstream.
  • VBAT powers the HX711 AVDD (3.7–4.2V is fine per HX711 datasheet 2.6–5.5V). Alternative: power HX711 AVDD from 3V3 for consistency — either works.

4.2 Battery voltage sense

VBAT ──► R1 (470kΩ) ──┬──► GPIO4 (ADC1_CH4)
                      R2 (470kΩ) ──► GND
  • Ratio: 0.5 — at 4.2V (TP4056 termination), GPIO4 sees 2.1V. At 4.25V cell max, GPIO4 sees 2.125V. Both well within 3.3V ADC range.
  • Use 1% resistors. 5% tolerance gives ±100mV error at full charge.
  • Add 100nF cap from GPIO4 to GND to reduce ADC noise.
  • Wire directly to GPIO4 (ADC1_CH4) as above. Do NOT use GPIO5 — it is ADC2_CH0, which is disabled during WiFi operation (hardware limitation of the ESP32-C3 SoC). This is also why the Olimex dev kit's BAT_SENS_E1 jumper must not be soldered on the dev board; on this custom PCB, simply avoid GPIO5 for any analog function.

4.3 HX711 load cell amplifier

Load cell (4-wire Wheatstone) ──► HX711:
  E+ → AVDD (excitation +)
  E− → AGND (excitation −)
  A+ → INA+ (signal +, channel A)
  A− → INA− (signal −, channel A)

HX711 digital interface:
  DOUT → GPIO0  (ESP32-C3 input)
  SCK  → GPIO10 (ESP32-C3 output)
  VCC  → 3V3
  DVDD → 3V3
  AVDD → VBAT or 3V3 (tie AVDD to 3V3 for consistency)
  AGND, DVDD → GND
  • Channel B is unused; leave INA+/INB+ open or tied to GND.
  • HX711 RATE pin: tie LOW (pin 15) for 10 SPS (less noise, preferred for scale). Tie HIGH for 80 SPS only if faster reads are needed during calibration.
  • Decouple HX711 AVDD with 10µF + 100nF close to pin.
  • Keep HX711 analog traces short; pour analog GND under HX711.
  • Add 4-pin connector (J2) for load cell wires: E+, E−, A+, A−.

4.4 OLED display (SSD1306 128×32)

  • I2C address: 0x3C (SA0 pin = GND)
  • SDA → GPIO7, SCL → GPIO3
  • Pull-ups: 4.7kΩ to 3V3 on both lines. If using an OLED module with onboard pull-ups, do not add external ones (double pull-up causes issues).
  • Power: 3V3. Add 10µF bypass cap on OLED Vcc.
  • Interface options: 4-pin FPC connector or 4-pin 1.27mm header for flat cable.

4.5 Status LED

  • GPIO8 → 1kΩ → LED anode → LED cathode → GND
  • Blue 0402 LED (Vf ≈ 3.0V, If ≈ 3mA at 1kΩ with 3.3V supply)
  • Firmware drives active high.

4.6 USB-C connector

  • Wire VBUS (pin A4/B4) → TP4056 IN (charge only).
  • Wire GND (A1/B1) → GND.
  • Wire D+ (A6) → ESP32-C3 GPIO19, D− (A7) → GPIO18 (JTAG/flashing over USB).
  • CC1, CC2: 5.1kΩ pull-downs to GND each (tells host this is a 5V/0.9A device).
  • No USB data switch needed — USB-C ↔ ESP32-C3 native USB is direct.

4.7 USB VBUS sense

When USB is connected, VBUS is 5V. The battery ADC will read the TP4056 output (~4.2V) rather than the real battery state. Firmware suppresses battery reporting and shows "charging" instead when it detects USB presence.

VBUS ──► R (100kΩ) ──┬──► GPIO1
                    R (100kΩ) ──► GND
  • Divider midpoint = 2.5V when USB present (5V), 0V when absent. Both within ADC range.
  • 100kΩ/100kΩ values — high impedance keeps idle draw < 25µA.
  • GPIO1 configured as INPUT in firmware (no internal pull-up/down needed).
  • Firmware reads HIGH (≥2.5V) = USB present; LOW (0V) = battery only.
  • Add 100nF cap from GPIO1 to GND for noise filtering.

5. GPIO assignment summary

GPIO Direction Function Notes
GPIO0 Input HX711 DOUT Digital only, no ADC needed
GPIO3 Output I2C SCL (SSD1306) 4.7kΩ pull-up to 3V3
GPIO4 Input Battery ADC ADC1_CH4 — external 470kΩ/470kΩ divider
GPIO7 Bidirectional I2C SDA (SSD1306) 4.7kΩ pull-up to 3V3
GPIO8 Output Status LED Active high, 1kΩ series
GPIO10 Output HX711 CLK Digital only
GPIO18 Bidirectional USB D− Native USB / JTAG
GPIO19 Bidirectional USB D+ Native USB / JTAG
GPIO20 Output UART0 TX Debug header J4
GPIO21 Input UART0 RX Debug header J4
GPIO1 Input USB VBUS sense 100kΩ/100kΩ divider from VBUS — HIGH = USB present, LOW = battery only

Do not use: GPIO5 (ADC2 — broken during WiFi), GPIO11–17 (internal flash SPI on ESP32-C3-MINI-1U — not bonded to module pads but reserved).


6. Mechanical / form factor

6.1 Overall assembly concept

The Scale Sense unit uses the DeVault Enterprises ICD2000 keg stacker ring as the structural base. The ring cross-section is a moat/bathtub shape — flat platform on top, outer ring wall hangs down on the outside, inner ring wall hangs down on the inside, with an annular gap between them where the pucks sit. The outer ring is taller than the inner ring.

  ←──────────── outer OD ~415mm ──────────────→
           ←──── inner OD ~335mm ────→
  ────────────────────────────────────────────  ← platform top (upper keg sits here)
  │  │←────── annular gap ~40mm ──────→│  │
  │  │         (4 pucks go here)       │  │
  │  │                                 │  │
  │  └─────────────────────────────────┘  │    ← inner ring base  (20mm tall)
  │                                        │
  └────────────────────────────────────────┘    ← outer ring base (30mm tall)

There are three variants — same electronics, same pucks, puck height differs:


Variant 1 — Keg on keg (stacked cooler setup)

Bottom keg fits up inside both rings and contacts the platform underside. Pucks sit in the annular gap on the bottom keg's top surface.

  ──────────────────────────────────────  ← platform top (upper keg above)
  │  │  [puck]  [puck]  [puck]  [puck]│  │  ← pucks in annular gap
  │  │  on bottom keg top surface     │  │
  │  └───────────────────────────────-┘  │  ← inner ring (inside bottom keg)
  │        ← bottom keg body →           │  ← outer ring (around bottom keg)
  ──────────────────────────────────────     ← bottom keg top (keg not weighed)

Puck height: any — shorter is better for stability. Just needs to fill the gap between the bottom keg top surface and the platform underside.


Variant 2 — Floor standing (single keg, no bottom keg)

Without pucks, the outer ring base contacts the floor first (tallest point). Pucks must protrude below the outer ring base to lift it off the floor.

  ──────────────────────────────────────  ← platform top (keg above)
  │  │  [puck]  [puck]  [puck]  [puck]│  │  ← pucks in annular gap
  │  │                                │  │     pucks extend below outer ring base
  │  └───────────────────────────────-┘  │  ← inner ring (raised off floor)
  │         [puck feet]                  │
  └──────────│──────────────────────│────┘  ← outer ring base (lifted by pucks)
        ─────┼──────────────────────┼──────  floor

Puck height > outer ring leg length. Outer ring lifts clear of floor.


Variant 3 — Dolly (mobile setup, DeVault 3000 or similar)

The dolly is taller than the outer ring leg length, so the outer ring dangles free. The inner ring makes first contact with the dolly platform (without pucks). Pucks protrude below the inner ring base to lift it off the dolly platform.

  ──────────────────────────────────────  ← platform top (keg above)
  │  │  [puck]  [puck]  [puck]  [puck]│  │  ← pucks in annular gap
  │  │                                │  │     pucks extend below inner ring base
  │  └────────────────────────────────┘  │  ← inner ring (lifted off dolly by pucks)
  │         [puck feet on dolly]         │
  │    ──────────────────────────────    │  ← dolly platform
  │                                      │
  └──────────────────────────────────────┘  ← outer ring dangles free (no contact)
              │   caster   │

Puck height > inner ring leg length. Outer ring hangs free — no lateral constraint from the ring in this variant (dolly provides its own stability).


Puck height summary:

Variant Puck height requirement Practical target
1 — keg on keg Any. Shorter = better stability ~10–15mm
2 — floor > 30mm (outer ring height) ~35mm
3 — dolly > 20mm (inner ring height) ~25mm

Measured ICD2000 dimensions (physical ring): - Outer ring height: 30mm - Inner ring height: 20mm - Annular gap width (inside outer to inside inner): 40mm — puck footprint must fit within this - Overall diameter: ~415mm (16")


Electronics housing (same for all variants) — bolted to outside of ICD2000 ring:

  ┌──────────────────────────────────────────┐
  │ [OLED] [●CHG] [●STATUS]                   │
  │                         [USB-C]  [SW2 ↑] │
  └──────────────────────────────────────────┘

What is being measured: ICD2000 ring weight + keg weight. Ring tare (~1.3–3 lbs) is constant — subtracted automatically during tare procedure (tare_empty with empty ring on pucks, tare_full with ring + full keg).

Critical requirement for all variants: The ICD2000 platform must rest only on the 4 puck top plates — no other surface contact. Any bypass contact carries load and causes under-reading.

6.2 Load cell pucks

Load cell spec: - 4× bar-type load cells, rated 50 kg each (200 kg / 440 lbs combined — well above the 161 lbs max for a full half-barrel) - Prefer 1kΩ bridge resistance cells — lower excitation current at 3.3V AVDD (~13mA at 1kΩ vs ~38mA at 350Ω). Either works; firmware power_down limits active time to ~400ms per 60s cycle regardless.

Puck housing (per cell — 4 required):

         ┌─────────────────────┐  ← top plate (~50×50×5mm aluminium)
         │   ring base contact  │    ICD2000 ring underside rests here
         └──────────┬──────────┘
                    │ load point (center of bar cell free end, facing UP)
         ┌──────────▼──────────┐
         │   bar load cell      │  ~80×13×13mm typical 50kg bar cell
         └──────────┬──────────┘
                    │ fixed end bolted to bottom plate
         ┌──────────▼──────────┐  ← bottom plate (~50×50×5mm aluminium)
         │  bottom keg contact  │    sits on flat top rim of bottom keg
         └─────────────────────┘
- Top and bottom plates: ~50 × 50 × 5mm aluminium - Bolt pattern: 2× M4 through bottom plate into load cell fixed end; load point contacts top plate via a small dome or set-screw - Cable exits from side of puck, routes up outside of ring wall to housing - Rubber pad on bottom plate to grip keg top surface and prevent sliding

Wiring: - Each puck has a short 4-wire cable (E+, E−, A+, A−) - All 4 cables parallel at a small junction point inside the ring (terminal block or junction PCB) before a single 6-wire cable exits through the ring wall to J2 - This keeps 4 cables inside the ring and only 1 cable reaching the electronics housing - J2 connector: 6-pin, 2.54mm or Molex KK — E+, E−, A+, A−, Shield, spare

6.3 Electronics housing

The electronics housing mounts on the outside wall of the ICD2000 ring. It is not constrained by the ring height — it can extend above the ring top as needed.

PCB target size: 60 × 40mm. 2-layer is sufficient.

Housing height constraint: ≤ 30mm — must not exceed the outer ring height so the assembly sits flush. This is tight: battery (10mm) + PCB with components (~12mm) + housing walls (~2mm each side) = ~26mm internal. Achievable with low-profile SMD components. Confirm component heights before finalising housing.

Internal layout (PCB + battery): - Battery (10 × 54 × 60mm) and PCB (60 × 40mm) sit side by side or stacked. Minimum housing internal floor: ~65 × 65mm side-by-side, or ~65 × 105mm stacked. - Battery sizing: current cell is 5000mAh. May downsize once overnight battery life test on dev prototype is confirmed — smaller cell reduces housing footprint. Do not finalise housing dimensions until test is complete.

Housing face (user-visible):

Feature Position Notes
OLED (128×32) Top-left of face Window cutout with light diffuser or direct viewing hole
D1 — CHG LED (amber) Right of OLED TP4056 CHRG pin — on while charging, off when complete. 3mm LED or light pipe
LED1 — Status (blue) Right of D1 GPIO8 — identify flash / maintenance pulse / OTA. 3mm LED or light pipe
USB-C (J3) Bottom-right of face Flush or recessed; IP-rated plug cover for cooler use
SW2 (power switch) Bottom-left of face Panel-mount rocker or slide; accessible without tools

Housing construction: ABS or polycarbonate, IP54 minimum (cooler condensation). Mount to ring wall with 2–4× M4 bolts through ring wall, or stainless hose-clamp if drilling the ring is undesirable.

Connector placement on PCB: - J1 (battery): inner edge, JST PH2.0 — short fly lead to battery in housing - J2 (load cell): bottom edge — 6-pin, wires pass through ring wall grommet - J3 (USB-C): aligns with housing face cutout - J4 (debug header): internal — not accessible through housing face - SW2 pads: near bottom-left edge — short fly leads to panel-mount switch

Layer count: 2-layer. Keep HX711 analog section (left) separated from MCU (right). GND pour on both layers, stitched with vias.

Mounting holes: 4× M3, one per corner, 3mm from edge.

6.4 Antenna

  • U.FL receptacle (J5) on PCB board edge nearest housing antenna exit
  • ≤150mm RG178 pigtail to external antenna
  • Antenna mounts on outside face of housing or ring wall — not inside the housing
  • Keep pigtail away from load cell wires (RF interference on HX711 analog lines)

6.5 Height budget (ring interior, puck stack)

Puck top plate:          ~5mm
Load cell body height:   ~13mm  (typical 50kg bar cell)
Puck bottom plate:       ~5mm
Ring floor to ring top:  38–76mm (ICD2000 range)
─────────────────────────────────────────────
Puck total height:       ~23mm  ✓ (well within 38mm minimum ring height)
Remaining clearance:     ~15–53mm above puck to ring top edge

Keg bottom rim should contact puck top plates, not the ring top edge. If puck height + keg rim clearance is tight, shim the puck bottom plates.


7. Design constraints and gotchas

# Constraint Why
1 Use HT7333, not AMS1117 AMS1117 has insufficient noise rejection for ADC accuracy; wrong dropout for 3.3V from 3.7V LiPo; we got burned replacing these on prototype boards
2 Battery ADC must use GPIO4 (ADC1), not GPIO5 ESP32-C3 ADC2 is disabled when WiFi radio is active; GPIO5 routes to ADC2
3 470kΩ divider resistors, not 100kΩ Lower power draw — at 4.2V, 470kΩ pair draws ~4.5µA vs ~21µA with 100kΩ. Matters in modem-sleep
4 HX711 RATE pin LOW 10 SPS reduces quantisation noise for a scale; 80 SPS only needed in bench test rigs
5 Use ESP32-C3-MINI-1U, not MINI-1 Scales mount inside metal walk-in coolers (Faraday cages) — onboard PCB antenna (MINI-1) is blocked. MINI-1U routes RF out via U.FL pigtail to an antenna outside the enclosure. Bonus: MINI-1U is 4mm shorter (no antenna protrusion), and requires no keepout zone on the host PCB
6 U.FL connector placement on board edge Short pigtail (≤150mm RG178) to external antenna. Mount J5 near the enclosure wall exit. Do not route high-current traces under U.FL pad
7 GPIO9 strapping pin Must be HIGH at boot. No button connected — leave GPIO9 unconnected or pull HIGH. Do NOT tie it permanently low
8 No deep sleep Firmware uses modem sleep only (BLE + MQTT must stay alive). Power saving comes from C3's lower sleep current, not from deep sleep mode
9 CC resistors on USB-C 5.1kΩ pull-downs required on CC1 and CC2 for USB-C host to detect and supply power
10 SW2 must NOT interrupt the TP4056 BAT–cell path The charge loop (TP4056 BAT ↔ cell) must stay intact when SW2 is open. SW2 only breaks VBAT → HT7333. If SW2 is wired incorrectly (in series with the battery, before the TP4056 BAT node), charging will not work when the unit is switched off — which is the primary charging use case (shipped off, plugged in to pre-charge)
11 J1 LiPo polarity — reseat wires before connecting PCB footprint has P+ on pin 1 (standard). The selected cell (Amazon B0GL1MH5YT) ships with reversed wiring (− on pin 1, + on pin 2). Plugging in reversed will likely destroy the TP4056 and may damage the cell. Reseat the wires in the JST housing before first connection. Confirm against actual cell before layout sign-off
12 LED1 wired active-high GPIO8 → 1kΩ → LED → GND. Firmware production env must NOT include -DLED_ACTIVE_LOW (that flag is only for the Olimex dev board, where the LED is wired active-low)

8. Firmware context (for hardware verification)

The firmware is PlatformIO / Arduino framework. Key configuration once PCB is populated:

// firmware/include/config.h — production PCB pin mapping (add to BOARD_ESP32_C3 block)
#define PIN_HX711_DOUT  0
#define PIN_HX711_CLK   10
#define PIN_BATTERY_ADC 4
#define PIN_USB_SENSE   1   // add when PCB is built — not present on dev board
#define PIN_LED         8
#define PIN_I2C_SDA     7
#define PIN_I2C_SCL     3

#define BATTERY_DIVIDER_RATIO 2.0f   // 470k/470k divider

Note: the production PCB firmware env should not include -DLED_ACTIVE_LOW (LED1 is wired active-high on the PCB). The dev board env uses this flag because the Olimex board wires GPIO8 active-low.

Note: the production PCB firmware env should not include -DARDUINO_USB_CDC_ON_BOOT=1. That flag is required on the dev board for USB serial monitor, but it prevents esp_light_sleep_start() from engaging (light sleep powers down the USB peripheral and panics the CDC stack). Without it, light sleep works correctly on production hardware. Initial firmware flashing on the production PCB should be done via the UART debug header (J4) using esptool.py; subsequent updates go via OTA.

Build target: esp32-c3-devkitm-1 in PlatformIO. The ESP32-C3-MINI-1U uses the same ESP32-C3 SoC as the MINI-1 — PlatformIO board ID, firmware, and all GPIO assignments are identical. The only physical difference is the antenna.

Hardware bring-up checklist (in order): 1. Power: measure 3V3 rail with no MCU populated — confirm HT7333 output. 2. Charge: plug USB-C, confirm D1 amber LED lights, cell voltage rises. 3. Boot: flash firmware via USB-C (no programmer needed — native USB DFU). 4. HX711: confirm stable weight readings over serial (unloaded + loaded). 5. Battery ADC: read GPIO4, verify maps to correct voltage (expect ~2.1V at 4.2V cell). 6. USB sense: plug/unplug USB-C, confirm GPIO1 reads HIGH/LOW; firmware shows "charging" on OLED when USB present. 7. OLED: confirm display renders beer name + level bar. 8. BLE: scan from phone, confirm SCALE-xxxx advertises. 9. WiFi + MQTT: connect to Pi AP, confirm readings publishing. 10. Power meter: measure modem-sleep current — target < 10mA average.


9. Reference documents

  • Espressif ESP32-C3-MINI-1 & MINI-1U datasheet v2.1 (covers both variants): https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf
  • Espressif ESP32-C3-MINI-1U Reference Design (Altium — schematics, PCB layout, Gerbers, BOM): https://www.espressif.com/sites/default/files/documentation/ESP32-C3-MINI-1U_Reference_Design.zip Use this for the module footprint and land pattern in Altium. This is the primary hardware design resource for the custom PCB.
  • Olimex ESP32-C3-DevKit-LiPo schematic (KiCad Rev C — circuit reference only, not Altium): https://github.com/OLIMEX/ESP32-C3-DevKit-LiPo
  • HX711 datasheet (AVIA Semiconductor)
  • HT7333 datasheet (Holtek)
  • TP4056 datasheet
  • SSD1306 datasheet (Solomon Systech)
  • Scale Sense firmware repo: https://github.com/scale-sense/keg-scale — firmware/ directory, branch main