NomadStep: Modular motor controllers

Control 2 x n motors through CAN over one UART channel

Similar projects worth following
Modular. Connect boards together to build more complicated systems. 1 board - differential drive robot, 2 boards - SCARA arm, 3 boards - 6 DOF arm.

Automatic. Boards automatically start communicating when they are linked up. At any one time, control of the entire series can be done by talking to one board. This simplifies wiring and control overheads

Precise. Control DC motors with closed PID feedback loops for position and velocity control.

Designed with the Tiva TM4C123 and the TB6612FNG motor driver. This makes the board transferable to other builds because it accepts a wide range of inputs for logic and power, and a wide range of motor types. API hooks will be written so that the board can be used without knowledge of the programming of the TIVA chip, allowing it to be used with other Raspberry Pi and Arduino boards.

Version 1 of the PCB is being made with OSHpark!

Version 2 of PCB complete!

Version 2 assembled!



With DC motors and encoders, it is possible get continuous rotation position/velocity control. This allows for very precise motion, for example, a differential drive robot will be able to drive straight, or a robot arm can return to the same position each time regardless of load.

However, there aren't many boards that do this control. By exposing the control loop, the parameters can be tuned to the specific application, allowing smooth motion and position with very little jitter. 

By having a CAN bus available on this board, it can talk to other similar boards and multiple motors can be linked up into a combined system just by connecting them together. 

This lowers the number of connections to a controlling system down to four connections: Power, ground, RX, and TX. This is advantageous for robots with multiple degrees of freedom, which can get quite bulky in terms of communication lines.

 Ideas for systems include differential drive robot (2), a SCARA arm robot (4) and a 6 DOF arm robot (6). 

While shopping around, I found that I really liked the Micro Metal Gearmotors from Pololu because of their form factor and the many different torque/speed configurations. One way to control these motors precisely is the use of magnetic encoders (which they also sell). With that, the precision you can get down to is theoretically up to the backlash of the gearbox, which is pretty precise for most applications since this is about a degree or so. With encoders, velocity control can be done, which allows for a high degree of precision for robotics.

So I happened on the TIVA TM4C123 from TI. Apart from its impressive specs as a Cortex M4 chip with FPU, it also boasts two hardware Quadrature Encoder Interfaces. Since this is implemented in hardware, the chip itself isn't being interrupted constantly and so is free to do other tasks. 

The nice thing is that this chip is also very capable as it is a Cortex M4, so it can do all the motion control for you while you implement a more complex control algorithm or processing intensive task like vision/mapping.  

You talk to it over communication channels such as UART, SPI, and CAN, or even an analog signal, so this board is good when paired with other boards such as the Raspberry Pi and nano Pi.


  1. Get version 1 prototype working with CAN bus, UART and SPI
  2. Demonstrate control for a robotic system
  3. Slim down version 1 prototype and produce version 2 prototype

Full code and schematics will be provided as this project progresses so that you can build your own boards.

Exported from ccs.

x-zip-compressed - 328.67 kB - 05/15/2018 at 20:58


sch - 415.57 kB - 04/21/2018 at 16:34


brd - 156.45 kB - 04/21/2018 at 16:34


  • PID Autotune controllers added

    Ben Lim05/15/2018 at 20:57 0 comments

    The code now includes generic PID controller functions that can be used for different purposes such as velocity and position tracking.

    And to use all these PID controllers, I added a PID autotuner based on the Nelder Mead algorithm that searches over a R3 space for the optimum coefficients to obtain the lowest rise time. These functions are included in the gen_algo.c file and should be applicable to other projects as well.

    I decided to reorganise the code this way so that it is portable to other projects. I was also got rather annoyed with having to write the same code over and over again in another project so this quickly became a priority. This reduces the code I have to rewrite and test and should result in increased productivity in the future since the code has already been written.

  • Progress!

    Ben Lim04/12/2018 at 13:44 0 comments

    Basic dynamic control over CAN bus complete, each board will discover and self-assign its position in a series. Currently you can only connect to a board at a end of a series for the dynamic addressing to work. An additional wire is required for this addressing. This increases the number of wires between boards to 5, POWER, CAN + 1 wire.

    UART has been tested with the Launchpad boards but not with a custom board because UART0 has not been broken out for some reason on the Launchpad.

  • Node assignment

    Ben Lim04/10/2018 at 22:29 0 comments

    One problem that this project faces is a dynamic assignment of nodes. However, there is no way to tell over the CAN bus which node is closer to the computer and how they are connected serially.

    One way would  be to do this in software where each board is set by the user, or using a jumper to select the node number. However, this detracts from the modular nature of the project.

    So I decided to add one more wire between boards to help tell how the boards are connected serially. A config protocol is written in the program so that each board will be able to tell the next how far they are from the controlling board.

  • Controller Version 1 assembled

    Ben Lim04/09/2018 at 15:43 0 comments

    When assembling version 1, I realised that I had made a few mistakes in the layout of the chip. I used a wrong header for the encoders, and I cannot just use any 16MHz crystal. There are some requirements, which rules out Abracon crystals. Reading the datasheet closer, it appears that that TI prefers CVX's crystals, so I will use that, even though they are slightly more expensive. I have also reduced the size of the decoupling capacitors. I have also added USER leds and a 3.3V regulator so that the board can be powered straight off the 12V supply, minimising the amount of supplies I have to add.

    Once I confirm the design the next batch will be sent off to be made.

    Currently a simple version of the CAN bus is working.

  • Controller version 1 received

    Ben Lim04/07/2018 at 04:17 0 comments

    Turns out that Sparkfun's M04 JSTPTH connector did not have 0.1" holes, which means that I couldn't connect the header that I already soldered onto the connector.

    Oh well, that's not such a big deal since some temporary measures can be put in place. I made the changes and for the time being will use some jumpers to connect the encoders to the board.

View all 5 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

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