LibreServo is a project with the goal of easily converting any standard size servo into the smartest servo possible.

Similar projects worth following
In the past (more than 10 years ago), I bought more than 20 5990TG servomotors from Hitec to build my second biped robot. They were expensive, with good hardware but still as dumb as the cheapest servo.
Years have passed and I always had a thorn in my side. Why not instead of dumb servos with excellent mechanics modify them to have clever servos with excellent mechanics? And, since we are going to design something new... why not make it in such a way that they would be compatible with future servos that I may buy?
The idea is to design the electronics of the servomotor to turn any standard servo into the smartest one in the world.
Text extracted from:

This project was born as a necessity of mine to build a biped robot with intelligent servos to be able to “feel the muscles” to walk more human like. In the past we had OpenServo, and I think this project inherits something from it, but OpenServo died many years ago and it didn't reach my expectations anyway (power, communications...), and the commercial alternatives are way too expensive (Dynamixel, Herkulex, Lynxmotion...).


It’s not hard to find servo motors with about 25-30 kg/cm of torque nowadays with quality ok, not great but ok for less than 20-25€ each although now everything has increase their price, and with that power from one of the well-known companies a smart servo costs more than 120-150€ easily, so we have room to play with. We can use cheap servo motors, just the hardware, with the coolest servo controller I can design for under 40€ everything.

5990TG disassembled
5990TG disassembled
Chinese servomotors I have bought
Chinese servomotors I have bought

My goal with LibreServo is to make any standard servo the “smartest” one in the market. The "gold standard" nowadays is Robotis-Dynamixel, LibreServo should be better than that, that’s my goal at least.
A few characteristics of LibreServo:

  • Compatible with standard servo motors (No need to change the bottom cover of them!)
  • Voltage: From 4.5V up to 18V (Recommended: 5-13V)
  • Communications: RS-485 half-duplex. Max Speed 9Mbps. Daisy chained. CRC-16
  • Amp: Up to 7A continuous (FDS8858CZ || VBA5311)
  • Micro-Controller: STM32F301k8 (cortex-M4@72MHz)
  • Position sensor: Magnetic encoder, 16 bits of resolution! 360 degrees (AEAT-8800). Using the servo motor potentiometer will be possible to lower the cost but will lost precision and some characteristics.
  • For the encoder I have designed 3D parts to substitute the potentiometer and used the same hole/space than the original.
  • LibreServo will generate their own curves (sine ramps, trapezoidal ramps, hermitian curves...)
  • Current sensor: +-15A ACS711
3D potentiometer-encoder adapter
3D potentiometer-encoder adapter

I have tried to use good hardware, better than the commercial ones, and then, in the software side, I will try to really shine against the competence, communication protocol, huge flexibility, different motor curves...

The project started 3 years ago, it has been progressing slowly because my lack of time but it will finish 100% sure even if it takes me 3 more years. I have been documenting my slow progress in the web/blog of LibreServo  (partially translated). I have finished the third version of LibreServo, with every component tested and selected. I have changed lots of components from the first designs and also the final form factor.

Old LibreServo v1
Old LibreServo v1
Old LibreServo v1
Old LibreServo v1
Newest LibreServo v2
Newest LibreServo v2
Newest LibreServo v2
Newest LibreServo v2
Just to understand better the final result
Just to understand better the final result

**There will be versions with only one connector on one side or the other.

The following video is from the second version of the PCB test.

Creative Commons License

  • 1 × STM32F301k8 Microcontroller
  • 1 × SIT3485EUA RS485
  • 1 × MPM3610 DC-DC
  • 1 × AP2112 Power Management ICs / Linear Voltage Regulators and LDOs @3V3
  • 2 × FAN3227/3 Mosfet Driver

