# Power System Wiring and Safety

Complete wiring diagrams, fusing, wire gauge selection, weatherproof connectors, and battery telemetry monitoring.

# Wiring a Solar Power System for LoRa Repeaters

Proper wiring is the difference between a reliable 5-year solar node and a fire hazard or intermittent failure. This page covers the complete wiring path from solar panel to LoRa load, including fusing strategy, wire gauge selection, connector types, weatherproofing, and cable management inside enclosures.

## System Wiring Overview

A correctly wired solar system follows this signal path:

```

Solar Panel(s)
 │
 ├─── [Fuse #1: Panel → Controller] ── MC4 cable to controller PV input
 │
Charge Controller (MPPT/PWM)
 │
 ├─── [Fuse #2: Controller → Battery] ── to battery positive terminal
 │
Battery Pack (LiFePO4/LiPo + BMS)
 │
 └─── [Fuse #3: Battery → Load] ── to load (LoRa node, 5V regulator, etc.)
```

Three independent fuses are required. Never combine them. Each fuse protects the wire segment between it and the next power source, limiting fault current to what the wire can safely carry.

## Fusing Requirements

<table id="bkmrk-segment-fuse-type-ra"> <thead> <tr> <th>Segment</th> <th>Fuse Type</th> <th>Rating (for 10 W panel, 7 Ah battery)</th> <th>Placement</th> </tr> </thead> <tbody> <tr> <td>Panel → Charge controller (PV in)</td> <td>Blade fuse or ANL</td> <td>10 A (next standard above Isc × 1.56)</td> <td>Within 12 inches of panel junction box positive terminal</td> </tr> <tr> <td>Charge controller → Battery</td> <td>Blade fuse or ANL</td> <td>15 A (next standard above charge controller rated output × 1.25)</td> <td>Within 12 inches of battery positive terminal</td> </tr> <tr> <td>Battery → Load</td> <td>Blade fuse or resettable PPTC</td> <td>3 - 5 A (sized to wire gauge, not load)</td> <td>Within 7 inches of battery positive terminal</td> </tr> </tbody></table>

Fuse ratings are sized to protect the *wire*, not the load. Use the next standard blade fuse size above 125% of the wire's ampacity at the installation temperature. ANL (bolt-down) fuses are preferred for currents above 30 A. For small LoRa systems (under 10 A total), automotive blade fuses in a waterproof inline holder (Littelfuse SPTP series, ~$2) are adequate.

## Wire Gauge Selection

<table id="bkmrk-awg-conductor-area-%28"> <thead> <tr> <th>AWG</th> <th>Conductor Area (mm²)</th> <th>Max Ampacity (60 °C insulation, bundled)</th> <th>Typical LoRa System Use</th> </tr> </thead> <tbody> <tr><td>AWG 22</td><td>0.33 mm²</td><td>3 A</td><td>Sensor wiring, signal lines</td></tr> <tr><td>AWG 20</td><td>0.52 mm²</td><td>5 A</td><td>Load output for single ESP32 node</td></tr> <tr><td>AWG 18</td><td>0.82 mm²</td><td>7 A</td><td>Load output for small system (5 A load)</td></tr> <tr><td>AWG 16</td><td>1.31 mm²</td><td>10 A</td><td>Battery-to-controller runs under 3 m</td></tr> <tr><td>AWG 14</td><td>2.08 mm²</td><td>15 A</td><td>Battery-to-controller runs 3 - 10 m; 10 W panel to controller</td></tr> <tr><td>AWG 12</td><td>3.31 mm²</td><td>20 A</td><td>20 - 40 W panel runs; Pi gateway battery cables</td></tr> <tr><td>AWG 10</td><td>5.26 mm²</td><td>30 A</td><td>40 - 100 W panel runs over 5 m</td></tr> <tr><td>AWG 8</td><td>8.37 mm²</td><td>40 A</td><td>100 W+ systems; long battery cable runs</td></tr> </tbody></table>

Always use **stranded copper wire** with UV-resistant and temperature-rated insulation (XLPE or THWN-2 for outdoor; silicone for inside enclosures near heat). Solid wire is not suitable for mobile or vibrating installations. Use tinned copper wire in marine environments.

For voltage drop calculation in long cable runs:

```

Voltage_drop (V) = 2 × I (A) × R_per_meter (Ω/m) × Length (m)

Target: keep drop to less than 3% of system voltage.
For 12 V system, 3% = 0.36 V maximum drop.

Example: 5 A load, 5 m one-way run, AWG 14 (0.0083 Ω/m):
 Drop = 2 × 5 × 0.0083 × 5 = 0.415 V (3.5% - marginal, upgrade to AWG 12)
```

