build-guides
Guide 4: Wiring & Control Integration
Replace the RC receiver with Pi control — ESC arming, steering, battery monitoring, complete wiring diagram
Build Guide 4: Wiring & Control Integration
Type: Build Guide
This is where the Pi takes control of the truck. By the end of this guide, you'll be able to steer and drive the TRX-4 from Python code. This is the most wiring-intensive guide — take your time, double-check connections, and label your wires.
What You Need
Parts:
- 3x servo extension cables (JR/Futaba style)
- JST connector taps (for battery monitoring)
- Terminal block
- Ground wire
- Buzzer module (optional)
Tools:
- Soldering iron + solder
- Wire strippers
- Heat shrink tubing
- Multimeter
- Electrical tape
- Labels or masking tape + marker
From previous guides (already mounted):
- Pi with PCA9685 and ADS1115 inside enclosure
- TRX-4 with ESC and steering servo
Understanding the Stock Wiring
Before we tap in, know what's already there:
[TRX-4 Stock Setup]
Main LiPo Battery
│
├──→ ESC (Electronic Speed Controller)
│ ├──→ Drive Motor (power wires)
│ ├──→ Receiver port (3-wire: signal, +5V, GND)
│ └──→ BEC output: provides 5-6V to receiver and servos
│
└──→ Steering Servo
└──→ Receiver port (3-wire: signal, +5V, GND)
Stock RC Receiver
├── CH1: Steering servo signal
└── CH2: ESC/throttle signal
What we're doing: Removing the RC receiver from the loop and connecting the PCA9685 in its place. The PCA9685 becomes the new "brain" that sends PWM signals to the ESC and steering servo.
Step 1: Disconnect the Stock Receiver
- Power off the TRX-4 (unplug the main battery)
- Locate the RC receiver — it's a small box connected to the ESC and steering servo via 3-pin cables
- Unplug the servo extension cables from the receiver
- Remove the receiver entirely — you won't need it anymore
- Keep the receiver and stock transmitter in case you ever want to go back to manual RC control
You now have two dangling 3-pin connectors:
- One from the ESC (throttle control)
- One from the steering servo
Step 2: Wire the PCA9685 Power Rail
The PCA9685 has two power inputs:
- VCC (3.3V from Pi via I2C) — powers the logic chip
- V+ (servo power rail) — powers whatever's connected to the output channels
The ESC's BEC (Battery Eliminator Circuit) outputs ~5-6V on the servo connector's red wire. We'll use this to power the PCA9685's V+ rail:
- Take one servo extension cable and cut it in half
- Identify the three wires: Signal (usually white or orange), Power (red), Ground (brown or black)
- Connect the ESC's connector to PCA9685 channel 1:
- Signal wire → PCA9685 channel 1 signal pin
- Red wire → V+ rail (this powers the PCA9685 servo outputs)
- Ground wire → GND rail
Important: You only need to connect V+ from ONE source. The ESC's BEC is the best choice because it's already regulated. Do NOT also connect a separate 5V supply to V+ — you'll create a power conflict.
Step 3: Connect the Servo Cables
Steering servo → PCA9685 Channel 0:
- Plug the steering servo's 3-pin connector directly into PCA9685 channel 0
- Signal, V+, and GND all route through the channel header
ESC → PCA9685 Channel 1:
- Already connected from Step 2
Channel assignments:
| Channel | Device | Purpose |
|---|---|---|
| 0 | Steering servo | Left/right steering |
| 1 | ESC | Forward/reverse throttle |
| 2 | (spare) | Future: camera tilt servo |
| 3 | (spare) | Future: buzzer or LED control |
Step 4: Common Ground
This is critical and easy to forget. All grounds must be connected:
- Pi GND
- PCA9685 GND
- ADS1115 GND
- TRX-4 ESC/battery GND
The PCA9685 GND connects to the Pi via I2C wiring (already done). The ESC GND connects via the servo cable (done in Step 2). But we need to verify the ADS1115 shares the same ground:
Use the terminal block as a ground bus:
- Run a ground wire from the Pi's GND pin to the terminal block
- Run a ground wire from the ADS1115 GND to the terminal block
- Run a ground wire from the voltage divider's GND to the terminal block
- Run a ground wire from the ESC/battery GND to the terminal block
Test with multimeter: Set to continuity mode and check that all ground points beep when you touch them together. If any don't — find and fix the break.
Step 5: Battery Monitoring Circuit
Connect the voltage divider to the main LiPo battery so the Pi can monitor charge level:
TRX-4 Main LiPo (+)
│
├──→ [JST Tap] ──→ Voltage Divider Input (+)
│
└──→ ESC (normal power path, unchanged)
Voltage Divider Output ──→ ADS1115 Channel A0
Voltage Divider GND ──→ Common Ground Bus
Using the JST tap: This connects in parallel with the existing battery connector — it doesn't interrupt the power flow to the ESC. You're just reading the voltage, not drawing meaningful current.
Verify the reading:
# On the Pi, with the TRX-4 battery connected
python ~/rover/test_adc.py
You should see the battery voltage (~7.4V for a charged 2S LiPo, ~6.6V for a discharged one).
Step 6: Optional — Buzzer
If you have a buzzer module, connect it to a GPIO pin:
| Buzzer Pin | Pi Pin |
|---|---|
| Signal | GPIO 17 (Pin 11) |
| VCC | 5V (Pin 2) |
| GND | GND (common bus) |
Quick test:
import RPi.GPIO as GPIO
import time
BUZZER_PIN = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.output(BUZZER_PIN, GPIO.HIGH)
time.sleep(0.5)
GPIO.output(BUZZER_PIN, GPIO.LOW)
GPIO.cleanup()
print("Beep!")
Step 7: The Moment of Truth — ESC Arming
Safety first: Put the TRX-4 on a stand or flip it upside down so the wheels are off the ground. The truck WILL try to move during this test.
The ESC needs to see a "neutral" throttle signal on startup to arm itself. This is critical:
# ~/rover/test_esc_arm.py
from adafruit_pca9685 import PCA9685
from adafruit_motor import servo
import board
import busio
import time
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c)
pca.frequency = 50
# ESC on channel 1, treated as a "continuous rotation servo"
# Neutral is ~90 degrees in servo terms
esc = servo.ContinuousServo(pca.channels[1])
print("Sending neutral signal... (plug in TRX-4 battery NOW)")
esc.throttle = 0 # Neutral
time.sleep(3) # Give ESC time to arm
print("ESC should be armed. You should have heard the arming beep sequence.")
print("Sending very light forward throttle...")
esc.throttle = 0.1 # Gentle forward
time.sleep(2)
print("Back to neutral...")
esc.throttle = 0
time.sleep(1)
pca.deinit()
print("Done.")
Sequence:
- Run the script (it sends neutral immediately)
- Plug in the TRX-4 main battery within the first 3 seconds
- Listen for the ESC arming beep sequence (usually 2-3 beeps)
- The wheels should spin gently forward, then stop
If the ESC doesn't arm: The neutral point might be slightly off. Try adjusting esc.throttle = 0 to small values like 0.02 or -0.02. ESCs are picky about what they consider "neutral."
Step 8: Test Steering
With the truck still on a stand:
# ~/rover/test_steering.py
from adafruit_pca9685 import PCA9685
from adafruit_motor import servo
import board
import busio
import time
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c)
pca.frequency = 50
steer = servo.Servo(pca.channels[0])
print("Center...")
steer.angle = 90
time.sleep(1)
print("Full left...")
steer.angle = 50
time.sleep(1)
print("Center...")
steer.angle = 90
time.sleep(1)
print("Full right...")
steer.angle = 130
time.sleep(1)
print("Center...")
steer.angle = 90
pca.deinit()
print("Done.")
Watch the front wheels — they should sweep left, center, right, center.
If the range is wrong (wheels don't turn enough, or servo buzzes at the limits), adjust the angle values. We'll do precise calibration in Guide 5.
Complete Wiring Diagram
Anker USB Battery ──USB-C──→ Raspberry Pi 4
│
┌───────────┼───────────┐
│ I2C │ I2C │ GPIO
▼ ▼ ▼
PCA9685 ADS1115 Buzzer
(0x40) (0x48) (GPIO 17)
│ │ │
CH0 │ │ CH1 │ A0
▼ │ ▼ │
Steering │ ESC ▼
Servo │ │ Voltage Divider
│ │ │
│ ▼ │
│ Drive │
│ Motor │
│ │
└──────────────┘
Common GND
│
TRX-4 Main LiPo
(drives ESC,
monitored by
ADC via divider)
Camera Module 3 ──CSI ribbon──→ Pi Camera Port
GPS Module ──Serial──→ Pi UART (GPIO 14/15)
Helpful Resources
- Raspberry Pi ESC Motor Tutorial (Rototron) — Thorough walkthrough of ESC arming/calibration with a Pi, including the exact pulse-width sequence, wiring diagrams, and working Python code.
Checklist
- Stock RC receiver removed
- ESC connected to PCA9685 channel 1 (with BEC powering V+ rail)
- Steering servo connected to PCA9685 channel 0
- Common ground verified across all components
- Battery monitoring circuit wired (JST tap → divider → ADC)
- ADC reads correct battery voltage
- ESC arms successfully with Pi sending neutral signal
- Steering sweeps left/center/right
- Wheels spin forward on throttle command (truck on stand!)
- Buzzer beeps (optional)
The truck is alive. Guide 5: First Drive & Calibration takes it off the stand and onto the ground.
