Phone HW Addon Base
📅 2026.07.18
Description
The idea for this project was to design a wireless and extendable hardware interface for phones.
The project can be divided into 3 parts; base board, extension boards and a phone app. This post covers the base board and phone app prototypes.
- Base board includes MCU/bluetooth module, Li-Po battery charger and a 20pin extension header.
- Phone app connects to the base board's bluetooth module, shows some information about firmware/battery status and shows the correct view for the connected extension board.
- Extension boards will connect to the base board's 20pin connector to add functionality. I will do a separate post in the future about this, since it's much more complex than the base board
Reason for dividing the PCB into 2 parts was to avoid the need to re-do the MCU and battery charger parts each time when adding new HW functionality. I was also thinking about designing this to be even more modular by allowing different HW extension boards to be chained together so that you could create different functionality combinations, but I felt like it requires a lot more design and the current method is simpler and easier to get at least something working soonish.
Pictures
PCBs
Base board on the left. Right one is a BUS sniffer extension board.

3D view top
3D view bottom
Assembling the boards
Components placed, before reflow oven

Powering on the boards
Powering on for the first time after basic measurements to make sure nothing's shorting.
I powered it on throught the USB-A breakout board that's connected to a bench power supply so that I can control the current limit.

Testing
Testing if the MCU is working by using the nRF Connect software to read the MCU memory.

Zephyr booting up and RTT debugging works using the J-Link mini
"SEGGER J-Link V9.24a - Real time terminal output
SEGGER J-Link (unknown) V2.0, SN=802009513
Process: JLink.exe
*** Booting nRF Connect SDK v3.3.0-ba167d9f3db4 ***
*** Using Zephyr OS v4.3.99-fd9204a02d52 ***
Hello from my board!
[00:00:00.013,821] <inf> app: Tick
[00:00:01.018,894] <inf> app: Tick
[00:00:02.024,047] <inf> app: Tick
[00:00:03.029,119] <inf> app: Tick
Battery charging didn't seem to work initially due to faulty (or scam?) batteries that I ordered from aliexpress.
Charger's CE pin soldered directly to GND here as a debugging measure, eventhough it should have a internal weak pull-down resistor. No help tho, but will need to route it to GND for rev.B.

I found another old 300mAh Li-Po battery from a box and the charging works fine with it.
There's just the through hole 10k resistor to bypass the battery pack temperature measurement, couldn't find 10k SMD component for it.

Charger is configured for max. 800mA charge current. The batteries that were meant to be used are 1500mAh.

Phone app
Preliminary phone app. It shows the charge current and there's a switch to toggle the user LED on/off and
there's a user button state that updates once pressed. I also tested the I2C bus by connecting a BME280 temperature sensor to it.

Power profiler
I placed a current measurement header to the base board where I can connect the nordic power kit 2 -power profiler.

~350uA idle current, ~5mA pulses when advertising in disconnected state, ~12mA pulses when transmitting data in connected state

Schematics
USB
Power-only USB. The Nora B2 module doesn't have USB and I decided that at least the first versions will communicate with the phone app using bluetooth only.

