Reverse engineering ACCESSORY port – Rain Bird ESP-RZX

Hello everyone,

I’m currently trying to find a way to communicate with a Rain Bird ESP-RZX controller using Home Assistant via ESPHome.

I’m sharing here the progress of my investigation on the ACCESSORY port (5 pins) of the Rain Bird ESP-RZX, which is used in particular by the WiFi LNK module.


:electric_plug: Measured pinout (from left to right)

Pin Function Measured Voltage
1 +12V OK
2 GND OK
3 +5V OK
4 Logic signal ~3.3V
5 Logic signal ~3.3V

:high_voltage: Electrical measurements

  • Pin 4 → GND: 180 kΩ
  • Pin 5 → GND: 100 kΩ
  • Pin 4 → +5V: ∞ (no continuity)
  • Pin 5 → +5V:
  • Pin 4 ↔ Pin 5: 4.7 kΩ

:backhand_index_pointing_right: The two logic lines (pins 4 and 5) are weakly pulled to ground and coupled together via an internal resistance of about 4.7 kΩ.


:zzz: Behavior with no module connected

  • Pins 4 and 5 are synchronous
  • Square wave signal at approximately 50 Hz
  • No communication frames observed

:high_voltage: Module presence detection

By injecting a signal on pin 5 that is synchronized but inverted relative to pin 4 (using an ESP32), the controller:

  • exits idle mode
  • appears to start transmitting digital frames

:backhand_index_pointing_right: The presence of a module seems to be detected through activity on the DATA line (pin 5).


:satellite_antenna: Observed communication

Once activated:

  • Pin 4: regular signal (clock)
  • Pin 5: synchronized signal with variable content

:backhand_index_pointing_right: The communication appears to be synchronous.


:cross_mark: Protocol tests

  • UART decoding: invalid
  • Signal is not compatible with UART

:white_check_mark: Captured frames (SPI decoding)

Examples of captured data:

20 43 80 04 08 10 A1 00 02 02 ...

or

02 07 16 80 02 00 43 80 04 ...

:backhand_index_pointing_right: The data is structured and repetitive, confirming a digital protocol.


:warning: Important behavior

  • If activity on pin 5 stops:
    → immediate return to the 50 Hz signal

:backhand_index_pointing_right: The controller requires continuous activity to keep the communication active.


:wrench: Tests performed

Active injection (ESP32)

Code used:

int inPin = 22; // pin 4
int outPin = 23; // pin 5

void setup() {
  pinMode(inPin, INPUT_PULLUP);
  pinMode(outPin, OUTPUT);
}

void loop() {
  int state = digitalRead(inPin);
  digitalWrite(outPin, !state);
}

Result:

  • bus activation
  • frames appear
  • but data is corrupted

Weak injection (short pulses)

  • microsecond pulses synchronized with the clock
  • clean frames observed
  • but no functional response

:puzzle_piece: Conclusion (established facts)

  • The ACCESSORY port uses a synchronous communication
  • Pin 4 acts as a clock
  • Pin 5 carries the data
  • The two lines are coupled via ~4.7 kΩ
  • The controller remains in idle mode without activity on DATA
  • Activity on the DATA line is required to activate communication
  • Communication stops immediately if this activity ceases
  • The protocol is not UART

:bullseye: Current status

  • Bus activation: :check_mark:
  • Frame capture: :check_mark:
  • Partial understanding of physical layer: :check_mark:
  • Full protocol decoding: in progress

If anyone has already worked on this port or the WiFi LNK module, I’d be happy to exchange ideas :+1:

Is your household power 50Hz or 60Hz? You may be picking up background hum.

Good question :+1:

My mains frequency is 50 Hz (France), so that was one of my first thoughts as well.

However, this signal is not background noise:

  • It is very stable and clean
  • It appears only on pins 4 and 5, perfectly synchronized
  • It disappears immediately when activity is injected on the DATA line
  • It is replaced by structured digital communication when the bus is activated

