Hi everyone, I’m Ivan. If you’ve been following my robotics journey, you know I am obsessed with finding efficient, accessible ways to build advanced animatronics without spending thousands of dollars on smart servos.
- Part1, I introduced the core concept: replacing expensive servos with affordable N20 DC motors and potentiometers. I proved we could get precise position control with a simple PID loop.
- Part2, I applied that concept to a robotic lower arm using an Arduino Uno and an L293D shield. It worked beautifully, and I was honored to have that project featured here on Hackster.
But I hit a wall. The L293D shield maxed out at 4 motors. A human hand has 5 fingers. A full humanoid robot (like the InMoov) has over 25 degrees of freedom. To build the full robot, I couldn't just stack more shields—I would need a mountain of Arduinos and a nightmare of wiring.
I needed a new architecture. I needed a way to control dozens of motors simultaneously, with position feedback, using just 4 wires.
2. The Hardware Solution: A Distributed I2C "Nervous System"Instead of running every single motor wire back to one central brain (which creates a massive, stiff cable bundle), I designed a Hub-and-Spoke topology.
The Architecture- The Brain (Master): An Arduino Mega 2560. It handles the logic and communication with the PC.
- The Router: A TCA9548A Multiplexer. Since I2C devices usually have fixed addresses, this chip allows me to split one bus into 8 separate channels (Ports 0-7), preventing address conflicts.
- The "IvanModules": These are custom clusters of chips placed inside the robot's body parts (one in the head, one in each arm, etc.).
Each module connects to one port of the Multiplexer and contains:
- PCA9685: A 16-channel PWM driver. It handles the motor signals. Crucially, it latches the commands—once told to move, it keeps the motor running until told to stop, freeing up the Arduino.
- TB6612FNG: A dual motor driver. It is much more efficient than the L293D (less heat, more power) and takes signals directly from the PCA9685.
- ADS1115: A high-precision Analog-to-Digital converter. It reads the potentiometers from the joints with far greater accuracy than the Arduino's built-in pins.
With this setup, one module can control 4 DC Motors and 4 Servos simultaneously. With 8 ports on the multiplexer, this system can scale to 64 actuators.
One of the biggest hurdles I faced was mixing DC Motors and Standard Servos on the same driver chip (PCA9685).
- The Constraint: Standard SG90 Servos generally require a PWM frequency of roughly 50-60Hz. The PCA9685 applies one frequency to all 16 pins.
- The Conflict: N20 DC Motors usually prefer high frequencies (1000Hz+). If you try to run a DC motor at 50% speed at 60Hz, it vibrates violently, makes audible noise, and loses torque.
To solve this without adding expensive hardware, I implemented a specific control strategy in the firmware:
- Servos receive standard variable angles at 60Hz.
DC Motors are driven in Bang-Bang Mode.
- The system ignores variable speed commands (e.g., 50% or 80%).
- If the motor needs to move, it receives 100% duty cycle (Full Voltage).
- If it needs to stop, it receives 0%.
This eliminates the 60Hz jitter. The motors move with maximum torque until they reach their target position, at which point the Python control loop cuts the power.
4. The Software: "Robot Studio"To manage this complex system, I developed Robot Studio, a desktop application written in Python (PyQt6). It acts as the "Cerebellum" of the robot.
Feature 1: The "Ghost-Lead" SynchronizationThe software controls a virtual "Ghost" robot on screen. The physical robot is forced to chase the Ghost.
- The User moves the Ghost (via Slider, IK, or Animation).
- The Physics Engine ensures the Ghost isn't colliding with itself.
- The Control Loop calculates the difference (Error) between the Ghost's joint angle and the Physical Robot's potentiometer value.
- The Driver sends a "Full Speed" command to catch up, then stops exactly when the sensor matches the target (within a tunable tolerance).
This is a pragmatic tool for builders. Instead of re-flashing code to change a pin, I built a UI where I can map any logical body part to any physical pin.
- Example: "Right Index Finger" -> Mapped to "Module 2, Pin 4".
- It includes a Live Diagnostic tool to scan the I2C bus and read sensor snapshots for debugging.
I built a JSON editor directly into the app. I can tweak safety limits, tolerances, or even import a completely different robot definition (like a Hexapod) and apply it instantly without restarting the application.
While my focus is the InMoov, I designed this architecture to be completely robot-agnostic. The entire structure of the robot—limb lengths, joint limits, and hierarchy—is defined in a simple JSON file.
You could write a spider.json file to control a 42-actuator hexapod, or a rover_arm.json for a mobile platform. The physics engine, the pin mapping, and the control loops will adapt instantly to whatever shape you define. It is effectively a universal operating system for custom Arduino robotics.
This architecture successfully allows a single Arduino Mega to coordinate over 40 actuators.
- Servos move with smooth, variable speed.
- DC Motors move with high torque and snap precision.
- Wiring is reduced from a massive bundle to a single 4-wire daisy chain.
I have open-sourced the entire platform.
- Python App: Runs on Windows/Linux/Mac.
- Arduino Firmware: Runs on the Mega 2560.
- Config Files: Pre-set for InMoov, but editable for any robot.
This project has evolved from a single motor on a breadboard to a comprehensive robotic control platform. By moving to a distributed I2C architecture, I have solved the scalability problem.
In the next article, I will be assembling the full Torso and Head using this system, documenting the cable management, and demonstrating full upper-body interaction.
Special Thanks: To the InMoov community and Gael Langevin for the inspiration, and to the Hackster community for the support on my previous projects!


_wzec989qrF.jpg?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)












_3u05Tpwasz.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)
Comments