Power
MCU
Connector
BOM
Design notes
Design choices
- Keep the base board as simple as possible to test the nordic ecosystem
and expose IOs to a header.
- For now the header could be just a generic 2.54 pitch jumper wire connector,
but for future versions it could be more targeted proper connector to connect
daughter boards to the base board.
- Base board would basically be:
- Nordic NORA-B20
- USB-C ( power only )
- BQ24074 ( battery charger ) + regulator and related components
- Battery connector
- SWD header
- Status LEDs + user controllable LED
- Button
- 20-pin expansion connector
- Use Zephyr for the firmware
- Use Android Studio for the phone app
PCB rules
- PCB thickness: 1.6mm
- Copper layers: 4
- Layer 1: Signal
- Layer 2: GND
- Layer 3: Power
- Layer 4: Signal
- Keep-out area on all layers below the BLE module antenna
- Signal traces
- 0.25mm width
- 0.2mm clearance
- Power traces
- max. 1A
- 0.5mm width ( 0.35mm recommended on outer layers. 0.9mm in internal,
which can't fit between charger pins, so need to route the charger
current path on upper layer )
- 0.3mm clearance
- Copper thickness
- Outer layers: 1oz
- Inner layers: 0.5oz
- https://tracewidthcalculator.com/
MCU / BLE
- U-blox Nora B2 ( NORA-B206-00B )
- Contains Nordic Semiconductor nRF54L15 + certified antenna RF circuit
and the 32MHz oscillator
- Risky to design the antenna myself and the Nordic's reference design is
9 layer board, so it's easier to use the u-blox module that costs
few € extra and has a working RF design.
- Nora B2 module doesn't include external slow clock.
- External 32kHz oscillator can be added to XL1 XL2 connectors
- Use the same one from the evaluation board:
https://www.digikey.fi/en/products/detail/epson/FC-135-32-7680KA-AC0/2834057
- The device can be used with external capacitors C1 and C2 or the
built-in configurable internal capacitors CINT
- Add placeholder footprints for external caps but leave them unpopulated
at least for now and use the configurable internal caps
- Also add 0R resistors between crystal and MCU pins to detach it if needed
- 'No connection'-pins: A2, A4, C9, D3, D7, D9, E3, E7, F3, F7, H1, H3, H7, J1, J4, J5, J7
- mark with 'no connect'-flag
- Left-over pins: B5, C5, C8, D1, D8, E9, F1, F2, G7
- Configure as digital output and drive them low
- mark with 'no connect'-flag
- SWD header pins:
- SWDIO
- SWCLK
- GND
- VREF
- RESET
- SWO (optional for trace logging)
- Reset button
- Bootmode jumpers?
- Flashing
- The J-Link SWD header is used to flash the MCU.
Alternatively BLE DFU (Device Firmware Update ) is an option as well
for OTA updates with MCUboot.
- Logging
- Route at least one UART to GPIO headers
- Enable RTT in SWD header
- Sleep
- Add configurable sleep time when no activity detected in any interface
- User button is routed to MCU pin H9 which is part of Port 1 power domain,
which can wake up the system up from System OFF state
- Retrospective:
- JLCPCB can manufacture all the way down to 0.09mm traces @ 1oz thickness,
which would have fit between MCU pins on top layer.
- With 1oz thickness they can carry up to 370mA
- Via drill size 0.15mm and 0.3mm via diameter is possible in JLCPCB,
but require some extra kelvin test that cost +60€ extra.
So make sure that Kicad constraints settings have at least 0.2mm
drill size and 0.45mm via diameter
USB-C
- Power only, nordic nRF54L15 series doesn't have USB
- Allow up to 800mA fast charging with static CC1/CC2 sensing / input current config
- CC1 and CC2 ( channel configuration ) must have a 5.1kΩ pull-down resistors
- 100R ferrite bead ( MPZ1608S101ATAH0 )
- 1A resettable polyfuse ( SMD0805B035TF )
- Hold current 1A
- Trip current 1.8A
- Connect shield straight to GND
- Part: USB4110-GF-A
- Current rating: 5.00A collectively for VBUS pins
- 6.25A collectively for GND pins
- 1.25A for VCONN
- 0.25A for all other pins, per pin
Power management
- Uses a power path design with BQ24074 to allow MCU to also
power on directly bypassing the battery
- USB 5V -> BQ24074 charger -> 3.3V regulator -> Nora-B20
|--> LiPo battery
- If battery dies, the device still works
- Alternatively simpler design could be used:
- USB 5V -> MCP73831 charger -> LiPo battery -> 3.3V LDO regulator -> Nora-B20
- MCU is always powered on with the battery
- Cheaper than the BQ24074 ( 0.65€ vs. ~2.15€ )
Charger
# High-frequency decoupling ( ceramic ):
- In: 1uF
- Out: 4.7uF
- Bat: 4.7uF
# LED Status:
- Connect a 1.5-kΩ resistor in series with a LED between OUT and CHG to indicate charging status.
- Connect a 1.5-kΩ resistor in series with a LED between OUT and PGOOD to indicate when a valid input source
is connected.
- Maybe route the statuses to MCU GPIOs to display the states in software as well
# Tie EN1 to ground and EN2 to OUT to allow 900mA charging
- EN1 and EN2 are internally pulled down with 285 kΩ
- Current limit config:
EN2 0, EN1 0: 100mA, USB100 mode
EN2 0, EN1 1: 500mA, USB500 mode
EN2 1, EN1 0: Set by an external resistor from ILIM to VSS
EN2 1, EN1 1: Standby (USB suspend mode)
- Alternatively connect EN1 and EN2 to MCU for dynamic input current limit configuration
# Fast charging config ( ISET resistor ) for 800mA charging:
R ISET = K ISET / I CHG
K ISET = 890 AΩ from the electrical characteristics table
R ISET = 890 AΩ / 0.8 A = 1.1125 kΩ
- Select the closest standard value, which for this case is 1.13 kΩ. Connect this resistor between ISET (pin 16)
and VSS.
# Input current limit config ( ILIM ) 900mA
R ILIM = K ILIM / II_MAX
K ILIM = 1550 AΩ from the electrical characteristics table
R ISET = 1550 AΩ / 0.9 A = 1722Ω
- Select the closest standard value, which for this case is 1.74 kΩ. Connect this resistor between ILIM (pin 12) and
VSS.
# Termination current threshold config ( ITERM ) 80mA
R ITERM = I TERM * R ISET / 0.030
R ISET = 1.13kΩ from the above calculation
R ITERM = 80mA * 1.13kΩ / 0.030 = 3013Ω
- Select the closest standard value, which for this case is 3.01 kΩ. Connect this resistor between ITERM (pin 15)
and VSS. Note that when in USB100 mode (EN1 = EN2 = VSS), the termination threshold is 1/3 of the normal
threshold
# Safety timer config ( RTMR ) 6.25h
R TMR = t MAXCHG / (10 * K TMR)
K TMR = 48 s/kΩ from the electrical characteristics table
R TMR = (6.25 hr × 3600 s/hr) / (10 × 48 s/kΩ) = 46.8 kΩ
- Select the closest standard value, which for this case is 46.4 kΩ. Connect this resistor between TMR (pin 14)
and VSS.
# Charging current monitoring:
- Accuracy +-10%
- When the charger is enabled, internal circuits generate a current proportional to the charge current at the ISET
input. The current out of ISET is 1/400 (±10%) of the charge current. This current, when applied to the external
charge current programming resistor, RISET, generates an analog voltage that can be monitored by an external
host to calculate the current sourced from BAT
V ISET = I Charge / 400 * R ISET
= ( 0.8A / 400) * 1.13kΩ = 2.26V
- Connect ISET to available ADC pin
- Add for example 100nF cap for filtering the ADC
- t = 1.13k * 100nF
= t = 113µs time constant
= 113µs * 5 Multiple of the time constant
= 0.565 ms charging time
Battery level monitoring
- Battery level can be roughly estimated by measuring the battery voltage level.
Note that voltage changes under load, so try to do the measurement in between
sending data over BLE.
- Uses one ADC pin that's connected to a voltage divider with 2 resistors with the same value,
for example 1MΩ. Lowering the value would increase the current draw and increasing
the value would make the voltage estimation more inaccurate. Also note that there's ~178mV voltage dropout
at 250mA in the LDO regulator, so regulated 3.3V output should stops at 3.478V.
Lower than that; it becomes battery voltage level - voltage dropout
- Voltage divider needed to drop the max 4.2V battery charge to MCU power level ( 3.3V )
- Approximate:
- 4.2V = 100%
- 4.0V = 80%
- 3.8V = 50%
- 3.6V = 15%
- 3.3V = nearly empty
- 4.2V / 2 = 2.1V full, 3.3V / 2 = 1.65V = ~0%
- With 470kΩ voltage divider, current draw of the battery level measurement would be:
4.2V / ( 470kΩ * 2 ) = 4.47 µA
- Use GPIO to enable measurement to prevent continuous current draw?
- Battery -> 470kΩ -> 470kΩ -> GPIO ( Switch to low to close the circuit briefly before the ADC measurement )
|-> ADC -> 10nF -> GND ( Cap for filtering noise )
- Time to charge the 10nF cap:
= t = R * C
= t = ( 470kΩ / 2) * 10nF
= t = 2.35 ms time constant
= 2.35ms * 5 time constant multiplier
= 11.75ms charging time
= wait for 15ms after GPIO enable and before measurement
- Zephyr battery voltage measurement support: https://docs.zephyrproject.org/latest/samples/boards/nordic/battery/README.html
- ( Maybe ) Fuel gauge MAX17048 for estimating battery charge
- Adds ~2.7€ to the design
- Probably not going to need this for this design since estimating battery life precicely is not that crucial here.
LiPo battery
- 950mAh
- Has PCM ( Protection Circuit Module ):
- Overcharge protection
- Overdischarge protection
- Overcurrent protection
- Short-circuit protection
- Supports 950mA charging, but maybe adjust the charger limit to around 800mA
- Add B3B-PH-K-S 3 pin through hole male connector for pcb
- PHR-3 female connector in the battery wires
- Length: 53mm, Width: 34.5mm, Thickness: 5.4mm - 5.8mm, Wire length: 70mm
Battery temperature monitoring
- Add 3rd pin for NTC as the middle pin:
- 1 = BAT+
- 2 = NTC
- 3 = BAT-
- From the BQ24074 datasheet:
The BQ2407x features an external battery pack temperature monitoring input. The TS input connects to the
NTC thermistor in the battery pack to monitor battery temperature and prevent dangerous over-temperature
condition
- Solder jumper / 0Ω resistor to bypass the temperature monitoring?
- "For applications that do not require the TS monitoring
function, connect a 10-kΩ resistor from TS to VSS to set the TS voltage at a valid level and maintain charging."
- This way the device could still function with 2 wire LiPo packs
- Maybe the footprint could be added for the TS -> 10k -> VSS and not populate it.
Then if 2pin battery is used, solder the 10k resistor in place
Regulator
- 1.6 μA Typical Quiescent Current ( idle current )
- ~178mV Dropout voltage @ 250mA
- 2.3V - 6V Input operating voltage
- 250mA Max. Output current
- Nora-B2 max current:
- Bluetooth LE TX 1 Mbps at +7 dBm (maximum setting): 9.8mA
- The LDO output is stable when using only 1 μF output capacitance.
Ceramic, tantalum or aluminum electrolytic capacitors can all be used for input and output.
- Add 1u ceramic cap for input
- Add 10uF ceramic cap for output near MCU for radio current bursts
- Add 1u ceramic cap for output since they react faster to quick
transient load.
Prototype charger bring-up findings
- R12, the 10k TS bypass, is intentionally DNP. Populate it only when using a
battery without a 10k NTC on the middle pin. A floating TS pin disables
charging.
- The schematic has R8 = 4.64k, but the 6.25-hour safety-timer calculation
above requires 46.4k. Use 46.4k in the next PCB revision; the fitted 4.64k
value gives an approximately 0.62-hour fast-charge timer.
- The active-low CE pin is left unconnected. It has an internal pull-down,
but TI recommends an external pull-down rather than leaving it floating.
Tie CE to ground in the next PCB revision when charging is always enabled.
- If CHG is off and the BAT net repeatedly rises and falls, check the battery
connector polarity, BAT/GND continuity, and the NTC connection. The charger
performs a pulsed battery-detection cycle when it does not detect a battery.