So this 50 Hz signal is actually generated by the controller itself and corresponds to its idle state when no module is detected, not external interference.

OK, so keep alive to keep the transmission bus primed for traffic.

You can’t imagine how much I was waiting for someone to attempt a reverse engineering on this specific controller. I wanted to integrate it on Home Assistant fo years but I have no skills in that department.

I can however – if you need it obviously – help you on the software/coding side where I’m more versed :slight_smile:

This really is very interesting. I was thinking about the same. It’s time to get this protocol reverse engineered. So far everything else is a high level aproach without touching the protocol:

All of these rely on the LNK module as a black box. Nobody has decoded the actual SPI-like communication on the accessory port yet.

Did you find anything if it is true SPI or is it even more proprietary?

+5V vcc, GND, +3.3V data +/-, +3.3V data +/-
This seams to be an USB protocol.

Protocol? As in serial?

You’ve got me also going down the reverse engineering rabbit hole now! Off to Google with ‘LNK Rainbird teardown’ in the search parameters as I don’t have any Rainbird bits to physically examine like you do, just experience to fall back on.

The following is thinking aloud, not the product of an LLM that may also follow a similar path, but you don’t learn much that way do you?

The LNK2, a successor, appears to employ an ESPRESSIF SOC according to the picture on this reddit post.

Given the LNK2 offers 5Ghz as well as 2.4Ghz WiFi connectivity, the chip (now visually identifiable as an Espressif, but the model number hidden by the sticker) might probably be the ESP32-C5, one of the few Espressif offers with dual band connectivity. If so, this offers the choice of ZigBee should you decide to write your own custom firmware to flash on this chip, extending the Rainbird functionality, and maybe going further, designing your own compatible interface offering Matter/Thread functionality too with the later generation ESP32 chips. Rainbird R&D take note, as this does not seem to be on offer yet, and could be a good money spinner to offer alternate firmware to make it happen as an aftermarket update. LNK3 anyone? :wink:

The two chips on the bottom side of the PCB adjacent the connector (U2 and U3) are optocouplers, and the other (U1) is a voltage converter. The rest of the components are ‘glue’ for making it all work, an inductor for the regulator, capacitors for transient spikes, and resistors for various pins for pull-up/down. Tracing each and every one could build you a detailed circuit diagram, and you will probably find most of it copied from the vendor application notes anyway.

Enough on the LNK2. Lets go back to the LNK, where the search results are less fruitful.

I’m assuming you have already used WireShark to sniff the WiFi traffic to the LNK and the results are encrypted or unintelligible, or are checksummed and you don’t know the algorithm, and there are no consistent, reproducible traffic blocks you can replicate? If you can, this may be the easiest route to go. If not, time for some heavy duty digging, the tools you need you probably already have, given your notes so far, and hesitancy at voltage and protocols in use. Let’s remove that lack of information and guessing.

Have you opened up your LNK unit by carefully splitting the shell open if it isn’t screwed together? If so, taking clear pictures of both sides may offer some further clues. The ones in the reddit post are just in sufficient detail to make out the chip numbers, an essential detail needed to examine data sheets. Make sure if you are taking photos and posting them here that it is clearly in focus and suitably detailed, even taking close-ups of each chip to be able to lookup their data sheet.

Sucking a copy of the firmware from the SOC and disassembling it may offer further clues. Tracing each connector pin to what part it goes to may also offer clues. Make sure you include any information found on the SOC label in your saved file name for cross reference later.

I’m guessing it uses standard serial protocol via TX/RX GPIO pins, buffered up from the 3.3v for external access by the optocouplers, one for TX, and the other for RX. Very careful circuit tracing on both sides of the board (visual and ohm meter) will probably confirm this.

The LNK unit is the forerunner to the LNK2, and the second offers greater number of modules it interfaces to. Given the LNK2 is backward compatible with the LNK, the content of the transmitted data should be similar when plugged into your Rainbird controller. This is the gem you are trying to find, the bit of that Rainbird intellectual property you are blowing wide open, and how most succesful reverse engineering projects end up documenting.