## Weatherproof Connectors

### MC4 Connectors (Panel Wiring)

MC4 (Multi-Contact 4 mm) connectors are the industry standard for solar panel connections. They are IP67-rated, UV-resistant, and rated to 1000 V DC and 30 A. Never use non-MC4 connectors on the panel-side wiring - the exposed conductors in DIY terminal connections will corrode and introduce resistance. Crimp MC4 connectors with the correct MC4 crimper (not pliers) to ensure proper contact retention. MC4 pairs from different manufacturers (e.g., Stäubli vs Amphenol) are nominally cross-compatible but may have reduced IP rating when mixed - use matched pairs.

### Anderson Powerpole Connectors (Load Connections)

Anderson Powerpole connectors (SB series 15 A, 30 A, 45 A) are the amateur radio and telecom standard for DC power distribution. They are genderless, stackable, and accept 12 - 20 AWG wire. The Powerpole 15/30 A connector accepts 14 - 18 AWG; crimp with an RENNSTEIG RE 2-30 or similar ratchet crimper. ARES (Amateur Radio Emergency Service) has standardized on red (+) and black (−) 30 A Powerpoles for all portable power connections.

### Other Connectors

<table id="bkmrk-connector-rating-use"> <thead> <tr> <th>Connector</th> <th>Rating</th> <th>Use Case</th> </tr> </thead> <tbody> <tr><td>XT60</td><td>60 A continuous, 12 V</td><td>High-current battery connections in drone/RC-derived builds</td></tr> <tr><td>JST PH 2.0 mm</td><td>2 A</td><td>LiPo cell to embedded board (standard on most Adafruit/SparkFun boards)</td></tr> <tr><td>JST XH 2.54 mm</td><td>3 A</td><td>Sensor connections inside enclosure</td></tr> <tr><td>Dean's Ultra T-plug</td><td>30 A</td><td>Legacy RC packs; avoid for new designs</td></tr> </tbody></table>

## Polarity Protection

A reverse-polarity connection will damage or destroy the charge controller, LoRa board, and BMS in milliseconds. Implement at least one of the following:

1. **Asymmetric connectors:** MC4 (panel), Powerpole (load), JST (board) are all polarised - they cannot be connected backwards if crimped correctly.
2. **Schottky diode on the input:** A 3 A / 40 V Schottky diode (e.g., 1N5822) in series with the positive line wastes 0.3 - 0.4 V but prevents reverse connection. Only practical for low-current loads.
3. **P-channel MOSFET reverse protection:** A P-channel MOSFET (e.g., AO3401, IRF9540) provides near-zero-drop reverse polarity protection. Standard in commercial MPPT charge controller input stages.

## Cable Routing and Strain Relief in Enclosures

Inside IP65/IP67 enclosures (Polycase WQ series, Bud Industries NBF, PolyBox), cables enter through compression cable glands. Rules:

- Use **double-sealed cable glands** (IP68 rated) for any cable entering an outdoor enclosure - single-seal glands allow moisture wicking along the cable jacket.
- All cable entries should be **on the side or bottom** of the enclosure, never on the top, to prevent water pooling at the seal.
- Leave a **drip loop** on the outside of each cable entry - a short downward curve below the gland that water follows away from the entry point before the cable turns upward.
- Inside the enclosure, route cables along the walls and use **cable ties on standoffs**, not across the PCB or battery. Keep power cables away from antenna cables to prevent RF interference.
- Add a **silica gel desiccant pack** (4 g minimum per 0.5 L enclosure volume) and replace annually.
- Secure the battery with **hook-and-loop strap or foam padding** to prevent it from shifting and chafing cables during thermal expansion/contraction.

# Monitoring Battery State via Meshtastic Telemetry

Meshtastic and MeshCore both include power telemetry features that allow a node to report its battery voltage and charge level over the mesh network. This page covers enabling these features, configuring voltage ADC pins for different hardware, interpreting voltage as state-of-charge for LiFePO4 batteries, setting low-battery alerts, and visualising data in Grafana.

## Enabling Power Telemetry in Meshtastic

In Meshtastic firmware (2.x), power metrics are part of the **Telemetry Module**. To enable battery reporting:

### Via Meshtastic Python CLI

```

# Install CLI: pip install meshtastic
# Enable device metrics (includes battery level, voltage, uptime)
meshtastic --set telemetry.device_update_interval 300
# Sets reporting interval to 300 seconds (5 minutes)

# Verify telemetry module is enabled
meshtastic --get telemetry
```

### Via Meshtastic Web App or Mobile App