View all 10 components

  • LibreServo v2 Schematics

    Luis06/18/2022 at 16:38 0 comments

    The schematics are exactly the same with which I made the LibreServo v2 PCBs but with the texts corrected in position so they read better.

    In previous posts as you can read in the article of the first LibreServo test board and in the conclusions of the second LibreServo test-board, the LibreServo changes were massive in each and every aspect. Virtually every component was overhauled and moved to a two PCB, four-layer design.

    The result is as seen below, in addition, I have uploaded the design files to the LibreServo Github in the PCB folder.

    An interactive version of the photos is available on the LibreServo website.

    LibreServo v2 Schematic
    LibreServo v2 Schematic
    Top & Bottom
    Top & Bottom
    Middle Bottom
    Middle Bottom
    Middle Top
    Middle Top

  • New version of the 3D encoder parts

    Luis06/12/2022 at 22:30 0 comments

    To know the position of the servomotor axis, LibreServo uses the AEAT-8800 16-bit encoder. This encoder replaces the potentiometer that the servomotors have and with it we get much more precision and allows the servomotor to rotate 360 degrees.

    To achieve this, LibreServo makes use of a tiny 10.2x11.2 mm PCB to which a 3D printed part of the same size and shape as the original potentiometer is attached. This 3D printed part consists of 3 small parts, a 4x7x2mm bearing and a small 6x2.5mm diametrically magnetized magnet. Only a glue point is needed to fix the magnet. The rest of the parts, bearing and PCB are designed to be snap-fitted and fixed.

    With the first release of the LibreServo software, the 3D parts have also been updated. The .stl is uploaded to the Libreservo github in the 3D folder. The parts are designed to be printed with 0.1mm layers.

    LibreServo encoder assembly video

  • LibreServo commands (part two)

    Luis06/06/2022 at 06:23 0 comments

    I have spent a lot of time on the command part of LibreServo and I think it is one of the most important parts of the project, it is how LibreServo is presented to the user. It offers a flexibility and possibilities that I have never seen in any manufacturer.

    The documentation of the commands will be divided into two articles, this article is more focused on examples and explanation of execution and the other article is focused on the description of LibreServo commands.

    LibreServo has a task manager for the high-priority engine management part and a separate low-priority task manager for sending data to the user only (commands GX). This must be taken into account since the order and timing will be independent between the commands to receive data and the rest of the commands.

    All commands start with the character 'S' and at least one servomotor number and end with ';'. Commands can be chained with the character '|' so that all commands are treated together as a block.

    This article will be divided into the following topics:

    Servomotor Selection

    All commands start with the character 'S' followed by at least one servomotor ID. The ID of a servo motor ranges from 1 to 255 (default is 1). LibreServo allows sending the same command to different servomotors at the same time. The '-' character indicates a range and the ',' character indicates independent servomotor IDs. For example, the commandS1,3,4,10-20M1000; means that servomotors with ID 1, 3, 4 and all with ID between 10 and 20 (both included) should move to position 1000. In addition, ID 0 is reserved (it is for broadcast) and any command sent to ID 0 will be like sending the command to all servomotors regardless of their actual ID.

    S5MW500|S0M12000:1000; All servomotors will move to position 12000 in 1000 milliseconds, but servomotor 5 after a 500ms delay.
    S2,5,10-14,6M2000:500; Servomotors 2, 5, 6, 10, 11, 12, 13 and 14 will move to position 2000 in 500 milliseconds

    Command chaining

    As we have seen, all commands start with the character 'S' and at least one servomotor number and end with ';'. You can chain commands with the '|' character so that all commands are treated together as a block. This is very useful for many reasons, one of the main ones being that until LibreServo sees the ';' character it doesn't start executing, so if you want different servomotors to execute different commands but want to make sure they all start moving at the same time, sending all the commands in one command is the way to make sure they start at the same time. Also, it is useful to send the variable reading commands along with the rest of the commands.

    S1L255:0:0|S1T1567:300:100|S1T1567:10:0|S1T1567:300:100; Chain a series of Tone and LED commands, it can be the start of a song
    S2M1000:500|S3M2000:1000|S2M500:500; Servomotor 2 will move to 1000 in 500ms and then to 500 in 500ms while servomotor 3 moves to 2000 in 1000ms
    S2M1000:500|S2Gs13,11:500:1; Servomotor 2 will move at 1000 in 500ms and will report every millisecond its position and current consumption for viewing on the Serial Plotter of the Arduino, for example

    Immediate commands [ ! ]

    Another unique feature of LibreServo is immediate or priority commands. A command can be sent as immediate with the '!' character before ';' or '|'. To take effect, it must be the first command for that servo motor that is sent, if it is sent with more chained commands, the one that is marked as immediate. An immediate command causes the execution of the command being executed to be aborted and clears all other commands in the task manager. An immediate command from the variable reading group (GX) does not affect the other commands as it is in a separate task manager, the same as the other immediate commands does not affect the...

    Read more »

  • LibreServo commands (part one)

    Luis06/05/2022 at 17:52 0 comments

    I have spent a lot of time on the command part of LibreServo and I think it is one of the most important parts of the project, it is how LibreServo is presented to the user. It offers a flexibility and possibilities that I have never seen in any manufacturer.

    The documentation of the commands I will divide it in two articles, this article is more focused on the description of the commands and the second part is focused on examples and explanation of execution in LibreServo.

    The LibreServo commands are as follows:

    Motion commands

    These are specific commands for the movement and control of the servomotor. The different motions and their curves are explained in more detail in the article on motion curves.

    Linear motion [M]

    • S12M12000[:1000]

    The notation we see for 12000[:1000] indicates that the M command forces one parameter to be passed, but the second parameter is optional. It also tells us that the ':' character is used to separate the parameters. This notation is used for all other commands.

    Returning to the command, the M command is a command in which the servomotor moves at constant speed to the end position.

    param1: the first parameter indicates the position we want to go to (a 360 degree turn is 65,535). Range: -2.147.483.646, +2.147.483.647
    param2 (optional): the second parameter indicates in milliseconds, ms, the time in which the movement should be completed, if no time is indicated LibreServo will try to arrive as soon as possible. Range: 0, +2.147.483.647
    S12M12000:1000; Servomotor 12 shall move to position 12000 in 1000 ms (1 second).

    Trapezoidal motion [MT]

    • S12MT12000[:150]:1000;

    The MT command is a constant acceleration and deceleration motion calculated based on a fixed acceleration duration.

    param1: final position. Range: -2.147.483.646, +2.147.483.647
    param2 (opcional): acceleration and deceleration time in ms. If not specified, the default value stored in flash (t_ramp_t) is taken. If the acceleration and deceleration time is greater than the total movement time, they are reduced to fit into the total movement time. Range: 0, +2.147.483.647
    param3: total movement time. Range: 0, +2.147.483.647
    S12MT-8000:1000; Servomotor 12 shall move to position -8000 in 1000ms. The ramp time shall be the one that is at t_ramp_t
    S12MT-8000:150:1000; Servomotor 12 shall move to position -8000 in 1000ms. The ramp time shall be 150ms

    Trapezoidal motion 50% [Mt]

    • S12Mt12000:1000;

    It is the same as MT, but the acceleration time will be half of the total movement time and the deceleration time the other half.

    param1: final position. Range: -2.147.483.646, +2.147.483.647
    param2: total movement time. Range: 0, +2.147.483.647
    S12MT-8000:1000; Servomotor 12 shall move to position -8000 in 1000ms. The ramp time shall be 500ms (500*2 = 1000)

    Accelerated trapezoidal motion [MA]

    • S12MA12000[:150]:1000;

    It is a trapezoidal movement, but instead of indicating the acceleration time, you indicate the desired acceleration and LibreServo calculates the required acceleration and deceleration time.

    param1: final position. Range: -2.147.483.646, +2.147.483.647
    param2 (opcional): Aceleración y desaceleración de la rampa. If not specified, the default value stored in flash...
    Read more »

  • Updated LibreServo software (version v0.1)

    Luis06/05/2022 at 09:38 0 comments

    After several months of work, LibreServo has finally reached version 0.1 in the software. What does this mean? It means that LibreServo is still in Beta version, but it is mature enough to present itself in society. This will be only the first of several entries that I will be uploading these days.

    I have updated the Github of LibreServo with the latest files and I will try to keep it updated.

    In the next few days I will upload the documentation of LibreServo commands, but in case anyone wants to read the code itself, I have made two small diagrams to help understand how LibreServo works.

  • Last steps for first official release

    Luis06/04/2022 at 21:13 0 comments

    Although I had many parts of the code already done, the truth is that putting all the code together and making all the functions and internal structure non-blocking has been a much more laborious task than expected. In addition, I have programmed dozens of commands and the first version of the LibreServo Software is much more complete than I had originally anticipated.

    In the following posts I will detail a little more the functions and operation of LibreServo, for now I leave a curious little video I made with the LibreServo test board v2 a few weeks ago as a small preview testing the sound function of LibreServo. Yes, LibreServo is able to generate sound making use of the DC motor.

    LibreServo allows you to send blocks of commands making it much easier to send dozens of commands at once. LibreServo takes care of storing them and executing them one after another. This simple test was not really about generating music, but about seeing that the whole internal LibreServo system worked. 

    The commands used are as follows.

    /*****IMPERIAL MARCH*****/
    /******MAIN THEME******/
    /*******Still D.R.E.*******/
    Read more »

  • Motion curves

    Luis11/15/2021 at 22:49 0 comments

    A servo motor is a motor that maintains a given position, but how does it get to that position?

    A normal servomotor only receives the final position by PWM and always goes as fast as it can to that point. A smart servo motor, on the other hand, usually receives a command that tells it the end position and how fast it has to reach that position, at which point the smart servo motor starts to calculate the path to the end position. There are several ways to trace the route, those are the motion curves.


    It is the most basic, the space is divided by the time you have and a constant velocity is calculated. The problem is that it proposes an almost infinite initial and final acceleration. This kick of acceleration causes great mechanical wear in motor and gears and strong vibrations by the accelerations.

    In the following picture it can be clearly seen, left axis corresponds to position and acceleration, while the right axis is velocity:

     Linear curve graph. Position, acceleration and velocity
    Linear curve graph. Position, acceleration and velocity


    To reduce the acceleration kick, a profile with a constant maximum acceleration is created. This generates an initial acceleration ramp, a constant velocity section and a final deceleration section. This is the only motion curve with the above that manufacturers offer. The problem with it is that it still generates vibrations from abrupt changes in acceleration. It is smoother than the previous profile, but it still has vibrations.

    Trapezoidal curve graph. Position, acceleration and velocity
    Trapezoidal curve graph. Position, acceleration and velocity


    This motion curve is not offered by manufacturers, but is offered by LibreServo. This motion curve is intended to completely eliminate any acceleration kick. This motion curve is specific to make a clean acceleration transition without jumps as seen in the graphs.

    S-curve graph. Position, acceleration and velocity
    S-curve graph. Position, acceleration and velocity


    This motion curve is again unique to LibreServo. All other curves presuppose starting from a standstill and ending at a standstill, this is the only curve that allows to start and end the movement starting or ending at a given velocity. This is indispensable in situations where we want to end a movement or modify it in the middle of a run, for example, if we detect a possible fall, a possible error or some danger. In addition, it is perfect for passing through different marked points at different speeds, LibreServo will take care of executing the curve. This curve continues a movement, but not the acceleration it already had, so it can generate vibrations.

    In the following picture we see two different paths. In both we start from 0, go through 100, through -50 and back to zero, but in the first path the velocity at each point is always indicated to be zero, while in the second path at the intermediate points the velocity will be 4.

    Hermitic curve graph. Comparison of position and velocity
    Hermitic curve graph. Comparison of position and velocity

    Text extracted from:

View all 7 project logs

Enjoy this project?



Daniel Collins wrote 07/16/2022 at 07:11 point

Hi Luis, just wanted to say great work on this project, it looks excellent. Can I ask some dumb questions to understand how applicable this project is for my applications? a) is LibreServo suitable for continuous rotation servos? b) Regarding communicatoin speed, what is a realistic top speed for LibreServo commands per second? c) how many commands can be buffered in the on-board memory? d) Will the PID parameters of the controller be accessible via commands? Many thanks

  Are you sure? yes | no

Luis wrote 07/16/2022 at 19:14 point

Hello Daniel,

No question is dumb question.

Yes LibreServo is suitable for continuous rotation servos, it has many commands for that matter (as you can see in the log) and use a magnetic encoder for that reason (among others).

commands per second? LibreServo has a limitation of 1 thousand movement commands per second that can execute by himself because the main loop runs at 1KHz, BUT, as is daisy chained, it can "read" more than that (commands for other servos).

Now, I put a limit of 100 commands (, but is just a number in the code, can be easily change it (is just a variable).

Yes, PID parameters and MUCH more!! You can check the commands in the logs of the project:

The project is not finished, so just wait a little bit please :)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates