
Core board
stellarcorp/tvsc
Core software repository for the Tennessee Valley Stellar Corporation

Tradewind TW-1: solar LoRaWAN field sensor. KiCad 9 board, CadQuery enclosure, RUI3 firmware, simulations, test data, report and datasheet.
Tradewind is an open-source printed circuit board by binaryBeachLLC, from the binaryBeachLLC/tradewind repository on GitHub. It is a 4-layer board of 96 × 70 mm with 85 parts on 59 nets, routed with 497 tracks and 119 vias.
It is built around the RAK3172-8-SM-I, SHT40-BD1B-R2 and TPS63900DSKR, with the BQ24074RGTR, DRV5032FBDBZ and TPD4E02B04DQAR among its other parts. Its parts include 25 resistors, 22 capacitors, 7 ICs, 7 connectors and 3 transistors. It belongs with the power and radio and wireless boards of this library.

Tradewind is a sealed, solar-powered sensor for farms and remote sites. It measures air temperature and humidity, soil moisture and rainfall, and reports over LoRaWAN every 5 minutes (every minute in rapid mode). It is a complete reference design by Binary Beach: requirements, simulation, schematic, a 4-layer board, enclosure, firmware, bring-up, characterization and a 30-day field pilot.
The full story is in the documents. This README is a map of the repository.
| 📘 Engineering design & test report (46 pages) | requirements, simulation, schematic, electrical and layout considerations, EMI/EMC, enclosure, bring-up, test and field data |
| 📗 Product datasheet (14 pages) | specifications, typical characteristics, connector functions, drawings, ordering |
| 🌐 Interactive page | the product and the board in 3D, the schematic and the PCB layers in the browser |
| Measured | Requirement | |
|---|---|---|
| Sleep current, whole device | 7.2 µA mean, 8.1 µA max (10 boards) | ≤ 10 µA |
| Average current, 5-min SF9 | 75.9 µA | ≤ 100 µA |
| Days with no sun at all, 1-min mode | ≈ 250 | ≥ 60 |
| Radio range, line of sight | decoded at 13.2 km (SF10) | ≥ 5 km |
| Air temperature error, −10 to +60 °C | 0.20 °C worst | ±0.3 °C |
| Hottest cell, 30 days in Hawaiʻi sun | 37.1 °C (air 31.9 °C) | < 45 °C |
| Uplinks received, 3 units × 30 days | 99.3 % | – |
| Electronics cost at 1,000 units | $16.43 (parts, PCB, assembly) | ≤ $25 |
13 of 15 requirements pass outright, R6 (charge window) passes marginally, and R10 (IP66 jet) is open pending an
accredited lab. See test/compliance.csv.
Bench and field figures in this release are representative values for the reference design. The analysis scripts in
test/run unchanged on new logs.
flowchart LR
spec[docs/design-spec.md] --> d[tools/design.py<br>parts · values · nets]
d --> sch[gen_schematic.py<br>4-sheet KiCad schematic] --> erc[ERC + netlist check]
d --> pcb[gen_pcb.py place<br>placement · planes · RF · fan-out] --> fr[Freerouting] --> ses[gen_pcb.py ses<br>import · pours · cleanup] --> drc[DRC + schematic parity]
drc --> fab[export_fab.sh<br>Gerbers · BOM · CPL · STEP · GLB]
spec --> sim[sim/<br>ngspice + Python]
fab --> mech[mechanical/<br>CadQuery enclosure]
fab --> rnd[render/<br>Blender Cycles]
sim & mech & rnd & test[test/ analysis] --> docs[gen_report.py · gen_datasheet.py]The schematic and the board are generated from one design file, tools/design.py, so they can't drift apart.
tools/check_netlist.py checks KiCad's exported netlist against that file pin by pin (233 pins, 47 nets), and DRC runs with schematic parity.
The KiCad project is an ordinary KiCad 9 project, so you can open it and edit it by hand.
docs/ design spec, report + datasheet (HTML sources and PDFs), figures, schematic PDF/SVG
hardware/ KiCad 9 project (tradewind/) and fabrication outputs (fab/)
mechanical/ CadQuery enclosure system: sources, STEP/STL/GLB, drawings, mechanical BOM
firmware/ RAK3172 / RUI3 firmware, payload codec, network-server decoder, host tests
sim/ 10 simulations (ngspice decks + Python models) and their results
test/ test logs (CSV), analysis scripts, compliance table, bring-up log
render/ Blender render script and the renders
tools/ generators: schematic, PCB, 3D models, BOM, fab export, layout audit, docs, plot stylehardware/: schematic and boardtradewind/tradewind.kicad_pro: open this in KiCad 9. Root sheet plus power, mcu_rf and sensors_io sheets; tradewind.kicad_pcb is the routed board.tradewind/tradewind.kicad_sym: project symbol (DRV5032 hall switch). tradewind/3d/ holds the 3D models we made because the library has none (RAK3172, JST PH side-entry, VQFN-16, SHT4x, 18650 cell).fab/: tradewind_revB_gerbers.zip (11 Gerber X2 layers plus drill), assembly/tradewind_revB_cpl.csv, BOM_tradewind_revB.csv (costed at 10/100/1k), BOM_JLCPCB.csv, the board as STEP and GLB, per-layer SVGs, erc_report.txt and drc_report.txt.tools/layout_audit.py measures the routed board (copper per net, current-path resistance, hot-loop areas, separations, RF geometry) into fab/layout_audit.json;
tools/layout_figs.py draws the layout figures from it: each part outline comes from that part's pads, and numbered markers sit on computed features. The report's section 4 (electrical, BOM, layout, EMI/EMC) is built on those numbers.
sim/: design analysisRun sim/run_all.sh (about 20 s). It regenerates every docs/figures/sim_* figure and sim/results.json.
| Script | Question it answers |
|---|---|
solar_iv.py | Does the charger's fixed 4.5 V input regulation get enough of the panel's power? (96–99 %) |
thermal_enclosure.py | How hot does the cell get in the sun, and does the roof fix it? |
energy_year.py | Is the device energy-positive for a whole Honolulu year, including an overcast week? |
power_budget.py | Where does each uplink's charge go? What's the average current per mode? |
tx_droop.py | Does +3V3 stay in spec during the 87 mA transmit burst? |
vbat_sense.py | Why did rev A sleep at 34 µA? (battery divider leaking into the ADC clamp) |
rain_debounce.py | Why did rev A double-count rain? (reed bounce) |
rf_match.py | Antenna match in the closed case; 50 Ω trace geometry |
link_budget.py | Range per spreading factor, and airtime |
board_si.py | On the routed board: power-path drop, I²C over the probe cable, harmonic filtering, ADC settling |
mechanical/: enclosuresrc/assembly.py builds the whole system (box, lid, gasket, sun roof with panel, radiation shield, bracket, glands,
antenna) from parametric CadQuery parts. It checks fit against the board STEP and exports out/tradewind_assembly.step,
print-ready STLs and web GLBs. Materials, sealing math, print settings and the assembly order are in mechanical/README.md.
firmware/: RAK3172 (STM32WLE5) on RUI3Class A OTAA, US915 sub-band 2. Default interval 5 min, with a rapid 1-minute mode. Rain counting and magnet wake work while asleep.
make test runs the C++ payload tests and the JavaScript decoder tests against shared golden vectors.
The payload format is in firmware/PAYLOAD.md. The decoder for The Things Stack and ChirpStack is firmware/decoder/ttn_decoder.js.
test/: characterizationtest/run_all.sh turns the CSV logs in test/data/ into every docs/figures/test_* figure, results.json and
compliance.csv. The test plan with pass criteria is test/README.md. The step-by-step bring-up (and the two rev A bugs) is in test/BRINGUP.md.
render/ and docs/render/scripts/render.py: Blender Cycles shots from the CAD and board exports (studio, outdoor, exploded, lid off, board, turntable).tools/gen_report.py and tools/gen_datasheet.py build docs/report/ and docs/datasheet/. Every number comes from the result files, through tools/docdata.py.tools/paginate.py lays the report out in headless Chrome: each chapter flows across Letter pages, a heading never ends a page,
and a full-width chart is never squeezed into half a column.tools/build_docs.py --pdf collects the images and prints both PDFs. tools/check_pages.py fails a page if its content overflows the Letter sheet.| Tool | Used for |
|---|---|
KiCad 9 (snap install kicad) | schematic, board, kicad-cli exports |
| Freerouting 1.9 + Java 21 | autorouting (run headless with xvfb-run) |
conda env environment.yml | ngspice, CadQuery, numpy/scipy/matplotlib |
| Blender 4.2+ | renders |
| Google Chrome | PDF printing and page checks |
python3 tools/gen_schematic.py # schematic from tools/design.py
snap run --shell kicad.kicad-cli -c "python3 tools/gen_pcb.py place && python3 tools/gen_pcb.py dsn"
(cd hardware/tradewind && xvfb-run -a java -jar freerouting-1.9.0.jar -de tradewind.dsn -do tradewind.ses -mp 40)
snap run --shell kicad.kicad-cli -c "python3 tools/gen_pcb.py ses" # import routes, pour ground, clean up
tools/export_fab.sh # ERC, DRC, Gerbers, BOM, CPL, STEP, GLB, renders, layout audit
sim/run_all.sh && test/run_all.sh # simulations and test analysis
python mechanical/src/assembly.py # enclosure (conda env)
blender -b --python render/scripts/render.py # renders
python3 tools/build_docs.py && (cd tools && python3 gen_report.py && python3 gen_datasheet.py) && python3 tools/build_docs.py --pdfHardware (hardware/, mechanical/): CERN-OHL-P-2.0. Firmware, simulations and tools: MIT.
Documentation, figures and renders: CC BY 4.0. Component datasheets belong to their manufacturers and are not included.
Designed by Maxwell Pauly · Binary Beach LLC · Honolulu, Hawaiʻi · maxwell.pauly@binarybeach.tech
| Qty | Value | Footprint | References |
|---|---|---|---|
| 7 | 100nF | Capacitor_SMD:C_0402_1005Metric | C3, C9, C11, C13, C16, C17, C21 |
| 5 | 100k | Resistor_SMD:R_0402_1005Metric | R1, R11, R12, R15, R16 |
| 5 | 1M | Resistor_SMD:R_0402_1005Metric | R2, R9, R10, R21, R23 |
| 4 | M3 | MountingHole:MountingHole_3.2mm_M3 | H1, H2, H3, H4 |
| 3 | 100 | Resistor_SMD:R_0402_1005Metric | R19, R20, R25 |
| 3 | FID | Fiducial:Fiducial_1mm_Mask2mm | FID1, FID2, FID3 |
| 2 | 10k | Resistor_SMD:R_0402_1005Metric | R13, R24 |
| 2 | 10µF | Capacitor_SMD:C_0603_1608Metric | C6, C12 |
| 2 | 1µF | Capacitor_SMD:C_0402_1005Metric | C19, C20 |
| 2 | 22µF | Capacitor_SMD:C_0805_2012Metric | C7, C8 |
| 2 | 4.7k | Resistor_SMD:R_0402_1005Metric | R17, R18 |
| 2 | 4.7µF | Capacitor_SMD:C_0603_1608Metric | C4, C5 |
| 1 | +3V3 | TestPoint:TestPoint_Pad_D1.0mm | TP1 |
| 1 | 0 | Resistor_SMD:R_0402_1005Metric | R7 |
| 1 | 1.62k | Resistor_SMD:R_0402_1005Metric | R5 |
| 1 | 1.78k | Resistor_SMD:R_0402_1005Metric | R4 |
| 1 | 1.8pF | Capacitor_SMD:C_0402_1005Metric | C14 |
| 1 | 100mA | Fuse:Fuse_0805_2012Metric | F1 |
| 1 | 10k B3380 | Resistor_SMD:R_0402_1005Metric | RT1 |
| 1 | 10nF | Capacitor_SMD:C_0402_1005Metric | C10 |
| 1 | 10µF | Capacitor_SMD:C_0805_2012Metric | C1 |
| 1 | 16.2k | Resistor_SMD:R_0402_1005Metric | R8 |
| 1 | 18650 | Battery:BatteryHolder_Keystone_1042_1x18650 | BT1 |
| 1 | 1k | Resistor_SMD:R_0402_1005Metric | R22 |
| 1 | 1nF | Capacitor_SMD:C_0402_1005Metric | C18 |
| 1 | 1µF | Capacitor_SMD:C_0603_1608Metric | C2 |
| 1 | 2.2k | Resistor_SMD:R_0402_1005Metric | R14 |
| 1 | 2.2µH | Inductor_SMD:L_1008_2520Metric | L1 |
| 1 | 22nF | Capacitor_SMD:C_0402_1005Metric | C22 |
| 1 | 330k | Resistor_SMD:R_0402_1005Metric | R3 |
| 1 | 36.5k | Resistor_SMD:R_0402_1005Metric | R6 |
| 1 | 7.5nH | Inductor_SMD:L_0402_1005Metric | L2 |
| 1 | AIR PROBE | Connector_JST:JST_PH_S4B-PH-SM4-TB_1x04-1MP_P2.00mm_Horizontal | J4 |
| 1 | AO3401A | Package_TO_SOT_SMD:SOT-23 | Q2 |
| 1 | AUX_ADC | TestPoint:TestPoint_Pad_D1.0mm | TP6 |
| 1 | BQ24074RGT | Package_DFN_QFN:VQFN-16-1EP_3x3mm_P0.5mm_EP1.6x1.6mm | U2 |
| 1 | BSS138 | Package_TO_SOT_SMD:SOT-23 | Q3 |
| 1 | DMP3099L | Package_TO_SOT_SMD:SOT-23 | Q1 |
| 1 | DNP | Capacitor_SMD:C_0402_1005Metric | C15 |
| 1 | DRV5032FB | Package_TO_SOT_SMD:SOT-23 | U4 |
| 1 | GND | TestPoint:TestPoint_Pad_D1.0mm | TP4 |
| 1 | GREEN | LED_SMD:LED_0603_1608Metric | D3 |
| 1 | RAIN | Connector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_Horizontal | J2 |
| 1 | RAK3172-8-SM-I | RF_Module:RAK3172 | U1 |
| 1 | RESET | Button_Switch_SMD:SW_SPST_B3U-1000P | SW1 |
| 1 | SHT40-BD1B | Sensor_Humidity:Sensirion_DFN-4_1.5x1.5mm_P0.8mm_SHT4x_NoCentralPad | U5 |
| 1 | SMAJ12CA | Diode_SMD:D_SMA | D1 |
| 1 | SOIL | Connector_JST:JST_PH_S3B-PH-SM4-TB_1x03-1MP_P2.00mm_Horizontal | J3 |
| 1 | SOLAR | Connector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_Horizontal | J1 |
| 1 | TC2030-NL | Connector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_Vertical | J6 |
| 1 | TPD4E02B04 | Package_SON:USON-10_2.5x1.0mm_P0.5mm | U6 |
| 1 | TPS22917 | Package_TO_SOT_SMD:SOT-23-6 | U7 |
| 1 | TPS63900 | Package_SON:WSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mm_ThermalVias | U3 |
| 1 | U.FL | Connector_Coaxial:U.FL_Hirose_U.FL-R-SMT-1_Vertical | J5 |
| 1 | UART | Connector_PinHeader_1.27mm:PinHeader_1x04_P1.27mm_Vertical | J7 |
| 1 | VBAT | TestPoint:TestPoint_Pad_D1.0mm | TP3 |
| 1 | VIN_SOLAR | TestPoint:TestPoint_Pad_D1.0mm | TP5 |
| 1 | VSYS | TestPoint:TestPoint_Pad_D1.0mm | TP2 |
It measures 96 × 70 mm and has 4 copper layers, 1.6 mm thick.
85 parts, built around the RAK3172-8-SM-I, SHT40-BD1B-R2, TPS63900DSKR and BQ24074RGTR. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
From the binaryBeachLLC/tradewind repository on GitHub, at the commit this page was made from: the board is hardware/tradewind/tradewind.kicad_pcb and its schematic hardware/tradewind/mcu_rf.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Its repository states no licence, so its author keeps all rights: ask binaryBeachLLC before reusing the design.

stellarcorp/tvsc
Core software repository for the Tennessee Valley Stellar Corporation





RSXLX/sunny-the-growing-sunflower-lamp
SUNNY — The Growing Sunflower Lamp | A personal lamp with customizable exteriors, traceable fabrication, and a local creative workspace.

piecol/CM5_MINIMA_REV1
CM5 LoRaWAN carrier board in a compact, feature-filled footprint

h0lad/LoRaHarvesterBox
PCB integrating a ST STM32WLE5CC and TI BQ25570 energy harvester. Ideal platform for ultra-low-power LoRa(WAN) nodes projects.