Initial firmware for ESP32-S3 six-channel soil moisture node
Implements ESP32_Soil_Moisture_Node_PRD.md on the VCC-GND Studio
YD-ESP32-S3 (ESP32-S3-WROOM-1) using Arduino via PlatformIO, publishing
to Home Assistant over MQTT with auto-discovery.
Two power profiles behind a compile-time switch (PRD 4):
-e mains always on, publishes every 60s
-e battery RTC wake, sample, publish, deep sleep 15min
PRD mitigations:
- All six probes on ADC1 (GPIO4-9); ADC2 is unusable while Wi-Fi is up.
- analogReadMilliVolts() for eFuse ADC calibration rather than raw counts.
- 16 samples per probe, sorted, 10% trimmed from each end, averaged.
- Per-probe two-point calibration; HW-390 output is inverted (dry reads
high), and an inverted config is rejected rather than silently producing
a backwards curve.
- MAC-derived node ID so identical binaries never collide on topics.
Design decisions that diverge from a literal reading of the PRD:
- Out-of-range probes publish null (HA "unknown") instead of clamping to
0%/100%. A cut Cat5 pair reads ~0mV, which clamps to a believable "very
dry" and would drive irrigation on wrong data.
- The battery profile uses expire_after rather than an availability topic;
a sleeping node is offline most of the time and would sit greyed out.
- AWAKE_BUDGET_MS forces deep sleep if a wake cycle overruns, covering
failure modes the per-step network timeouts miss (DHCP never issued,
CONNACK never sent) that would otherwise flatten the cell.
- docs/WIRING.md notes the 18650 cannot feed the probes directly: the
XC6206 LDO needs ~3.4V headroom, so a boost converter is required on the
switched side of the MOSFET.
Both profiles compile clean under -Wall. Not yet run on hardware; pin map,
MOSFET circuit and calibration defaults are unverified against a board.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
commit
ad9c457ea7
24 files changed
+2178
No files matched your search
@@ -0,0 +1,113 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 940 520" width="940" height="520" role="img" aria-labelledby="t4">
|
||||
<title id="t4">Solar and battery power topology with boost converter and battery sense divider</title>
|
||||
<style>
|
||||
.bg { fill: #fcfcfa; }
|
||||
.ttl { font: 600 19px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.h { font: 600 13px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.s { font: 11.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #6b7280; }
|
||||
.m { font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #374151; }
|
||||
.box { fill: #f3f4f6; stroke: #16181d; stroke-width: 1.6; }
|
||||
.boxp { fill: #fff3ec; stroke: #c2410c; stroke-width: 1.8; }
|
||||
.boxs { fill: #eef2ff; stroke: #1d4ed8; stroke-width: 1.8; }
|
||||
.pw { fill: none; stroke: #c2410c; stroke-width: 2.2; }
|
||||
.sigw { fill: none; stroke: #1d4ed8; stroke-width: 1.8; }
|
||||
.gw { fill: none; stroke: #374151; stroke-width: 1.9; }
|
||||
.comp { fill: #ffffff; stroke: #16181d; stroke-width: 1.5; }
|
||||
</style>
|
||||
|
||||
<rect class="bg" x="0" y="0" width="940" height="520"/>
|
||||
<text class="ttl" x="20" y="30">Solar / battery topology — remote node</text>
|
||||
<text class="s" x="20" y="49">The cell cannot feed the probes directly: an 18650 runs 3.0–4.2V and the HW-390's XC6206 LDO needs ~3.4V of headroom.</text>
|
||||
|
||||
<!-- ============ chain ============ -->
|
||||
<rect class="boxp" x="24" y="96" width="150" height="80" rx="6"/>
|
||||
<text class="h" x="38" y="120">Solar panel</text>
|
||||
<text class="m" x="38" y="139">6V / 1–2W</text>
|
||||
<text class="s" x="38" y="158">sized for winter, not</text>
|
||||
<text class="s" x="38" y="171">for a sunny afternoon</text>
|
||||
|
||||
<path class="pw" d="M174,136 L216,136" marker-end="url(#ar)"/>
|
||||
|
||||
<rect class="boxp" x="222" y="96" width="160" height="80" rx="6"/>
|
||||
<text class="h" x="236" y="120">TP4056 + DW01</text>
|
||||
<text class="m" x="236" y="139">CC/CV charger</text>
|
||||
<text class="s" x="236" y="158">protection variant only</text>
|
||||
<text class="s" x="236" y="171">— no MPPT</text>
|
||||
|
||||
<path class="pw" d="M382,136 L424,136" marker-end="url(#ar)"/>
|
||||
|
||||
<rect class="boxp" x="430" y="96" width="140" height="80" rx="6"/>
|
||||
<text class="h" x="444" y="120">18650 Li-Ion</text>
|
||||
<text class="m" x="444" y="139">3.0 – 4.2 V</text>
|
||||
<text class="s" x="444" y="158">VBAT node</text>
|
||||
|
||||
<!-- split to MCU and boost -->
|
||||
<circle cx="600" cy="136" r="4" fill="#c2410c"/>
|
||||
<path class="pw" d="M570,136 L600,136"/>
|
||||
<path class="pw" d="M600,136 L600,86 L716,86" marker-end="url(#ar)"/>
|
||||
<path class="pw" d="M600,136 L600,206 L716,206" marker-end="url(#ar)"/>
|
||||
|
||||
<rect class="boxs" x="722" y="56" width="192" height="62" rx="6"/>
|
||||
<text class="h" x="736" y="79">ESP32-S3 · 5V/VIN</text>
|
||||
<text class="s" x="736" y="97">onboard reg accepts VBAT</text>
|
||||
<text class="m" x="736" y="112">deep sleep ≈ 10 µA</text>
|
||||
|
||||
<rect class="boxp" x="722" y="176" width="192" height="62" rx="6"/>
|
||||
<text class="h" x="736" y="199">Boost converter → 5V</text>
|
||||
<text class="s" x="736" y="217">on the SWITCHED side of</text>
|
||||
<text class="s" x="736" y="231">the P-FET, not before it</text>
|
||||
|
||||
<path class="pw" d="M818,238 L818,282" marker-end="url(#ar)"/>
|
||||
<rect class="boxp" x="722" y="288" width="192" height="54" rx="6"/>
|
||||
<text class="h" x="736" y="310">P-FET → Cat5 pin 2</text>
|
||||
<text class="s" x="736" y="329">see power-switch.svg</text>
|
||||
|
||||
<!-- ============ battery sense divider ============ -->
|
||||
<path class="sigw" d="M500,176 L500,222"/>
|
||||
<circle cx="500" cy="176" r="4" fill="#c2410c"/>
|
||||
<text class="h" x="300" y="228">Battery sense divider</text>
|
||||
|
||||
<rect class="comp" x="480" y="222" width="40" height="52" rx="2"/>
|
||||
<text class="m" x="528" y="252">R1 1 MΩ</text>
|
||||
|
||||
<path class="sigw" d="M500,274 L500,302"/>
|
||||
<circle cx="500" cy="302" r="4" fill="#1d4ed8"/>
|
||||
<path class="sigw" d="M500,302 L640,302" marker-end="url(#ab)"/>
|
||||
<text class="h" x="648" y="299">GPIO10</text>
|
||||
<text class="s" x="648" y="315">ADC1_CH9</text>
|
||||
|
||||
<!-- shunt cap -->
|
||||
<path class="sigw" d="M566,302 L566,336"/>
|
||||
<circle cx="566" cy="302" r="3.4" fill="#1d4ed8"/>
|
||||
<line x1="555" y1="336" x2="577" y2="336" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="555" y1="342" x2="577" y2="342" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M566,342 L566,368"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="566" y="368"/>
|
||||
<text class="m" x="584" y="342">1 µF</text>
|
||||
|
||||
<rect class="comp" x="480" y="302" width="40" height="52" rx="2"/>
|
||||
<text class="m" x="410" y="332">R2 1 MΩ</text>
|
||||
<path class="gw" d="M500,354 L500,382"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="500" y="382"/>
|
||||
|
||||
<!-- ============ notes ============ -->
|
||||
<rect x="20" y="410" width="900" height="90" rx="5" fill="#fff3ec" stroke="#c2410c" stroke-width="1.4"/>
|
||||
<text class="h" x="34" y="431">Why 1 MΩ and not the usual 100 kΩ.</text>
|
||||
<text class="s" x="34" y="450">A 100 kΩ/100 kΩ divider draws ~21 µA continuously — more than the sleeping MCU itself (~10 µA), and enough to dominate</text>
|
||||
<text class="s" x="34" y="468">the winter power budget. 1 MΩ/1 MΩ draws ~2 µA. The 1 µF cap is not optional at that impedance: it supplies the ADC's sampling charge.</text>
|
||||
<text class="s" x="34" y="486">Trim BATTERY_DIVIDER_RATIO in config.h against a meter to cancel resistor tolerance.</text>
|
||||
|
||||
<defs>
|
||||
<marker id="ar" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#c2410c"/>
|
||||
</marker>
|
||||
<marker id="ab" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#1d4ed8"/>
|
||||
</marker>
|
||||
<g id="gnd">
|
||||
<line x1="-10" y1="0" x2="10" y2="0" stroke="#374151" stroke-width="1.9"/>
|
||||
<line x1="-6" y1="4.5" x2="6" y2="4.5" stroke="#374151" stroke-width="1.9"/>
|
||||
<line x1="-2.5" y1="9" x2="2.5" y2="9" stroke="#374151" stroke-width="1.9"/>
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,131 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 710" width="900" height="710" role="img" aria-labelledby="t5">
|
||||
<title id="t5">Firmware control flow for the mains and battery power profiles</title>
|
||||
<style>
|
||||
.bg { fill: #fcfcfa; }
|
||||
.ttl { font: 600 19px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.col { font: 600 14px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.h { font: 600 12.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.s { font: 11px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #6b7280; }
|
||||
.m { font: 10.5px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #374151; }
|
||||
.node { fill: #f3f4f6; stroke: #16181d; stroke-width: 1.5; }
|
||||
.nsig { fill: #eef2ff; stroke: #1d4ed8; stroke-width: 1.6; }
|
||||
.npw { fill: #fff3ec; stroke: #c2410c; stroke-width: 1.6; }
|
||||
.nnet { fill: #ecfdf3; stroke: #15803d; stroke-width: 1.6; }
|
||||
.flow { fill: none; stroke: #16181d; stroke-width: 1.6; }
|
||||
.alt { fill: none; stroke: #c2410c; stroke-width: 1.6; stroke-dasharray: 5 4; }
|
||||
</style>
|
||||
|
||||
<rect class="bg" x="0" y="0" width="900" height="710"/>
|
||||
<text class="ttl" x="20" y="30">Firmware flow — one compile-time switch, two shapes</text>
|
||||
<text class="s" x="20" y="49">POWER_PROFILE_MAINS keeps setup() short and does the work in loop(). POWER_PROFILE_BATTERY does everything in setup() and never reaches loop().</text>
|
||||
|
||||
<!-- divider -->
|
||||
<line x1="450" y1="72" x2="450" y2="676" stroke="#d1d5db" stroke-width="1.4" stroke-dasharray="4 4"/>
|
||||
|
||||
<!-- ================= MAINS ================= -->
|
||||
<text class="col" x="30" y="94">-e mains · continuous power</text>
|
||||
|
||||
<rect class="node" x="30" y="108" width="200" height="38" rx="5"/>
|
||||
<text class="h" x="44" y="132">boot → setup()</text>
|
||||
<path class="flow" d="M130,146 L130,168" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="npw" x="30" y="168" width="200" height="52" rx="5"/>
|
||||
<text class="h" x="44" y="189">power::begin()</text>
|
||||
<text class="m" x="44" y="207">gate HIGH, rail stays on</text>
|
||||
<path class="flow" d="M130,220 L130,242" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="node" x="30" y="242" width="200" height="52" rx="5"/>
|
||||
<text class="h" x="44" y="263">node_id::begin()</text>
|
||||
<text class="m" x="44" y="281">MAC → soil-node-a1b2c3</text>
|
||||
<path class="flow" d="M130,294 L130,316" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nnet" x="30" y="316" width="200" height="52" rx="5"/>
|
||||
<text class="h" x="44" y="337">Wi-Fi + MQTT connect</text>
|
||||
<text class="m" x="44" y="355">LWT → availability topic</text>
|
||||
<path class="flow" d="M130,368 L130,390" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nnet" x="30" y="390" width="200" height="52" rx="5"/>
|
||||
<text class="h" x="44" y="411">publish discovery</text>
|
||||
<text class="m" x="44" y="429">retained, homeassistant/</text>
|
||||
<path class="flow" d="M130,442 L130,464" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="node" x="30" y="464" width="200" height="38" rx="5"/>
|
||||
<text class="h" x="44" y="488">loop()</text>
|
||||
<path class="flow" d="M130,502 L130,524" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nsig" x="30" y="524" width="200" height="52" rx="5"/>
|
||||
<text class="h" x="44" y="545">every 60 s: sample</text>
|
||||
<text class="m" x="44" y="563">+ publish state JSON</text>
|
||||
|
||||
<!-- loop back -->
|
||||
<path class="flow" d="M230,550 L256,550 L256,483 L230,483" marker-end="url(#a)"/>
|
||||
<text class="s" x="262" y="520">repeat</text>
|
||||
|
||||
<!-- reconnect branch, routed clear of the repeat loop -->
|
||||
<path class="alt" d="M230,566 L330,566 L330,342 L230,342" marker-end="url(#ar)"/>
|
||||
<text class="s" x="338" y="436">on drop:</text>
|
||||
<text class="s" x="338" y="452">reconnect +</text>
|
||||
<text class="s" x="338" y="468">re-announce</text>
|
||||
|
||||
<!-- ================= BATTERY ================= -->
|
||||
<text class="col" x="482" y="94">-e battery · solar / 18650</text>
|
||||
|
||||
<rect class="node" x="482" y="108" width="212" height="38" rx="5"/>
|
||||
<text class="h" x="496" y="132">RTC wake → setup()</text>
|
||||
<path class="flow" d="M588,146 L588,166" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="npw" x="482" y="166" width="212" height="52" rx="5"/>
|
||||
<text class="h" x="496" y="187">armAwakeBudget()</text>
|
||||
<text class="m" x="496" y="205">30 s ceiling on the cycle</text>
|
||||
<path class="flow" d="M588,218 L588,238" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="npw" x="482" y="238" width="212" height="52" rx="5"/>
|
||||
<text class="h" x="496" y="259">sensorsOn() + settle</text>
|
||||
<text class="m" x="496" y="277">MOSFET on, wait 500 ms</text>
|
||||
<path class="flow" d="M588,290 L588,310" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nnet" x="482" y="310" width="212" height="52" rx="5"/>
|
||||
<text class="h" x="496" y="331">Wi-Fi + MQTT connect</text>
|
||||
<text class="m" x="496" y="349">expire_after, no LWT</text>
|
||||
<path class="flow" d="M588,362 L588,382" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nnet" x="482" y="382" width="212" height="52" rx="5"/>
|
||||
<text class="h" x="496" y="403">cold boot? → discovery</text>
|
||||
<text class="m" x="496" y="421">skipped on RTC wake</text>
|
||||
<path class="flow" d="M588,434 L588,454" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="nsig" x="482" y="454" width="212" height="66" rx="5"/>
|
||||
<text class="h" x="496" y="475">oversample + publish</text>
|
||||
<text class="m" x="496" y="493">16 reads, trim 10%,</text>
|
||||
<text class="m" x="496" y="509">map, one JSON publish</text>
|
||||
<path class="flow" d="M588,520 L588,540" marker-end="url(#a)"/>
|
||||
|
||||
<rect class="npw" x="482" y="540" width="212" height="66" rx="5"/>
|
||||
<text class="h" x="496" y="561">flush → sensorsOff()</text>
|
||||
<text class="m" x="496" y="579">→ deep sleep 15 min</text>
|
||||
<text class="m" x="496" y="595">loop() never runs</text>
|
||||
|
||||
<!-- wake cycle back -->
|
||||
<path class="flow" d="M694,573 L744,573 L744,127 L694,127" marker-end="url(#a)"/>
|
||||
<text class="s" x="752" y="346">RTC timer</text>
|
||||
<text class="s" x="752" y="361">wake</text>
|
||||
|
||||
<!-- early-sleep bailout -->
|
||||
<path class="alt" d="M482,336 L458,336 L458,573 L482,573" marker-end="url(#ar)"/>
|
||||
<text class="s" x="466" y="470" transform="rotate(-90 466 470)">network down → sleep early</text>
|
||||
|
||||
<!-- ================= note ================= -->
|
||||
<rect x="20" y="626" width="860" height="62" rx="5" fill="#fff3ec" stroke="#c2410c" stroke-width="1.4"/>
|
||||
<text class="h" x="34" y="646">The awake budget is armed before anything that can block.</text>
|
||||
<text class="s" x="34" y="664">Per-step timeouts don't cover an AP that associates but never issues a DHCP lease, or a broker that completes TCP but never</text>
|
||||
<text class="s" x="34" y="681">sends CONNACK. Without the ceiling, one bad night flattens the cell.</text>
|
||||
|
||||
<defs>
|
||||
<marker id="a" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#16181d"/>
|
||||
</marker>
|
||||
<marker id="ar" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#c2410c"/>
|
||||
</marker>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
@@ -0,0 +1,94 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 740 500" width="740" height="500" role="img" aria-labelledby="t3">
|
||||
<title id="t3">High-side P-channel MOSFET switch for the 5V sensor rail, driven through a 2N7002 inverting stage</title>
|
||||
<style>
|
||||
.bg { fill: #fcfcfa; }
|
||||
.ttl { font: 600 19px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.h { font: 600 13px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.s { font: 11.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #6b7280; }
|
||||
.m { font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #374151; }
|
||||
.pin { font: 600 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #16181d; }
|
||||
.pw { fill: none; stroke: #c2410c; stroke-width: 2; }
|
||||
.sigw { fill: none; stroke: #1d4ed8; stroke-width: 1.8; }
|
||||
.gw { fill: none; stroke: #374151; stroke-width: 2; }
|
||||
.comp { fill: #ffffff; stroke: #16181d; stroke-width: 1.5; }
|
||||
.fet { fill: #eef2ff; stroke: #1d4ed8; stroke-width: 1.8; }
|
||||
</style>
|
||||
|
||||
<rect class="bg" x="0" y="0" width="740" height="500"/>
|
||||
<text class="ttl" x="20" y="30">Switched 5V sensor rail — high-side P-FET</text>
|
||||
<text class="s" x="20" y="49">A 3.3V GPIO cannot turn a P-FET on a 5V rail fully off. The 2N7002 inverting stage is what makes it work.</text>
|
||||
|
||||
<!-- ============ +5V rail ============ -->
|
||||
<path class="pw" d="M60,110 L660,110"/>
|
||||
<text class="h" x="60" y="100">+5V</text>
|
||||
<text class="s" x="98" y="100">from buck (mains) or boost converter (battery)</text>
|
||||
|
||||
<!-- ============ 100k pull-up ============ -->
|
||||
<path class="pw" d="M330,110 L330,150"/>
|
||||
<circle cx="330" cy="110" r="3.6" fill="#c2410c"/>
|
||||
<rect class="comp" x="310" y="150" width="40" height="56" rx="2"/>
|
||||
<text class="m" x="212" y="174">100 kΩ</text>
|
||||
<text class="s" x="212" y="190">holds gate off</text>
|
||||
<path class="sigw" d="M330,206 L330,240"/>
|
||||
|
||||
<!-- ============ P-channel MOSFET ============ -->
|
||||
<rect class="fet" x="400" y="180" width="130" height="96" rx="6"/>
|
||||
<text class="h" x="416" y="206">P-channel</text>
|
||||
<text class="m" x="416" y="224">AO3401</text>
|
||||
<text class="s" x="416" y="242">or IRLML6402</text>
|
||||
<text class="pin" x="416" y="262">S ▲ G ◀ D ▼</text>
|
||||
|
||||
<!-- P-FET source up to rail -->
|
||||
<path class="pw" d="M465,180 L465,110"/>
|
||||
<circle cx="465" cy="110" r="3.6" fill="#c2410c"/>
|
||||
<text class="pin" x="472" y="172">S</text>
|
||||
|
||||
<!-- P-FET gate left to node -->
|
||||
<path class="sigw" d="M400,240 L330,240"/>
|
||||
<circle cx="330" cy="240" r="3.6" fill="#1d4ed8"/>
|
||||
<text class="pin" x="380" y="234">G</text>
|
||||
|
||||
<!-- P-FET drain down to output -->
|
||||
<path class="pw" d="M465,276 L465,330 L620,330"/>
|
||||
<text class="pin" x="472" y="292">D</text>
|
||||
<text class="h" x="500" y="322">+5V to Cat5 pin 2</text>
|
||||
<text class="s" x="500" y="350">sensors + battery-side boost load</text>
|
||||
|
||||
<!-- ============ 2N7002 inverting stage ============ -->
|
||||
<path class="sigw" d="M330,240 L235,240 L235,290"/>
|
||||
<rect class="fet" x="170" y="290" width="130" height="90" rx="6"/>
|
||||
<text class="h" x="186" y="315">N-channel</text>
|
||||
<text class="m" x="186" y="333">2N7002</text>
|
||||
<text class="s" x="186" y="351">logic-level</text>
|
||||
<text class="pin" x="186" y="370">D ▲ G ◀ S ▼</text>
|
||||
<text class="pin" x="242" y="284">D</text>
|
||||
|
||||
<!-- gate drive from GPIO14 -->
|
||||
<path class="sigw" d="M170,335 L140,335"/>
|
||||
<rect class="comp" x="80" y="325" width="60" height="20" rx="2"/>
|
||||
<text class="m" x="92" y="339">10 kΩ</text>
|
||||
<path class="sigw" d="M80,335 L36,335"/>
|
||||
<text class="h" x="20" y="318">GPIO14</text>
|
||||
<text class="pin" x="150" y="329">G</text>
|
||||
|
||||
<!-- source to ground -->
|
||||
<path class="gw" d="M235,380 L235,420"/>
|
||||
<text class="pin" x="242" y="396">S</text>
|
||||
<path class="gw" d="M60,420 L660,420"/>
|
||||
<circle cx="235" cy="420" r="3.6" fill="#374151"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="360" y="420"/>
|
||||
<text class="h" x="60" y="440">GND</text>
|
||||
<text class="s" x="98" y="440">common star point with Cat5 pin 1</text>
|
||||
|
||||
<!-- ============ truth table ============ -->
|
||||
<rect x="20" y="456" width="700" height="34" rx="5" fill="#fff3ec" stroke="#c2410c" stroke-width="1.4"/>
|
||||
<text class="m" x="34" y="477">GPIO14 HIGH → 2N7002 conducts → gate pulled low → rail ON · GPIO14 LOW or FLOATING → 100 kΩ pulls gate to 5V → rail OFF</text>
|
||||
|
||||
<defs>
|
||||
<g id="gnd">
|
||||
<line x1="-10" y1="0" x2="10" y2="0" stroke="#374151" stroke-width="2"/>
|
||||
<line x1="-6" y1="4.5" x2="6" y2="4.5" stroke="#374151" stroke-width="2"/>
|
||||
<line x1="-2.5" y1="9" x2="2.5" y2="9" stroke="#374151" stroke-width="2"/>
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,174 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 800 690" width="800" height="690" role="img" aria-labelledby="t2">
|
||||
<title id="t2">RJ45 breakout schematic with six RC low-pass filters feeding ESP32-S3 ADC1 pins</title>
|
||||
<style>
|
||||
.bg { fill: #fcfcfa; }
|
||||
.ttl { font: 600 19px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.h { font: 600 13px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.s { font: 11.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #6b7280; }
|
||||
.m { font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #374151; }
|
||||
.mp { font: 600 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #16181d; }
|
||||
.wire { fill: none; stroke: #1d4ed8; stroke-width: 1.7; }
|
||||
.pw { fill: none; stroke: #c2410c; stroke-width: 1.9; }
|
||||
.gw { fill: none; stroke: #374151; stroke-width: 1.9; }
|
||||
.comp { fill: #ffffff; stroke: #16181d; stroke-width: 1.5; }
|
||||
.jack { fill: #f3f4f6; stroke: #16181d; stroke-width: 1.8; }
|
||||
</style>
|
||||
|
||||
<rect class="bg" x="0" y="0" width="800" height="690"/>
|
||||
<text class="ttl" x="20" y="30">RJ45 breakout — RC low-pass per analog line</text>
|
||||
<text class="s" x="20" y="49">PRD §3.1, mandatory. One filter per signal, sited at the ESP32 end of the series resistor.</text>
|
||||
|
||||
<!-- ================= jack ================= -->
|
||||
<rect class="jack" x="34" y="86" width="104" height="478" rx="6"/>
|
||||
<text class="h" x="46" y="110">RJ45</text>
|
||||
<text class="s" x="46" y="126">T568B</text>
|
||||
|
||||
<!-- column headers -->
|
||||
<text class="s" x="152" y="80">wire</text>
|
||||
<text class="s" x="238" y="80">series R</text>
|
||||
<text class="s" x="360" y="80">shunt C</text>
|
||||
<text class="s" x="470" y="80">to MCU</text>
|
||||
|
||||
<!-- ================= pin 1: GND ================= -->
|
||||
<text class="mp" x="46" y="156">1</text>
|
||||
<rect x="62" y="146" width="26" height="12" fill="#ffffff" stroke="#f97316" stroke-width="1.2"/>
|
||||
<rect x="62" y="150" width="26" height="4" fill="#f97316"/>
|
||||
<path class="gw" d="M138,152 L470,152"/>
|
||||
<text class="m" x="152" y="138">Orange/White</text>
|
||||
<text class="h" x="480" y="157">GND</text>
|
||||
<text class="s" x="524" y="157">star point</text>
|
||||
|
||||
<!-- ================= pin 2: +5V ================= -->
|
||||
<text class="mp" x="46" y="214">2</text>
|
||||
<rect x="62" y="204" width="26" height="12" fill="#f97316" stroke="#374151" stroke-width="1"/>
|
||||
<path class="pw" d="M138,210 L470,210"/>
|
||||
<text class="m" x="152" y="196">Orange</text>
|
||||
<text class="h" x="480" y="215">+5V</text>
|
||||
<text class="s" x="524" y="215">switched rail</text>
|
||||
|
||||
<!-- ================= signal rows ================= -->
|
||||
<!-- row: pin 3 -->
|
||||
<text class="mp" x="46" y="272">3</text>
|
||||
<rect x="62" y="262" width="26" height="12" fill="#ffffff" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<rect x="62" y="266" width="26" height="4" fill="#16a34a"/>
|
||||
<text class="m" x="152" y="254">Green/White</text>
|
||||
<path class="wire" d="M138,268 L206,268"/>
|
||||
<rect class="comp" x="206" y="258" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="272">10 kΩ</text>
|
||||
<path class="wire" d="M270,268 L470,268"/>
|
||||
<circle cx="352" cy="268" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,268 L352,286"/>
|
||||
<line x1="341" y1="286" x2="363" y2="286" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="292" x2="363" y2="292" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,292 L352,300"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="300"/>
|
||||
<text class="m" x="370" y="292">0.1 µF</text>
|
||||
<text class="h" x="480" y="273">GPIO4</text>
|
||||
<text class="s" x="534" y="273">ADC1_CH3 · moisture 1</text>
|
||||
|
||||
<!-- row: pin 4 -->
|
||||
<text class="mp" x="46" y="330">4</text>
|
||||
<rect x="62" y="320" width="26" height="12" fill="#2563eb" stroke="#374151" stroke-width="1"/>
|
||||
<text class="m" x="152" y="312">Blue</text>
|
||||
<path class="wire" d="M138,326 L206,326"/>
|
||||
<rect class="comp" x="206" y="316" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="330">10 kΩ</text>
|
||||
<path class="wire" d="M270,326 L470,326"/>
|
||||
<circle cx="352" cy="326" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,326 L352,344"/>
|
||||
<line x1="341" y1="344" x2="363" y2="344" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="350" x2="363" y2="350" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,350 L352,358"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="358"/>
|
||||
<text class="m" x="370" y="350">0.1 µF</text>
|
||||
<text class="h" x="480" y="331">GPIO6</text>
|
||||
<text class="s" x="534" y="331">ADC1_CH5 · moisture 3</text>
|
||||
|
||||
<!-- row: pin 5 -->
|
||||
<text class="mp" x="46" y="388">5</text>
|
||||
<rect x="62" y="378" width="26" height="12" fill="#ffffff" stroke="#2563eb" stroke-width="1.2"/>
|
||||
<rect x="62" y="382" width="26" height="4" fill="#2563eb"/>
|
||||
<text class="m" x="152" y="370">Blue/White</text>
|
||||
<path class="wire" d="M138,384 L206,384"/>
|
||||
<rect class="comp" x="206" y="374" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="388">10 kΩ</text>
|
||||
<path class="wire" d="M270,384 L470,384"/>
|
||||
<circle cx="352" cy="384" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,384 L352,402"/>
|
||||
<line x1="341" y1="402" x2="363" y2="402" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="408" x2="363" y2="408" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,408 L352,416"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="416"/>
|
||||
<text class="m" x="370" y="408">0.1 µF</text>
|
||||
<text class="h" x="480" y="389">GPIO7</text>
|
||||
<text class="s" x="534" y="389">ADC1_CH6 · moisture 4</text>
|
||||
|
||||
<!-- row: pin 6 -->
|
||||
<text class="mp" x="46" y="446">6</text>
|
||||
<rect x="62" y="436" width="26" height="12" fill="#16a34a" stroke="#374151" stroke-width="1"/>
|
||||
<text class="m" x="152" y="428">Green</text>
|
||||
<path class="wire" d="M138,442 L206,442"/>
|
||||
<rect class="comp" x="206" y="432" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="446">10 kΩ</text>
|
||||
<path class="wire" d="M270,442 L470,442"/>
|
||||
<circle cx="352" cy="442" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,442 L352,460"/>
|
||||
<line x1="341" y1="460" x2="363" y2="460" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="466" x2="363" y2="466" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,466 L352,474"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="474"/>
|
||||
<text class="m" x="370" y="466">0.1 µF</text>
|
||||
<text class="h" x="480" y="447">GPIO5</text>
|
||||
<text class="s" x="534" y="447">ADC1_CH4 · moisture 2</text>
|
||||
|
||||
<!-- row: pin 7 -->
|
||||
<text class="mp" x="46" y="504">7</text>
|
||||
<rect x="62" y="494" width="26" height="12" fill="#ffffff" stroke="#92400e" stroke-width="1.2"/>
|
||||
<rect x="62" y="498" width="26" height="4" fill="#92400e"/>
|
||||
<text class="m" x="152" y="486">Brown/White</text>
|
||||
<path class="wire" d="M138,500 L206,500"/>
|
||||
<rect class="comp" x="206" y="490" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="504">10 kΩ</text>
|
||||
<path class="wire" d="M270,500 L470,500"/>
|
||||
<circle cx="352" cy="500" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,500 L352,518"/>
|
||||
<line x1="341" y1="518" x2="363" y2="518" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="524" x2="363" y2="524" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,524 L352,532"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="532"/>
|
||||
<text class="m" x="370" y="524">0.1 µF</text>
|
||||
<text class="h" x="480" y="505">GPIO8</text>
|
||||
<text class="s" x="534" y="505">ADC1_CH7 · moisture 5</text>
|
||||
|
||||
<!-- row: pin 8 -->
|
||||
<text class="mp" x="46" y="562">8</text>
|
||||
<rect x="62" y="552" width="26" height="12" fill="#92400e" stroke="#374151" stroke-width="1"/>
|
||||
<text class="m" x="152" y="544">Brown</text>
|
||||
<path class="wire" d="M138,558 L206,558"/>
|
||||
<rect class="comp" x="206" y="548" width="64" height="20" rx="2"/>
|
||||
<text class="m" x="222" y="562">10 kΩ</text>
|
||||
<path class="wire" d="M270,558 L470,558"/>
|
||||
<circle cx="352" cy="558" r="3.4" fill="#1d4ed8"/>
|
||||
<path class="wire" d="M352,558 L352,576"/>
|
||||
<line x1="341" y1="576" x2="363" y2="576" stroke="#16181d" stroke-width="1.8"/>
|
||||
<line x1="341" y1="582" x2="363" y2="582" stroke="#16181d" stroke-width="1.8"/>
|
||||
<path class="gw" d="M352,582 L352,590"/>
|
||||
<use xlink:href="#gnd" href="#gnd" x="352" y="590"/>
|
||||
<text class="m" x="370" y="582">0.1 µF</text>
|
||||
<text class="h" x="480" y="563">GPIO9</text>
|
||||
<text class="s" x="534" y="563">ADC1_CH8 · moisture 6</text>
|
||||
|
||||
<!-- ================= notes ================= -->
|
||||
<rect x="20" y="610" width="760" height="64" rx="5" fill="#fff3ec" stroke="#c2410c" stroke-width="1.4"/>
|
||||
<text class="h" x="34" y="631">Placement matters more than the values.</text>
|
||||
<text class="s" x="34" y="650">The capacitor must sit at the ESP32 end of the resistor, close to the pin — it is what supplies the ADC's sampling charge.</text>
|
||||
<text class="s" x="34" y="667">Fitting the 10 kΩ without the cap leaves source impedance worse than having no filter at all.</text>
|
||||
|
||||
<defs>
|
||||
<g id="gnd">
|
||||
<line x1="-10" y1="0" x2="10" y2="0" stroke="#374151" stroke-width="1.9"/>
|
||||
<line x1="-6" y1="4.5" x2="6" y2="4.5" stroke="#374151" stroke-width="1.9"/>
|
||||
<line x1="-2.5" y1="9" x2="2.5" y2="9" stroke="#374151" stroke-width="1.9"/>
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1,164 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 980 600" width="980" height="600" role="img" aria-labelledby="t1">
|
||||
<title id="t1">System architecture: six HW-390 probes over Cat5 to an ESP32-S3, published to Home Assistant over MQTT</title>
|
||||
<style>
|
||||
.bg { fill: #fcfcfa; }
|
||||
.box { fill: #f3f4f6; stroke: #16181d; stroke-width: 1.6; }
|
||||
.boxhi { fill: #eef2ff; stroke: #1d4ed8; stroke-width: 1.8; }
|
||||
.boxpw { fill: #fff3ec; stroke: #c2410c; stroke-width: 1.8; }
|
||||
.boxha { fill: #ecfdf3; stroke: #15803d; stroke-width: 1.8; }
|
||||
.ttl { font: 600 19px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.h { font: 600 13.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #16181d; }
|
||||
.s { font: 11.5px ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif; fill: #6b7280; }
|
||||
.m { font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #374151; }
|
||||
.mb { font: 600 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; fill: #1d4ed8; }
|
||||
.sig { fill: none; stroke: #1d4ed8; stroke-width: 1.5; }
|
||||
.cat5 { fill: none; stroke: #1d4ed8; stroke-width: 8; stroke-linecap: round; }
|
||||
.pwr { fill: none; stroke: #c2410c; stroke-width: 2.2; }
|
||||
.data { fill: none; stroke: #15803d; stroke-width: 2.2; }
|
||||
.dash { stroke-dasharray: 5 4; }
|
||||
</style>
|
||||
|
||||
<rect class="bg" x="0" y="0" width="980" height="600"/>
|
||||
<text class="ttl" x="20" y="30">Soil Moisture Node — system architecture</text>
|
||||
<text class="s" x="20" y="49">Up to 6 HW-390 v2.0 probes per node · one Cat5 run · multi-node safe via MAC-derived ID</text>
|
||||
|
||||
<!-- ============ probes ============ -->
|
||||
<text class="h" x="20" y="80">Field sensors</text>
|
||||
<g>
|
||||
<rect class="box" x="20" y="90" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="110">HW-390 #1</text><text class="m" x="32" y="126">sealed · 5mA</text>
|
||||
<rect class="box" x="20" y="146" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="166">HW-390 #2</text><text class="m" x="32" y="182">sealed · 5mA</text>
|
||||
<rect class="box" x="20" y="202" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="222">HW-390 #3</text><text class="m" x="32" y="238">sealed · 5mA</text>
|
||||
<rect class="box" x="20" y="258" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="278">HW-390 #4</text><text class="m" x="32" y="294">sealed · 5mA</text>
|
||||
<rect class="box" x="20" y="314" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="334">HW-390 #5</text><text class="m" x="32" y="350">sealed · 5mA</text>
|
||||
<rect class="box" x="20" y="370" width="152" height="44" rx="5"/>
|
||||
<text class="h" x="32" y="390">HW-390 #6</text><text class="m" x="32" y="406">sealed · 5mA</text>
|
||||
</g>
|
||||
<text class="s" x="20" y="437">Each: XC6206 LDO 5V→3.3V on-board.</text>
|
||||
<text class="s" x="20" y="452">Upper PCB epoxy-sealed; prongs bare.</text>
|
||||
|
||||
<!-- ============ cat5 funnel ============ -->
|
||||
<text class="h" x="186" y="80">Cat5 24AWG</text>
|
||||
<text class="s" x="186" y="96">8 conductors · T568B</text>
|
||||
<path class="sig" d="M172,112 Q212,112 244,252"/>
|
||||
<path class="sig" d="M172,168 Q212,168 244,252"/>
|
||||
<path class="sig" d="M172,224 Q216,224 244,252"/>
|
||||
<path class="sig" d="M172,280 Q216,280 244,252"/>
|
||||
<path class="sig" d="M172,336 Q212,336 244,252"/>
|
||||
<path class="sig" d="M172,392 Q212,392 244,252"/>
|
||||
<path class="cat5" d="M244,252 L300,252"/>
|
||||
|
||||
<!-- ============ breakout ============ -->
|
||||
<rect class="boxhi" x="300" y="112" width="184" height="302" rx="6"/>
|
||||
<text class="h" x="314" y="136">RJ45 breakout</text>
|
||||
<text class="s" x="314" y="153">at MCU enclosure</text>
|
||||
|
||||
<rect x="314" y="166" width="156" height="96" rx="4" fill="#ffffff" stroke="#1d4ed8" stroke-width="1.2"/>
|
||||
<text class="h" x="326" y="187">6× RC low-pass</text>
|
||||
<text class="m" x="326" y="205">10 kΩ series</text>
|
||||
<text class="m" x="326" y="221">0.1 µF to GND</text>
|
||||
<text class="m" x="326" y="237">at the ADC pin</text>
|
||||
<text class="m" x="326" y="253" fill="#c2410c">MANDATORY §3.1</text>
|
||||
|
||||
<rect x="314" y="274" width="156" height="58" rx="4" fill="#ffffff" stroke="#374151" stroke-width="1.2"/>
|
||||
<text class="h" x="326" y="294">Star ground</text>
|
||||
<text class="m" x="326" y="312">single point, no</text>
|
||||
<text class="m" x="326" y="326">daisy-chaining</text>
|
||||
|
||||
<text class="m" x="314" y="356" fill="#c2410c">pin 2 → +5V (switched)</text>
|
||||
<text class="m" x="314" y="373" fill="#374151">pin 1 → GND</text>
|
||||
<text class="m" x="314" y="390" fill="#1d4ed8">pins 3-8 → 6 signals</text>
|
||||
|
||||
<!-- breakout to mcu -->
|
||||
<path class="sig" d="M484,252 L522,252" marker-end="url(#arrowb)"/>
|
||||
|
||||
<!-- ============ esp32 ============ -->
|
||||
<rect class="boxhi" x="530" y="112" width="180" height="302" rx="6"/>
|
||||
<text class="h" x="544" y="136">ESP32-S3</text>
|
||||
<text class="s" x="544" y="153">YD-ESP32-S3 (WROOM-1)</text>
|
||||
|
||||
<rect x="544" y="166" width="152" height="122" rx="4" fill="#ffffff" stroke="#1d4ed8" stroke-width="1.2"/>
|
||||
<text class="h" x="556" y="186">ADC1 only</text>
|
||||
<text class="s" x="556" y="201">ADC2 is owned by Wi-Fi</text>
|
||||
<text class="m" x="556" y="221">GPIO4-9 moisture 1-6</text>
|
||||
<text class="m" x="556" y="238">GPIO10 battery÷2</text>
|
||||
<text class="m" x="556" y="255">GPIO14 rail MOSFET</text>
|
||||
<text class="m" x="556" y="272">GPIO48 status LED</text>
|
||||
|
||||
<rect x="544" y="300" width="152" height="100" rx="4" fill="#ffffff" stroke="#374151" stroke-width="1.2"/>
|
||||
<text class="h" x="556" y="320">Firmware</text>
|
||||
<text class="m" x="556" y="338">16× oversample</text>
|
||||
<text class="m" x="556" y="354">trim 10% outliers</text>
|
||||
<text class="m" x="556" y="370">eFuse ADC cal</text>
|
||||
<text class="m" x="556" y="386">2-point curve → %</text>
|
||||
|
||||
<!-- ============ wifi ============ -->
|
||||
<path class="data" d="M710,220 L770,180" marker-end="url(#arrowg)"/>
|
||||
<text class="s" x="716" y="248">Wi-Fi</text>
|
||||
<text class="s" x="716" y="262">MQTT</text>
|
||||
|
||||
<!-- ============ broker + HA ============ -->
|
||||
<rect class="boxha" x="790" y="130" width="170" height="86" rx="6"/>
|
||||
<text class="h" x="804" y="153">MQTT broker</text>
|
||||
<text class="s" x="804" y="170">Mosquitto</text>
|
||||
<text class="m" x="804" y="190">soil/<node>/state</text>
|
||||
<text class="m" x="804" y="206">retained JSON</text>
|
||||
|
||||
<path class="data" d="M875,216 L875,266" marker-end="url(#arrowg)"/>
|
||||
|
||||
<rect class="boxha" x="790" y="270" width="170" height="120" rx="6"/>
|
||||
<text class="h" x="804" y="293">Home Assistant</text>
|
||||
<text class="s" x="804" y="310">auto-discovery, no YAML</text>
|
||||
<text class="m" x="804" y="331">moisture 1-6 %</text>
|
||||
<text class="m" x="804" y="348">battery level %</text>
|
||||
<text class="m" x="804" y="365">wifi signal dBm</text>
|
||||
<text class="m" x="804" y="382">uptime s</text>
|
||||
|
||||
<!-- ============ power path ============ -->
|
||||
<!-- Flow runs right-to-left along the bottom: source -> MOSFET -> breakout -> Cat5 -->
|
||||
<rect class="boxpw" x="530" y="440" width="180" height="76" rx="6"/>
|
||||
<text class="h" x="544" y="462">Power source</text>
|
||||
<text class="m" x="544" y="481">mains: 5V USB / buck</text>
|
||||
<text class="m" x="544" y="497">remote: 18650 + solar</text>
|
||||
<text class="m" x="544" y="512">→ boost to 5V</text>
|
||||
|
||||
<path class="pwr" d="M530,470 L492,470" marker-end="url(#arrowr)"/>
|
||||
|
||||
<rect class="boxpw" x="300" y="440" width="184" height="76" rx="6"/>
|
||||
<text class="h" x="314" y="462">Switched 5V rail</text>
|
||||
<text class="m" x="314" y="481">P-FET high-side</text>
|
||||
<text class="m" x="314" y="497">HIGH = sensors on</text>
|
||||
<text class="m" x="314" y="512">floating = off</text>
|
||||
|
||||
<path class="pwr" d="M392,440 L392,418" marker-end="url(#arrowr)"/>
|
||||
|
||||
<!-- GPIO14 gate control: out the right of the MCU, under both boxes, up into the FET -->
|
||||
<path class="pwr dash" d="M690,414 L730,414 L730,548 L430,548 L430,522" marker-end="url(#arrowr)"/>
|
||||
<text class="m" x="560" y="542" fill="#c2410c">GPIO14 gate</text>
|
||||
|
||||
<!-- ============ legend ============ -->
|
||||
<line x1="20" y1="575" x2="46" y2="575" stroke="#1d4ed8" stroke-width="2.2"/>
|
||||
<text class="s" x="54" y="579">analog signal</text>
|
||||
<line x1="152" y1="575" x2="178" y2="575" stroke="#c2410c" stroke-width="2.2"/>
|
||||
<text class="s" x="186" y="579">power</text>
|
||||
<line x1="248" y1="575" x2="274" y2="575" stroke="#15803d" stroke-width="2.2"/>
|
||||
<text class="s" x="282" y="579">network / data</text>
|
||||
<line x1="378" y1="575" x2="404" y2="575" stroke="#c2410c" stroke-width="2.2" stroke-dasharray="5 4"/>
|
||||
<text class="s" x="412" y="579">control</text>
|
||||
|
||||
<defs>
|
||||
<marker id="arrowb" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#1d4ed8"/>
|
||||
</marker>
|
||||
<marker id="arrowr" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#c2410c"/>
|
||||
</marker>
|
||||
<marker id="arrowg" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto">
|
||||
<path d="M0,0 L9,4.5 L0,9 z" fill="#15803d"/>
|
||||
</marker>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.9 KiB |
Reference in new issue
Block a user