CurrentFireT.png: 801x185, 335k (February 17, 2026, at 02:38 am)
Two linked Gravity RS485 transceivers (in TestSys)

The system employs four distinct communication protocols, each selected specifically for its role in the overall architecture. Understanding why each protocol was chosen and how they work together reveals much about the design.

MQTT, running between Module 1 and Module 2, provides the interface between Home Assistant and Arduino AR1. This protocol's publish-subscribe model with retained messages and quality-of-service guarantees makes it ideal for dashboard control, where state persistence across disconnections and guaranteed delivery of critical commands are essential. The MQTT broker running in a Docker container in the Raspberry Pi maintains the authoritative state of all controllable elements, ensuring that reconnecting clients immediately receive current system status. Topics are organized hierarchically, with pump control under home/pump/inTopic, peripheral states under home/peripheral1/set through home/peripheral4/set, and sensor readings published to home/sensor/ topics. This organization allows Home Assistant automations to subscribe to specific state changes and respond accordingly.

RS-485, linking Module 2 and Module 4 over the multicore cable, was chosen for its exceptional noise immunity and reliability over extended cable runs. The differential signaling inherent to RS-485 makes it highly resistant to electromagnetic interference from the diesel pump motor and electrical noise in the pump shed environment. The implementation uses framed messages with checksum protection and explicit acknowledgment of critical commands. Every frame follows the format <PAYLOAD|CHECKSUM> where the checksum is calculated as an XOR of all payload bytes, converted to two-character hexadecimal representation. Pump commands additionally include sequence numbers from 0 to 15 that roll over, allowing the receiving end to detect and acknowledge each unique command while ignoring duplicates that might result from retry logic.

The RS-485 protocol defines several message types, each serving specific purposes. Command frames beginning with CMD: contain pump and peripheral relay states along with a sequence number and LOCK status. Status frames beginning with STAT: provide relay mirror states, heartbeat status, and Home Assistant automation flags without commanding pump state changes. Configuration frames beginning with CFG: transmit manual intermittent timing parameters from Home Assistant to AR3. Heartbeat frames consist simply of HB:0 or HB:1 indicating whether manual control is active. Telemetry frames flow from AR3 to AR1, containing all sensor readings, current relay states, autonomous mode and phase information, FSMODE status (0 = REMOTE, 1 = AUTONOMOUS), and system ready status. Since the system is battery powered, power interruptions are operator initiated. Given this, at AR1 the A wire is routed through a RS485 bus connection switch mounted on the external module wall. With this in place the protocol to protect the Gravity unit is for the connection switch to be switched off (isolation on) prior to powering down the module, and switched back on only after power has been reinstated. To further provide some protection against a voltage surge in the event the unit is not isolated when power is switched on or off 47 Ohm resistors are put in series with both the A and B wires at the AR1 end. This is well within tolerance at 9,600 baud which is the speed at which the system communication is configured.

Beyond the hardware protection, the firmware implements three layers of software protection for the bus. First, AR1 enforces a strict transmit window: it never drives the bus spontaneously, but only opens a transmit window for a brief period following each AR3 telemetry frame, after a 5 ms guard delay that allows the Gravity module's direction-switching circuitry to settle. Only one frame is dispatched per window, with CMD frames taking priority over STAT and CFG frames. A 400 ms freeze additionally prevents rapid pump direction reversals that would otherwise cause a burst of CMD retries on the bus. This ensures the two nodes never drive simultaneously — the primary failure mode for auto-direction transceivers. Second, AR1 withholds all relay CMD frames until AR3 has been confirmed alive by receipt of at least one telemetry frame containing sensor data (the ar3Ready gate). This prevents a burst of commands into a potentially unresponsive bus at startup or after a path switch. When ar3Ready transitions to true, AR1 immediately syncs current relay state so no command is permanently lost during the detection window. Third, when AR3 is operating in AUTONOMOUS mode it owns its own relays and must not accept relay commands from AR1. Simply ignoring CMD frames would cause AR1's retry logic to retransmit repeatedly, generating unnecessary bus traffic. Instead, AR3 ACKs every CMD frame even in AUTONOMOUS mode — satisfying the retry arbiter and quiescing the bus — but does not apply the relay or pump fields to its outputs.