1. Open the [Meshtastic app](https://wiki.meshamerica.com/books/hardware-guide/page/meshtastic-app) and connect to your node.
2. Navigate to **Config → Module Config → Telemetry**.
3. Enable **Device Metrics**.
4. Set the update interval (300 - 3600 seconds; use longer intervals for battery-powered nodes to reduce TX duty cycle).
5. Save and reboot the node.

Once enabled, the node broadcasts a `meshtastic.Telemetry` protobuf packet on the default channel at the configured interval. The packet includes:

- `battery_level`: Integer 0 - 100 (firmware-estimated SoC percentage)
- `voltage`: Float in volts (actual measured ADC voltage)
- `channel_utilization`: Float (% airtime used)
- `air_util_tx`: Float (TX airtime)

## Voltage ADC Pin Configuration on Different Boards

Not all Meshtastic hardware platforms use the same pin or divider ratio for battery voltage measurement. The firmware auto-detects the board type from compile-time defines, but custom builds or off-label hardware may need manual configuration.

<table id="bkmrk-board-adc-pin-%28gpio%29"> <thead> <tr> <th>Board</th> <th>ADC Pin (GPIO)</th> <th>Voltage Divider Ratio</th> <th>Max Measurable Voltage</th> <th>Notes</th> </tr> </thead> <tbody> <tr> <td>TTGO T-Beam v0.7</td> <td>GPIO35</td> <td>1:2 (100 kΩ / 100 kΩ)</td> <td>~8.4 V</td> <td>Measures raw LiPo voltage</td> </tr> <tr> <td>TTGO T-Beam v1.1 (AXP192)</td> <td>AXP192 PMIC register</td> <td>Internal PMIC ADC</td> <td>Reported via I²C</td> <td>Reads VBAT register; very accurate</td> </tr> <tr> <td>TTGO LoRa32 v2.1</td> <td>GPIO35</td> <td>1:2</td> <td>~8.4 V</td> <td>Same as T-Beam v0.7</td> </tr> <tr> <td>Heltec WiFi LoRa 32 v3</td> <td>GPIO1 (ADC1\_CH0)</td> <td>1:1 (no divider; up to 3.3 V input only)</td> <td>3.3 V max</td> <td>Only suitable for direct 3.3 V LiPo via USB-C charging; not for 12 V systems</td> </tr> <tr> <td>RAK WisBlock RAK4631</td> <td>GPIO5 (P0.05 / AIN3)</td> <td>1:2 via RAK5005-O base board</td> <td>~6 V</td> <td>Reads via nRF52840 SAADC</td> </tr> <tr> <td>Wispr / Custom ESP32</td> <td>User-defined GPIO</td> <td>User-defined</td> <td>User-defined</td> <td>Set in platformio.ini or via power.adc\_multiplier\_override config key</td> </tr> </tbody></table>

If the reported voltage seems incorrect, verify with a multimeter at the battery terminals. Then check `power.adc_multiplier_override`:

```

meshtastic --set power.adc_multiplier_override 2.0
# Multiplies the raw ADC reading by 2.0 (use for 1:2 divider boards)
```

## Interpreting Voltage as State-of-Charge for LiFePO4

Meshtastic's built-in SoC estimation uses LiPo voltage thresholds (3.0 - 4.2 V per cell). For LiFePO4 packs, these thresholds are incorrect - LiFePO4 cells operate in the 2.5 - 3.65 V range. The firmware will report incorrect percentages unless you compensate.

### LiFePO4 Single-Cell (3.2 V nominal) Voltage → SoC Table

<table id="bkmrk-resting-ocv-%28v%29-appr"> <thead> <tr> <th>Resting OCV (V)</th> <th>Approximate SoC (%)</th> <th>Interpretation</th> </tr> </thead> <tbody> <tr><td>3.60 - 3.65</td><td>100%</td><td>Fully charged, absorb phase complete</td></tr> <tr><td>3.40 - 3.45</td><td>90%</td><td>High charge, float plateau</td></tr> <tr><td>3.30 - 3.35</td><td>70 - 80%</td><td>Mid-range - most of usable capacity here</td></tr> <tr><td>3.27 - 3.30</td><td>50%</td><td>Flat region - voltage barely distinguishable from 70%</td></tr> <tr><td>3.22 - 3.25</td><td>30%</td><td>Still flat; lower usable threshold approaching</td></tr> <tr><td>3.18 - 3.22</td><td>20%</td><td>Low battery - alert threshold</td></tr> <tr><td>3.10 - 3.18</td><td>10%</td><td>Critical - immediate recharge needed</td></tr> <tr><td>&lt; 3.10</td><td>&lt;5%</td><td>BMS will soon disconnect; node will shut down</td></tr> </tbody></table>

### 4S LiFePO4 Pack (12.8 V nominal) Voltage → SoC Table

<table id="bkmrk-pack-voltage-%28v%29-soc"> <thead> <tr> <th>Pack Voltage (V)</th> <th>SoC (%)</th> </tr> </thead> <tbody> <tr><td>14.4 - 14.6</td><td>100% (end of charge)</td></tr> <tr><td>13.6 - 13.8</td><td>90%</td></tr> <tr><td>13.2 - 13.4</td><td>70 - 80%</td></tr> <tr><td>13.0 - 13.2</td><td>50%</td></tr> <tr><td>12.8 - 13.0</td><td>30%</td></tr> <tr><td>12.4 - 12.8</td><td>20%</td></tr> <tr><td>12.0 - 12.4</td><td>10%</td></tr> <tr><td>&lt; 11.8</td><td>&lt;5% (BMS cutoff imminent)</td></tr> </tbody></table>

## Setting Low-Battery Alerts in Meshtastic

Meshtastic does not natively send alert messages when battery drops below a threshold, but there are two approaches to implement this:

### Approach 1 - Node-Red / MQTT Alert Pipeline

1. Configure Meshtastic MQTT uplink: `meshtastic --set mqtt.enabled true --set mqtt.address YOUR_BROKER_IP`
2. In Node-Red, subscribe to `msh/US/+/json/LongFast/#` (adjust channel name as needed).
3. Filter for `msg.payload.decoded.telemetry.deviceMetrics.voltage` below your LVD threshold.
4. Route low-voltage events to an alert node (email, PushOver, Telegram bot).

### Approach 2 - Meshtastic Python Script (Autonomous Node)

```

import meshtastic
import meshtastic.serial_interface
from meshtastic.mesh_pb2 import MeshPacket

iface = meshtastic.serial_interface.SerialInterface()
LOW_VOLTAGE_THRESHOLD = 3.18 # V per cell for LiFePO4 (20% SoC)

def on_receive(packet, interface):
 if "decoded" in packet and "telemetry" in packet["decoded"]:
 m = packet["decoded"]["telemetry"].get("deviceMetrics", {})
 voltage = m.get("voltage", 0)
 node_id = packet["fromId"]
 if voltage > 0 and voltage < LOW_VOLTAGE_THRESHOLD:
 print(f"LOW BATTERY: Node {node_id} at {voltage:.2f} V")
 # Send alert message on mesh
 iface.sendText(f"⚠ Low battery: {node_id} {voltage:.2f}V", wantAck=False)

iface.localNode.setOwner("MonitorNode")
iface.addReceiveObserver(on_receive)
input("Press Enter to exit\n")
iface.close()
```

## MeshCore Telemetry Equivalent

MeshCore uses a similar but distinct telemetry structure. Battery reporting in MeshCore is enabled via the `telemetry` section in the node YAML configuration file:

```

telemetry:
 enabled: true
 interval_s: 300
 battery:
 adc_pin: 35
 adc_vref: 3.3
 divider_ratio: 2.0
 low_voltage_alert: 3.18
```

MeshCore publishes telemetry packets to MQTT in JSON format. Grafana can consume these via the Grafana MQTT data source plugin or via InfluxDB (Node-Red → InfluxDB → Grafana).

## Graphing Battery Data in Grafana

### Architecture

```

Meshtastic Node
 │ (MQTT telemetry JSON)
 ▼
Mosquitto MQTT Broker
 │
 ▼
Node-Red (parse JSON → extract voltage/SoC → write to InfluxDB)
 │
 ▼
InfluxDB 2.x (time-series storage)
 │
 ▼
Grafana (dashboards, alerts)
```

### InfluxDB Line Protocol (Node-Red write node)

```

measurement: node_battery
tags: node_id, node_name, location
fields: voltage (float), battery_pct (int), soc_lifepo4 (float)
timestamp: nanosecond UNIX timestamp from packet
```

### Grafana Panel Configuration

- **Battery voltage time series:** Use a Time Series panel with threshold bands - green above 3.30 V, yellow 3.18 - 3.30 V, red below 3.18 V (per cell) or scale for your pack voltage.
- **Multi-node SoC gauge:** Use a Gauge panel per node with min=0, max=100, thresholds at 20% (red) and 40% (yellow).
- **Grafana Alerting:** Set an alert rule on `avg(voltage) < 3.18` for any node, with a 15-minute evaluation window (to avoid false alarms from momentary load spikes). Route to PagerDuty, Slack, or email.

A complete Grafana dashboard JSON template for Meshtastic power monitoring is maintained in the Mesh America GitHub repository under `monitoring/dashboards/meshtastic-power.json`.