Serial Protocol
The Winegard dish variants use two different differential signaling standards. Understanding which one your variant uses is essential for choosing the right USB adapter.
RS-485 vs RS-422
Section titled “RS-485 vs RS-422”RS-485 Half-Duplex (2-wire)
Section titled “RS-485 Half-Duplex (2-wire)”One shared differential pair carries both TX and RX. Only one device talks at a time — the transmitter drives the bus, then releases it so the other side can respond. This is how the Trav’ler IDU communicates with the ODU: the IDU sends a command on the shared T/R pair, then listens for the response on the same wires. Simple wiring (2 signal wires + ground), but throughput is limited by the turn-around time between send and receive.
RS-422 Full-Duplex (4-wire)
Section titled “RS-422 Full-Duplex (4-wire)”Two separate differential pairs — one dedicated TX pair and one dedicated RX pair. Both sides can transmit simultaneously because the signals do not share wires. Higher throughput (no bus turnaround penalty), and the Carryout G2 uses this at 115200 baud. Point-to-point only (one transmitter per pair).
RS-485 Full-Duplex (4-wire)
Section titled “RS-485 Full-Duplex (4-wire)”Electrically identical to RS-422 wiring (same 4-wire differential pairs), but the RS-485 spec allows multiple transmitters on each pair (multi-drop bus). For our point-to-point dish-to-computer connection, 4-wire RS-485 and RS-422 are interchangeable.
Comparison Table
Section titled “Comparison Table”| Property | RS-485 half-duplex | RS-422 / RS-485 full-duplex |
|---|---|---|
| Signal wires | 2 (+ GND) | 4 (+ GND) |
| Direction | One direction at a time | Both directions simultaneously |
| Max nodes | 32 drivers + 32 receivers | 1 driver + 10 receivers (RS-422) |
| Max distance | 1200m / 4000ft | 1200m / 4000ft |
| Max baud | ~10 Mbps | ~10 Mbps |
| Voltage swing | +/-1.5V to +/-5V differential | +/-2V to +/-5V differential |
| Bus turnaround | Required (adds latency) | Not needed |
| Typical adapter | USB-to-RS485 (DTECH, etc.) | USB-to-RS422 (FTDI, DIYables, etc.) |
Hardware Protocol Notes
Section titled “Hardware Protocol Notes”- RS-485 serial, 57600 baud, 8N1 (Trav’ler variants) or RS-422, 115200 baud, 8N1 (Carryout G2)
- Motor commands:
a <motor_id> <degrees>(0=azimuth, 1=elevation) - Position query:
a(in motor submenu) returns position in variant-specific format - Two motor control methods:
a <id> <deg>— queues command, waits for current motor to finish. Tolerant of rapid command streams from Gpredict.g <az> <el> <sk>— immediate move, aborts on any new keystroke/character. Some firmware has a typo listing the order as az/sk/el.
- Skew motor can run simultaneously with AZ or EL (the others are mutually exclusive)
- Elevation floor: HAL 2.05 unreliable below 15 degrees with direct motor commands
- Cable wrap limit: usually 360 or 455 degrees, dish reverses at limit
- Console does not accept backspace — hit enter to clear on typo
- Firmware prompt character is
>(ASCII 62) — used for reliable response termination in prompt-terminated read strategies - Firmware expects ASCII CR (
0x0D) as line terminator
RS-422 Module Notes (DIYables MAX490)
Section titled “RS-422 Module Notes (DIYables MAX490)”The DIYables RS422-to-TTL module uses the MAX490 transceiver chip (2.5 Mbps max, well above the 115200 baud requirement).
Module Specs
Section titled “Module Specs”- 5V TTL logic on the microcontroller side (RXD/TXD)
- 15 kV ESD protection on RS-422 lines
- TVS diode for lightning/spike suppression
- 10 ohm current-limiting resistors for overcurrent protection
- Built-in 120 ohm termination resistor (reduces echo on long runs)
- Power + TX/RX activity LEDs
- Board size: 5.0cm x 2.7cm
Failsafe Concern
Section titled “Failsafe Concern”Workaround options:
-
Add external bias resistors — pull A/RX+ toward V+ and B/RX- toward GND through ~560 ohm resistors. This biases the idle bus to a known logic-high state (RS-422 “mark” / idle). Solder to the module or add inline on the RJ-12 breakout.
-
Use the prompt-terminated read strategy — the
CarryoutG2Protocol._send()reads until>(ASCII 62) which naturally filters out garbage between commands, since random transitions are unlikely to produce a valid>in context. -
Ignore idle noise in firmware — the Winegard firmware likely ignores unexpected input while it is processing or idle, but any bytes received during the bus float could corrupt the next valid command if they land in the UART buffer at the wrong time.
For short cable runs (under ~3m between ESP32 and dish), the built-in 120 ohm termination is sufficient and bus float is less likely to cause issues. For longer runs or electrically noisy environments (near motors, power supplies), add the bias resistors.
Known Console Hazards
Section titled “Known Console Hazards”Command Response Format
Section titled “Command Response Format”One-Shot Commands
Section titled “One-Shot Commands”Execute once, return a result, and show the prompt (>). Safe to use programmatically.
a Angle[0] = 180.00 Angle[1] = 45.00MOT>Streaming Commands
Section titled “Streaming Commands”Run indefinitely until interrupted. Some accept q to stop, others require closing the serial port. Known streamers include ts, agc, lnbv, snr, qls, nid, and stats.
Reads:1 SNR[avg: 0.0 cur: 0.0]Reads:2 SNR[avg: 0.0 cur: 0.0]...Write Commands
Section titled “Write Commands”Modify state (motor position, NVS values, fault registers). The firmware provides no confirmation prompts for destructive operations.
Prompt-Terminated Reading
Section titled “Prompt-Terminated Reading”The most reliable strategy for programmatic serial communication is to read until the prompt character > (ASCII 62) appears. This is what the CarryoutG2Protocol._send() method does:
def _send(self, cmd: str) -> str: self._serial.write(f"{cmd}\r".encode("ascii")) resp_data = bytearray() while True: byte = self._serial.read(1) if len(byte) == 0: raise TimeoutError(f"No prompt after command: {cmd!r}") resp_data.append(byte[0]) if byte[0] == 62: # ASCII '>' break return resp_data.decode("utf-8", errors="ignore")This approach handles variable-length responses and is resilient to bus noise, since random garbage is unlikely to produce a valid > in the expected context.