Your First Satellite Track
You have a working serial connection and the dish responds to position queries. Now let’s point it at something in the sky.
Prerequisites
Section titled “Prerequisites”- Serial connection confirmed working (see Your First Connection)
- Gpredict installed (or any Hamlib rotctld client)
- Dish physically mounted with “BACK” label aligned to true North
- Clear sky view (no obstructions taller than 8 inches within 32.5 inches of the base center)
Track a satellite
Section titled “Track a satellite”-
Disable the TV satellite search
On power-up, the firmware automatically starts searching for DirecTV/DISH Network satellites. This will fight your tracking commands if not stopped.
The
birdcage initcommand handles this automatically. It waits for boot to complete, then sends:ngsearch → s → qThis enters the search submenu, stops the search, and exits. You need to run init on every power cycle.
Also handled by
birdcage init. The older firmware uses a different approach — killing the search task through the OS task manager:os → kill Search → qThe G2 uses a permanent one-time configuration. Set NVS index 20 to TRUE using a serial terminal:
TRK> nvsNVS> e 20 1NVS> sNVS> qThis disables the tracker process permanently (survives power cycles). After setting this,
birdcage initskips the search kill entirely. -
Initialize the dish
Run the init command to boot the dish and prepare it for motor commands:
Terminal window uv run birdcage init --port /dev/ttyUSB0 --firmware hal205This waits for the boot signal (
NoGPSorNo LNB Voltage), kills the satellite search, and enters the motor menu. It may take 30-60 seconds on first power-up while the dish homes its motors.Terminal window uv run birdcage init --port /dev/ttyUSB2 --firmware g2With the tracker already disabled via NVS 20, this connects and enters the motor menu immediately.
You should see:
Connecting to /dev/ttyUSB2 (firmware: g2)...Antenna initialized and ready. -
Start the rotctld server
The
servecommand starts a TCP server that speaks the Hamlib rotctld protocol:Terminal window uv run birdcage serve \--port /dev/ttyUSB2 \--firmware g2 \--host 127.0.0.1 \--listen-port 4533 \--skip-initUse
--skip-initif you already raninitseparately. Without it, the serve command runs the full initialization sequence first.rotctld server listening on 127.0.0.1:4533Ctrl-C to stopThe server handles these commands from Gpredict:
Command Function pGet current AZ/EL position P <az> <el>Move dish to target position SStop tracking _Return model name qDisconnect For the Carryout G2, the server also supports extended commands:
R(read RSSI),L(enable LNA), andD(discover capabilities). -
Configure Gpredict
In Gpredict, add a rotor controller:
- Host:
127.0.0.1 - Port:
4533 - Az type:
0 -> 180 -> 360 - Min elevation: set per your variant (see table below)
- Max elevation: set per your variant
Variant Min Elevation Max Elevation Trav’ler (HAL 0.0.00) 15 deg 90 deg Trav’ler (HAL 2.05) 15 deg 90 deg Trav’ler Pro 12 deg 75 deg Carryout (2003) 22 deg 73 deg Carryout G2 18 deg 65 deg The firmware enforces these limits. Commands below the minimum elevation are clamped by
birdcagebefore being sent to the dish. - Host:
-
Track a satellite
Open Gpredict’s satellite list, select a target with an upcoming pass, and click Track. Gpredict will start sending
P(position) commands to the rotctld server at its configured update interval.In the terminal running
birdcage serve, you’ll see the motor commands flowing:14:23:01 INFO birdcage.antenna: Moving to AZ=145.3 EL=23.7 (move #0)14:23:02 INFO birdcage.antenna: Moving to AZ=145.8 EL=24.1 (move #1)14:23:03 INFO birdcage.antenna: Moving to AZ=146.2 EL=24.5 (move #2)The leap-frog algorithm adds a small predictive overshoot to each command, compensating for mechanical lag. Motor commands alternate between AZ-first and EL-first to prevent either axis from starving on the shared serial bus.
What’s happening under the hood
Section titled “What’s happening under the hood”When Gpredict sends P 145.3 23.7, here’s the chain:
- RotctldServer receives the TCP command and calls
antenna.move_to(145.3, 23.7) - BirdcageAntenna applies leap-frog compensation: if the dish is currently at 144.0 AZ and moving right, the target gets nudged to ~145.8
- BirdcageAntenna enforces the elevation floor (e.g., 18 deg for G2)
- BirdcageAntenna alternates motor order — even moves send AZ then EL, odd moves send EL then AZ
- FirmwareProtocol sends
a 0 145.8thena 1 23.7over serial - The dish firmware queues each motor command and executes them
The a <id> <deg> command is tolerant of rapid command streams — it queues the new target while the motor is still moving to the previous one. This is what makes Gpredict’s frequent updates work without overwhelming the firmware.
Troubleshooting
Section titled “Troubleshooting”Dish doesn’t move:
- Is the TV search still running? Check that you disabled it (step 1).
- Is the dish initialized? Run
birdcage initbeforeserve. - Are you in the motor submenu? The server handles this, but if you interrupted a previous session, the firmware may be in a different submenu.
Position reads as 2147483647:
- This is INT_MAX — the motor axis is uncalibrated. The dish needs to home before it can report position. Power-cycle and let the boot sequence complete.
Dish overshoots targets:
- The leap-frog algorithm adds intentional overshoot. For fine pointing, you can disable it:
birdcage move --no-leapfrog --az 180 --el 45.
Connection drops after a few minutes:
- Check your cable connections. RS-485/422 differential signaling is robust but loose wires cause intermittent failures.