Skip to content

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.

  • 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)
  1. 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 init command handles this automatically. It waits for boot to complete, then sends:

    ngsearch → s → q

    This enters the search submenu, stops the search, and exits. You need to run init on every power cycle.

  2. 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 hal205

    This waits for the boot signal (NoGPS or No 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.

    You should see:

    Connecting to /dev/ttyUSB2 (firmware: g2)...
    Antenna initialized and ready.
  3. Start the rotctld server

    The serve command 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-init

    Use --skip-init if you already ran init separately. Without it, the serve command runs the full initialization sequence first.

    rotctld server listening on 127.0.0.1:4533
    Ctrl-C to stop

    The server handles these commands from Gpredict:

    CommandFunction
    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), and D (discover capabilities).

  4. 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
    VariantMin ElevationMax Elevation
    Trav’ler (HAL 0.0.00)15 deg90 deg
    Trav’ler (HAL 2.05)15 deg90 deg
    Trav’ler Pro12 deg75 deg
    Carryout (2003)22 deg73 deg
    Carryout G218 deg65 deg

    The firmware enforces these limits. Commands below the minimum elevation are clamped by birdcage before being sent to the dish.

  5. 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.

When Gpredict sends P 145.3 23.7, here’s the chain:

  1. RotctldServer receives the TCP command and calls antenna.move_to(145.3, 23.7)
  2. BirdcageAntenna applies leap-frog compensation: if the dish is currently at 144.0 AZ and moving right, the target gets nudged to ~145.8
  3. BirdcageAntenna enforces the elevation floor (e.g., 18 deg for G2)
  4. BirdcageAntenna alternates motor order — even moves send AZ then EL, odd moves send EL then AZ
  5. FirmwareProtocol sends a 0 145.8 then a 1 23.7 over serial
  6. 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.

Dish doesn’t move:

  • Is the TV search still running? Check that you disabled it (step 1).
  • Is the dish initialized? Run birdcage init before serve.
  • 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.