You have focused on reverse engineering from examining the signal from the connector, measuring the voltages at the pins. Look at it from a circuit designer aspect - how would you build an interface to support WiFi connectivity?

I’m guessing you may find a simpler earlier generation SOC in the LNK, a ESP8266, ESP8285, or early generation ESP32 series. Maybe a HiFlying HF-LPB100 chip like in early GoodWe solar inverter WiFi dongles (the explorations along a similar path to yours are painfully documented at Reverse-engineering an encrypted IoT protocol | @smlx's blog ) This is where date stamps on other components can narrow things down as to what was available at the tine your LNK was manufactured.

Where to from here? Lets do a physical examination of your LNK module by opening it up. If your fingernail or knife edge doesn’t work, carefully refrigerate your dongle to make the plastic cover more brittle. Gently place it in a vice or clamp so it puts pressure on the seams and carefully wind up the handle so the welded/glued seams split open enough to get a pry tool in there and finish prying it apart without smashing anything. At the end of the day, you still want to glue it back and use it, don’t you? No cutting or grinding if you want to put it back to how it was later.

Take out the circuit board. Photograph both sides with strong light, high magnification, and clear focus. Identify all semiconductors and individually photograph them too in enough detail to get the manufacturer, model, batch, and date information stamped on top. You may need side lighting and different angles to achieve this. An overall picture showing where circuit traces go can sometimes be valuable too, especially where there aren’t multilayer boards where you sometimes need to follow the PCB vias as the signal hops from one side to the other. Larger components such as fuses, capacitors, relays, connectord, and inductors can help identify PCB ‘zones’ such as power supply, interface, and display drivers. In this case they are not present, the optocouplers adjacent to the connector being the item of interest that grabbed my initial scan, followed by the inductor confirming some form of switching power supply onboard.

Look at the SOC. Is it an Espressif one? Photo with label if present, and carefully peel it off if it covers important information, or try a flash to shine through the label. Stick the label back later once you have succeeded in identifying the SOC.

Once you have identified the SOC, you can examine the data sheet. You can confidently get useful information. What voltages? Where are the UART pins? Which is TX, and which is RX? Which pins do you need to put it into programming mode? What are the default values if not specifically set?

Use the Espressif software to make a copy of the firmware, in case you cook something and have to solder a replacement SOC in place - you can then zap this original firmware back and pickup back from this step.

You can run this backup through a disassembler to identify where the UART settings are configured in the firmware. This then gives you a firm and definite spot to start logging serial traffic, either through the external connector (like you have already attempted), at the optocoupler inputs, or even at the SOC pins. You may be able to identify command strings getting sent and received embedded in the firmware using a HEX editor (hint: often right near the end, so start looking there). If this is too complex, you go back to guessing - what speed, stop bits, etc, but that may be an option if you have a lot of spare time. The commands may also be bit combinations, not ASCII, and be checksummed for error control, so don’t get your hopes up too high yet.

If you are extremely lucky, the entire LNK may actually be a simple WiFi to serial passthrough in transparent mode (the way GoodWe use the cheap HF-LPB100 SOC), and no decoding is needed - just an initialisation routine to pair it and then just pass data in both directions. If the LNK is translating or processing the traffic, the two options are the disassembly to follow the algorithms, configure a WireShark session on your computer, or sniffing the board. Now that you can confidently connect your own sniffer to the LNK at correct voltage and parameters, you then have to start looking for patterns in the traffic as you execute commands and see the results.

[Comment: this is turning onto a reverse engineering tutorial I may write for other people that attempt similar things]

Take the plunge - blow the protocol open. If Rainbird didn’t charge so much for their LNK’s, we wouldn’t be doing this, would we?

Now that you have piqued my curiosity, please keep us posted on progress.

[Post photos, traces, logs, etc in forum formatted </> options for readability would be appreciated]