Building a SatDump-Compatible Satellite Antenna Rotator with an ESP32, ADS1115 and Pelco PT570P
A Satellite tracker build using the Pelco PT570Pβs factory position pots, an ADS1115, an ESP32 web interface and SatDumpβs rotctl protocol.
Commercial satellite rotators are convenient, but older broadcast hardware can be a surprisingly good foundation for a precise, network-connected antenna positioner. This project combines a 120-volt Pelco PT570P/PP pan/tilt head, an ESP32, an ADS1115 analog-to-digital converter, and four isolated motor-control channels to make a rotator that SatDump can command directly.
The finished architecture
SatDump
β Hamlib/rotctl TCP, port 4533
βΌ
ESP32 βββββ web setup, calibration and status
β
βββ IΒ²C ββ ADS1115 ββ pan and tilt position pots
β
βββ four logic outputs ββ isolated motor switching
β
βββ PT570P LEFT/RIGHT/UP/DOWNThe ESP32 has three jobs. It reads position feedback, serves a local setup/status page, and implements the subset of the Hamlib rotctl protocol used by SatDump. It does not continuously run a motor until the target is reached. Instead, it applies a short pulse, switches everything off, waits for electrical and mechanical settling, reads the pots, and decides whether another pulse is needed.
That pulse-and-settle approach is well suited to the PT570Pβs nominal 6Β°/second pan and 3Β°/second tilt speeds. The default 150 ms pulse represents roughly 0.9Β° of pan or 0.45Β° of tilt before inertia and loading are considered. Configurable deadbands prevent the controller from hunting around a target.
Hardware used
- Classic ESP32 DevKit/WROOM-class board
- ADS1115 16-bit IΒ²C ADC breakout
- Pelco PT570P/PP with factory 5 kΞ© position pots
- Four isolated motor-rated switching channels
I started with a four-channel MOC3061 TRIAC module. A warning is necessary here: βMOC3061β identifies the zero-cross optotriac driver, not the power switching capability of the complete module. The main TRIAC part number, heat sinking, snubber network, creepage, terminal rating and inductive-load rating all matter. An anonymous board should not be assumed suitable merely because its advertised current exceeds the PT570Pβs 0.18 A running and 0.27 A starting current.
Why the ADS1115 replaced the IMU
An IMU is attractive when a mechanism has no position feedback, but it creates several difficulties on a steel outdoor pan/tilt:
- A magnetometer sees the mount, mast, motors, feedline current and nearby structures as magnetic errors.
- An accelerometer can provide tilt, but not reliable absolute azimuth.
- The IMU reports the orientation of its circuit board, so mounting alignment becomes another calibration variable.
- Motor vibration and acceleration contaminate measurements while moving.
The Pelco pots avoid those problems. They are mechanically coupled to the output axes and give an absolute position immediately after boot. The ESP32 does have internal ADCs, but the external ADS1115 provides more resolution, predictable scaling and easier analog filtering.
The ADS1115 runs at address 0x48, with its ADDR pin grounded. The firmware selects GAIN_ONE and 128 samples/second, then averages four interleaved readings from each axis. Interleaving helps keep the two measurements close in time and reduces coupled 50/60 Hz noise.
The Pelcoβs original controller excited the pots from 5 V. In this design they are passive 5 kΞ© elements excited from regulated 3.3 V instead. This is important: a 3.3 V-powered ADS1115 input is not 5 V tolerant merely because its programmable gain is set to a Β±4.096 V range. TI limits the physical input pins to the supply rails, with only the small absolute-maximum margin specified in the data sheet.
ESP32 and ADS1115 wiring
| ESP32 connection | Function |
|---|---|
| GPIO 25 | LEFT control output |
| GPIO 26 | RIGHT control output |
| GPIO 27 | UP control output |
| GPIO 14 | DOWN control output |
| GPIO 21 | ADS1115 SDA |
| GPIO 22 | ADS1115 SCL |
| GPIO 33 | Provisioning button to GND |
| 3V3 | ADS1115 VDD and pot excitation |
| GND | ADS1115, pots and low-voltage control reference |
ESP32 3V3 βββββββ¬ββββββββ ADS1115 VDD
βββββββββ Pelco WHITE/BROWN (pot excitation)
ESP32 GND βββββββ¬ββββββββ ADS1115 GND + ADDR
βββββββββ Pelco WHITE/BLACK (pot common)
ESP32 GPIO21 βββββββββββββ ADS1115 SDA
ESP32 GPIO22 βββββββββββββ ADS1115 SCL
Pelco WHITE/GREEN ββ 1k βββ¬ββ ADS1115 A0 (pan)
βββ 1Β΅F ββ GND
βββ 1MΞ© ββ GND
Pelco WHITE/VIOLET β 1k βββ¬ββ ADS1115 A1 (tilt)
βββ 1Β΅F ββ GND
βββ 1MΞ© ββ GNDAt the ADC board, add 100 nF ceramic and 10 Β΅F bulk decoupling from VDD to GND. If the breakout has no IΒ²C pull-ups, add approximately 4.7 kΞ© from SDA and SCL to 3.3 V. Avoid blindly adding more pull-ups when a breakout already contains them.
The 1 kΞ© input resistors and 1 Β΅F capacitors form simple low-pass filters. The 1 MΞ© pulldowns make a disconnected wiper tend toward zero, although that is not perfect open-wire detection when a legitimate endpoint can also approach zero. Route feedback separately from mains and motor conductors; shielded twisted pairs are worth using on a long outdoor run.
PT570P internal wire colors
The connector had already been removed from this unit, so the build uses the factory internal wire colors rather than connector pin numbers. Pelcoβs service drawing identifies them as follows:
| Internal wire | Factory function | Connection here |
|---|---|---|
| Brown | Motor common | AC neutral |
| Red | Pan left | Switched AC line from LEFT |
| Blue | Pan right | Switched AC line from RIGHT |
| Orange | Tilt up | Switched AC line from UP |
| Yellow | Tilt down | Switched AC line from DOWN |
| Green | Frame/safety ground | Protective earth; never switch |
| White/green | Pan-position wiper | 1 kΞ© to ADS1115 A0 |
| White/violet | Tilt-position wiper | 1 kΞ© to ADS1115 A1 |
| White/brown | Pot excitation | Regulated 3.3 V |
| White/black | Position-pot common | Low-voltage GND |
| White | Optional heater neutral | Individually insulate unless used |
| Black | Optional heater 120 V | Individually insulate unless used |
Color is not proof when a harness may have been repaired. With all power removed, verify green-to-frame continuity, measure approximately 5 kΞ© between white/brown and white/black, and verify that each wiper resistance changes smoothly as the appropriate axis moves. Do not force the worm drive by hand.
The 120 VAC functional arrangement
120 VAC LINE
β
lockable disconnect
β
safety contactor controlled by hardwired E-stop loop
β
correctly selected protection
βββ motor-rated LEFT switch ββ RED
βββ motor-rated RIGHT switch ββ BLUE
βββ motor-rated UP switch ββ ORANGE
βββ motor-rated DOWN switch ββ YELLOW
120 VAC NEUTRAL βββββββββββββββββββ BROWN
PROTECTIVE EARTH ββββββββββββββββββ GREEN/frameNever energize LEFT and RIGHT together, or UP and DOWN together. The firmware preloads every GPIOβs inactive output latch before changing it to an output, stops all channels before selecting a direction, and inserts a break-before-make delay. External pull-ups or pulldowns are still required to guarantee the inactive state while the ESP32 is reset or unpowered.
The correct polarity depends on the input circuit of the exact switching board. A direct low-trigger module uses the firmwareβs Active low option. A direct high-trigger module uses Active high. If a low-trigger module needs an NPN open-collector interface, the ESP32βs high level turns the transistor on, so the firmware should also be configured as Active high. Determine this with the AC side completely disconnected.
How the control loop works
Two-point calibration maps each ADC channel into physical degrees. Raw counts are allowed to increase or decrease with movement, so the wiring orientation does not need to be changed just to obtain a positive slope. Degree values must still increase from left to right and from down to up.
position = degree_at_first_endpoint
+ (raw - raw_at_first_endpoint)
Γ degree_span / raw_spanBefore accepting a motion target, the controller verifies that:
- The ADS1115 is present and acknowledging on IΒ²C.
- Both calibration spans are plausible and have been explicitly confirmed.
- Motor outputs have been deliberately enabled.
- The current feedback is inside the calibrated range plus a small fault margin.
- The requested azimuth and elevation are inside configured travel limits.
- A valid rotctl client is still connected and communicating.
Only one axis and direction is pulsed at a time. After the pulse, all outputs are turned off, a settle timer runs, and feedback is sampled again. The controller selects the axis with the larger normalized error, which keeps both axes progressing without energizing two motor channels simultaneously.
A fixed-size nonblocking TCP parser is used instead of Arduinoβs blocking line-reading helpers. This matters in a motor controller: a client that sends half a command must not be able to hold the processor inside a network timeout while an output remains energized.
Matching SatDumpβs rotctl behavior
SatDump talks to rotators through a Hamlib-style TCP service. The ESP32 listens on port 4533 and supports:
pand\get_posto read azimuth and elevationP az eland\set_posto set a targetSand\stopto stop and discard the target
A subtle watchdog issue appeared during source review. SatDump keeps one TCP connection open and asks for position on each update, but it may not resend an unchanged target. Therefore, refreshing the safety timer only on P commands would eventually cancel a perfectly healthy tracking session. The firmware refreshes the timer on every valid position query, target command or stop command. A disconnected client still causes an immediate stop and target discard.
For a manual test, keep a netcat session open:
nc ESP32_IP 4533
p
P 180 30
p
SA position query returns azimuth and elevation on separate lines. A valid target or stop returns RPRT 0; an unsafe or invalid target returns RPRT -1.
Web setup and status
On first bootβor after a 15-second Wi-Fi connection failureβthe ESP32 starts PT570P-Setup-xxxxxx. The setup network and initial web login use the temporary password pt570setup. The interface accepts the normal 2.4 GHz Wi-Fi SSID and password, a replacement web-admin password, calibration endpoints, output polarity, pulse timing, deadbands and permitted elevation range.
Motion is forcibly disabled in RAM whenever the fallback setup AP is active. This is intentional because the fallback network uses a known initial password. Calibration must be reviewed and motion explicitly enabled from the normal trusted network.
The status page reports:
- Wi-Fi address and connection state
- ADS1115 presence and feedback health
- Current raw A0/A1 counts
- Calculated azimuth and elevation
- Requested target and active direction
- Calibration and motor-enable state
- A feedback fault or range rejection
The GUI uses HTTP Basic authentication and POST request tokens, but Basic authentication is not encrypted over ordinary HTTP. Keep the controller on a trusted or isolated IoT network. Never port-forward the web interface or unauthenticated rotctl port to the public internet; use a VPN if remote access is required.
Calibration and staged commissioning
The safe order is deliberately slow.
Stage 1: no AC connected
- Identify every Pelco conductor with resistance and continuity tests.
- Wire only the ESP32, ADS1115, position pots, provisioning switch and unpowered control inputs.
- Upload the firmware and confirm that both raw ADC readings are stable.
- Verify all four logic outputs are inactive during reset, setup mode and loss of ESP32 power.
- Determine the switching moduleβs input polarity without its mains side connected.
Stage 2: establish position references
- Choose where to place the PT570Pβs approximately 5Β° unreachable pan sector. The mechanism travels 355Β°, while azimuth is a 360Β° coordinate.
- Use a suitable supervised controller to reach the safe left limit and capture the pan raw count and true azimuth.
- Move to the safe right limit and capture the corresponding values.
- Repeat for the down and up tilt limits.
- Check several known intermediate angles. Endpoint calibration cannot correct pot or gear nonlinearity.
- Mark calibration as verified, but leave motor outputs disabled.
Stage 3: supervised powered testing
- Have the completed AC section inspected before energizing it.
- Begin with the antenna load removed or safely supported.
- Energize through the external disconnect, protection, contactor and emergency-stop system.
- Test one short pulse in each direction and verify the mechanical limit switches.
- Enable motor outputs and test small targets before attempting large slews.
- Watch overshoot, feedback noise, cable motion, enclosure temperature and duty cycle.
Pelco specifies a 50% duty cycle and a 30-minute operating rating. Pulsed control helps, but repeated full-travel testing can still exceed the mechanismβs intended service. Duty-cycle supervision remains part of commissioning and operation.
SatDump configuration
- Give the ESP32 a DHCP reservation so its address stays fixed.
- In SatDumpβs Recorder/Tracking view, select the rotctl rotator handler.
- Enter the ESP32 address and port
4533. - Confirm SatDump displays the same position as the web GUI.
- Test manual targets before enabling automatic tracking.
- Keep park position and minimum elevation inside the calibrated travel.
- Run a simulated or low-risk pass before installing the final antenna and feedline load.
Firmware verification and remaining work
The complete sketch compiles without warnings for the ESP32 Dev Module using ESP32 Arduino core 3.3.10, Adafruit ADS1X15 2.6.2 and Adafruit BusIO 1.17.4. The build occupies about 1.06 MB of flash and 51 KB of static RAM.
Compilation and source review are not the same as field validation. The exact TRIAC board still needs to be identified and electrically tested, and the final installation needs staged motion, noise, thermal, grounding, weather and fault testing. The highest-value upgrades would be documented interlocked motor switching, a hardware watchdog and maximum-run timer, latched fault reporting, surge protection, and multi-point calibration or absolute encoders if pointing tests show meaningful midpoint error.
References
- Pelco PT550P/PT570 maintenance and service manual
- Pelco PT570P specification sheet
- Texas Instruments ADS1115 data sheet
- Adafruit ADS1X15 Arduino library
- Hamlib rotctl command reference
- SatDump rotctl handler source
This project turns a sturdy piece of legacy positioning hardware into a practical SatDump rotator without pretending that software alone solves mains safety. The factory position pots, external ADC, cautious motion loop and staged commissioning process are what make the design predictable.