SoftwareSerial Backup Communications between Modules 2 and 4, is a second (redundant route) linking Module 2 and Module 4 over spare wire pairs in the existing multicore cable, and was added to prevent a fault in which the RS-485 transceiver IC on AR1 could fail, silently severing communication while the rest of the system remained operational. The backup path uses Arduino's SoftwareSerial library on dedicated GPIO pins — AR1 transmits on A3 and receives on D13; AR3 transmits on D10 and receives on D9 — forming a direct UART link that is entirely independent of the RS-485 transceiver hardware.

The backup path carries the identical framed protocol used on the primary RS-485 link, including the same <PAYLOAD|CHECKSUM> frame format, XOR/hex checksum, sequence numbers, and acknowledgment logic. No protocol translation is required: AR3 processes frames from both paths through the same handler, and AR1 routes outgoing command and status frames to whichever path is currently active. The heartbeat frame is a deliberate exception — it is always transmitted on both paths simultaneously, regardless of active path, so that AR3 maintains its keep-alive regardless of which transceiver is functional.

AR1 monitors the primary RS-485 path continuously and switches automatically to the backup after 10 seconds of silence in received telemetry. The ar3Ready gate is re-armed on every path switch, requiring fresh telemetry confirmation from AR3 before relay commands are permitted on the new path. Recovery to primary is detected automatically when RS-485 telemetry resumes. AR3 transmits its telemetry on both paths at all times, which both enables this recovery detection and means AR1 always has a secondary confirmation of AR3's state. A dashboard test hook — the AR3 Comms Path Force control in Home Assistant — allows the operator to force either path without physically disconnecting cables, and triggers an alert notification (email and SMS) whenever the backup path becomes active in normal operation.

The SoftwareSerial backup path runs AR1 pin A3 (TX) to AR3 pin D9 (RX), and AR3 pin D10 (TX) to AR1 pin D13 (RX), with no RS-485 transceiver in the signal path. To protect against the unpowered-node fault condition — where a powered Arduino's TX pin forward-biases the protection diodes on the unpowered Arduino's RX pin — a 300 Ω series resistor is placed on each TX line: one at AR1 A3, one at AR3 D10. This limits fault current to (3.3 − 0.7) / 300 ≈ 8.7 mA, within the RA4M1 GPIO diode rating, while remaining transparent at 9600 baud where the 104 µs bit period dwarfs the RC rise time. UDP broadcast, operating within Module 4 between AR2 and AR3, provides high-frequency sensor data delivery at 10 hertz. Arduino AR2 operates as a WiFi access point with SSID "Arduino2_AP", creating a dedicated wireless network for this critical sensor link. AR3 connects as a client and receives broadcast packets containing pipe-delimited key-value pairs of all sensor readings.

A typical UDP packet might contain: EXT_TEMP:35.20|INT_TEMP:30.15|WATER_LEVEL:2.85|FLOW_OUT:165.30|BAT:13.20|OIL_OK:1|WATER_PV:0.15. The choice of UDP rather than TCP reflects the real-time nature of sensor data—if a packet is lost, the next reading will arrive in 100 milliseconds, making retransmission unnecessary and avoiding the latency that TCP's guaranteed delivery would introduce. The broadcast nature of UDP also means that multiple devices could listen to the sensor stream if future expansion requires it.

SMS communication to Module 5 provides the ultimate backup control path, operating entirely independently of the local network infrastructure. If both the NBN and local network fail, operators can still command the pump via the mobile network, ensuring that manual control remains possible under the most adverse conditions. This path is intentionally kept simple—a text message with a specific format sent to the pump controller's phone number can force pump activation or deactivation, bypassing all other control logic. Autonomous control As described later, if all external communication is lost the system continues to operate using inputs from AR2 and control decisions from AR3 in Module 3 transmitted by cable to the Relay Module (AR2).

For more background and technical detail refer to Inter-Module Communication, Gravity-RS485 half duplex serial communication, Multicore red and blue cable: connections.

<< Electronic Modules | | The Heartbeat System and Mode Transitions >>      |Table of Contents>


Page last modified on June 11, 2026, at 11:49 pm