Project Overview: 2S LiPo High-Current Power Box with two Sbus inputs
This circuit is a high-performance power distribution system designed for large-scale RC models. It manages power from dual batteries to drive up to 16 High-Voltage (HV) servos while providing redundancy from two Sbus receivers and electronic switching.
Key Technical Features
- Dual Battery Redundancy: The input stage features two "Ideal Diodes" (U$1, U$2). These allow for a dual-battery setup (2S LiPo, ~8.4V) with minimal voltage drop and prevent back-charging if one pack fails or has a lower voltage.
- High-Current Power Path: Utilizing multiple IRF4905 P-Channel MOSFETs in parallel, the board is designed to handle a continuous load of 20A, ensuring stable current delivery to 16 HV servos during high-torque maneuvers.
- Electronic Switching (Soft-Switch): * The circuit includes a logic stage (BSS123 N-FETs) that controls the main power MOSFETs.
- Compatibility: The "SW" header is designed to interface with Jeti RC switches or Magnetic switches. It uses a "fail-on" logic where the system remains powered if the switch signal is lost, enhancing safety.
- Servo Distribution: The output rail (VSERV) distributes power across 16 headers , supporting 16 primary servos with integrated decoupling capacitors (C1, C2, C3) to filter voltage spikes and electrical noise..
- Receivers decoding : An ESP32 will take care of decoding Sbus signal from two independant receivers and switch from one to the other in case of failure. Failsafe output can be configured
Schematics

PCB
The PCB can be bought at PCBWay


The PCB was kindly sponsored by PCBWay and is as usual of excellent quality.

You can order it here :PCBWay shared project. It's cheap, delivered very fast and so professional looking!
and if you are new to PCBWay please use this affiliated link : https://pcbway.com/g/o35z4O
As you can see "big" tracks are exposed to be reinforced either with solder or (better) with copper wire. Doing this will increase drastically the current capcabilities of this board. It will sustain up to 20A with a total of 16 servos powered with 2s lipo packs.
Power considerations
2x 2s lipo packs are used to power the box. The "OR" of their voltage is performed with two ideal diodes

These tiny devices are available for cheap on Aliexpress. They are mostly used as "anti back flow" components on solar panels. The XL 74610 is an ideal diode module built around the brilliant LM 74610 chip from Texas Instruments.
When paired with an N-channel power MOSFET, it behaves like a diode, but with a significantly lower voltage drop.

Switch control
A three stages mosfet combination allows to switch On/Off the power box

The three big P channels mosfets IRF4905 are used to cut the VCC line.
Each Mosfet can handle 74A
Heat Dissipation per MOSFET
- Current Split: Assuming the load is balanced, each MOSFET carries approximately 6.67A
- The IRF4905 has a typical resistance of 0.02Ω at VGS = -10V$.
- Power Dissipation per Component: P = 0.02 * (6.67)^2 = 0.89W
Thermal Analysis
- Total Power Box Dissipation: Approximately 2.67W of total heat across the power stage
This means that the mosfets should remain totally cold and no heatsink willbe needed.
Reliability : 3 mosfets are soldered in parallel allowing a very strong reliability in case of one or even two Mosfets failure.
Switching Logic and Fail-safe Mechanism
The switch circuit uses a dual-stage N-FET inverter logic to control the main high-power P-MOSFETs (Q7, Q8, Q9).
Operating States
- Off State (Switch Closed): When the switch pulls pin 3 of the SW header to GND, Q4 is turned off. This allows the gate of Q6 to be pulled High, turning Q6 ON. Q6 then pulls the gates of the IRF4905s to GND, which turns the main power ON.
- On State (Switch Open): Inversely, when pin 3 is High (3.3V or 5V), Q4 turns ON, pulling Q6's gate to GND and turning Q6 OFF. The 10k resistor (R6) then pulls the IRF4905 gates to VCC, turning the main power OFF.
Fail-safe Logic
This design features a "Fail-On" safety mechanism, which is standard for high-end RC power systems:
- Mechanical Failure: If the external switch fails, its wires are cut, or it becomes unplugged, the gate of Q4 is pulled to GND by the 10k pull-down resistor (R7).
- Result: Q4 remains OFF, Q6 remains ON, The IRF4905s stay ON.
- Safety Benefit: If the switch fails during flight, the power to your receiver and servos is maintained, preventing a crash.
Software
ESP32 firmware can be found on my Github pages
firmware is pretty simple and rely mostly on borderflight SbuS library
All the RF of the chip is disabled (no Wifi no Bluetooth) and a watchdog is enabled to reboot in case of emergency...
The toucpad "FAIL" allows to memorize all channels configuration. These values will be used to output "failsafe" values to servos if SBUS AND SBUS2 fail simultaneously.
//SBUS
#include "sbus.h" //https://github.com/bolderflight/sbus/tree/main
// two SBUS object, which are on hardware serial ports 1 and 2
bfs::SbusData data1;
bfs::SbusRx sbus_rx1(&Serial1, 34, 0, true); //ESP32 (true = inverted 3.3V from FSIA6B SBUS pin)
bfs::SbusData data2;
bfs::SbusRx sbus_rx2(&Serial2, 35, 0, true); //ESP32 (true = inverted 3.3V from FSIA6B SBUS pin)
//PWM for servos
#include //https://github.com/madhephaestus/ESP32Servo
uint16_t pwmPin[16] = { 14, 27, 26, 25, 33, 32, 19, 13, 16, 17, 18, 5, 23, 4, 2, 15 }; //contains pins for PWM output for each servo
uint16_t failsafe[16] = { 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500 }; //failsafe servos values for each 16 channels in µs
Servo servos[16];
uint16_t channels[16];
#define LED_PIN 22
//watchdog
#include <esp_task_wdt.h>
#define WDT_TIMEOUT 1 //1 seconds WDT
//touchpad
touch_pad_t touchPin;
int threshold = 35; //Threshold value for touchpads pins
long lastTouch;
#define FAIL_PIN 12
//wifi/bluetooth (just to switch them Off !)
#include <WiFi.h>
#include <bt.h>)
//Preferences
#include <Preferences.h>
Preferences preferences;
//#define DEBUG //uncomment to get debug messages
void setup() {
//stop Wifi and Bluetooth
WiFi.mode(WIFI_OFF);
btStop();
Serial.begin(115200);
delay(1000);
Serial.println("program started");
//Preferences
preferences.begin("sbusBox", false);
size_t size = preferences.getBytesLength("failsafe"); //check if failsafe is already saved
if (size == sizeof(failsafe)) {
preferences.getBytes("failsafe", failsafe, sizeof(failsafe)); //get values
} else preferences.putBytes("failsafe", failsafe, sizeof(failsafe)); // if not already done, save failsafe array
//preferences.clear(); // Remove all preferences under the opened namespace
//preferences.remove("counter"); // remove the counter key only
Serial.println("read preferences :");
Serial.print("\tstart at ");
//Serial.println(startThr);
//preferences.end(); // Close the Preferences
//SBUS
sbus_rx1.Begin();
sbus_rx2.Begin();
//servos PWM
for (int i = 0; i < 16; i++) {
servos[i].attach(pwmPin[i]); // each servo is attached to a "Ledc channel"
}
//start watchdog (will be reseted into the loop)
esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
}
void loop() {
esp_task_wdt_reset(); //reset the watchdog
if (sbus_rx1.Read()) { // if something on SBUS1
data1 = sbus_rx1.data();
#ifdef DEBUG
for (int8_t i = 0; i < data1.NUM_CH; i++) {
Serial.print(data1.ch[i]);
Serial.print("\t");
}
Serial.print(data1.lost_frame);
Serial.print("\t");
Serial.println(data1.failsafe);
#endif
}
if (sbus_rx2.Read()) { //if something on SBUS2
data2 = sbus_rx2.data();
#ifdef DEBUG
for (int8_t i = 0; i < data2.NUM_CH; i++) {
Serial.print(data2.ch[i]);
Serial.print("\t");
}
/* Display lost frames and failsafe data */
Serial.print(data2.lost_frame);
Serial.print("\t");
Serial.println(data2.failsafe);
#endif
}
//map SBUS to servos PWM
if (!data1.lost_frame && !data1.failsafe) { // if SBUS1 is "clean" use it !
for (int i = 0; i < 16; i++) {
int pulseWidth = map(data1.ch[i], 172, 1811, 1000, 2000);
servos[i].write(pulseWidth); //write directly pulsewodth to the library
channels[i] = pulseWidth;
}
digitalWrite(LED_PIN, LOW); // RX1 OK : LED on
} else if (!data2.lost_frame && !data2.failsafe) { // else if SBUS2 is clean use it
for (int i = 0; i < 16; i++) {
int pulseWidth = map(data2.ch[i], 172, 1811, 1000, 2000);
servos[i].write(pulseWidth); //write directly pulsewodth to the library
channels[i] = pulseWidth;
}
digitalWrite(LED_PIN, (millis() / 100) % 2 == 0 ? LOW : HIGH); // RX2 ok : blink LED
} else //apply failsafe
{
for (int i = 0; i < 16; i++) {
servos[i].write(failsafe[i]);
}
digitalWrite(LED_PIN, HIGH); // LED off in failsafe
}
//check if should save failsafe
if ((millis() - lastTouch) > 1000) { //avoid bouncing on touchpad
if (ftouchRead(FAIL_PIN) < threshold) {
Serial.println("touchpad - detected : save faisafe");
lastTouch = millis();
for (int i = 0; i < 16; i++) {
failsafe[i] = channels[i]; //save current position into failsafe array
}
preferences.putBytes("failsafe", failsafe, sizeof(failsafe)); // if not already done, save failsafe array into preferences
}
}
}
int ftouchRead(int gpio) // this will filter false readings of touchRead() function...
{
int val = 0;
int readVal;
for (int i = 0; i < 10; i++) { //perform 10 readings and keep the max
readVal = touchRead(gpio);
val = max(val, readVal);
}
return val;
}
Box for the power box
An enclosure for the PCB can be 3D printed. It will accomodate the PCB soldered with 90° pin headers, so that its form factor should remain "flat" when inserted into the plane.
If you prefer vertical pin headers, you will have to redesign the box (which is not complex !)
Parts are available on thingiverse : https://www.thingiverse.com/thing:7291279
JP Gleyzes