An absolute position encoder VHDL core

Fabien Le MentecNovember 11, 2015


Let's consider motorized systems controlled by electronics. A closed loop architecture looks like this:

Closed loop system

The following components are involved:

This article is available in PDF format for easy printing
  • the motor itself (DC, stepper ...),
  • the controller, in charge of computing position according to the whole system state,
  • the driver board in charge of generating signals and power for the motor,
  • the position encoder, the subject of this post.

Most of the time, there is a difference between the position the system has to reach (the setpoint) and the current position. Moving to a particular point does not occur instantly due to inertia, obstacles, failures ... Thus, the controller needs a way to know the current position. This is the role of position encoders.

A position encoder transmits information that allow the controller to infer the current position. From that, it can take further decisions: regulate the motion, alert an operator ...

While initially designed for it, motor positions are not the only type of data handled by position encoders. In fact, any type of value can be sent. For instance, the output of sensors that may be used in the regulation loop, such as a chamber temperature or pressure, a fluid level ...

There are different technologies to encode position. Then, are different methods to send the position information. First, the transmitted signal can be either analog or digital. In the digital domain, there are also 2 fundamentally different information that can be sent: position difference or absolute value.

Position difference encoders

Difference encoding involves sending the difference between 2 positions. By cumulating this information, the controller knows the current position. For instance, quadrature encoding is often found in hobby robotics. It uses 2 out of phase signals that encode a step and a direction. Some microcontrollers have quadrature encoding hardware modules built in (DSPIC33F), but you can also implement it quite efficiently in software (TEENSY).

While quadrature encoding is attractive, there are drawbacks to this approach:

  • if your system loses power, the absolute position is lost since you start counting back from 0. You can solve this by storing the position, but it involves writing to an additional memory 'regularly enough', which has its own shortcomings. If the system supports it, another solution is to do homing, which is finding a position considered as 0,
  • since one pulse encodes a '+/-1' increment, the time it takes to send a value is not constant but proportional to the position difference. The greater the difference, the longer the transmission time. This time can be reduced by increasing the frequency, but there are limiting factors such as cable length, electronics maximum sampling frequency ...,
  • missing a single pulse results in an incorrect positions. With time, it can result in a large error due to accumulation.

Depending on your system, these drawbacks may not apply and quadrature coding may do the job. But position encoders exist that send absolute positions.

Absolute position encoders

There is not a single standard for absolute position encoders. Instead, there are multiple and somewhat redundant interfaces. They differ in the mechanics (packaging, connector ...), electronics (frequency, signal electrical specifications ...), protocol (framing ...), and openness.

To further reduce the scope, we focus on synchronous serial encoders. In these, a master (the controller) drives a clock that is used to synchronize transmission with a slave (the encoder) over a single data line. Note that some interfaces allow for single master multiple slaves topologies, but we are only interested in point to point configurations.

In this category, there are at least 3 possible interfaces:

  • ENDAT, a proprietary interface developed by Heidenhain. It is very rich in that the standard allows for cable length delay compensation, transmission error checking, auxiliary data transmission ... It is also complex to implement fully,
  • BISS, an open specification that offers features similar to that of ENDAT,
  • SSI, an interface simpler than the 2 above. Since it is less clearly specified, it is possible that 2 SSI implementations cannot communicate together (data encoding, framing ...).

An absolute position encoder VHDL core

I work at the ESRF synchrotron facility where motorization control is critical for various components of the machine  itself, and for the instruments used in experiments on beamlines.

For that, we develop our own devices or integrate proprietary ones. More and more, absolute position encoders appear somewhere in the system. From a firmware development point of view, we are currently in a situation where multiple redundant and independently maintained implementations exist to interface absolute position encoders. This is not efficient as people spend time redoing what others did, and individual implementations do not benefit from the 'on the field' experience of each others. Thus, and due to a new instrument being developed, I recently started an effort to implement a unique VHDL core addressing absolute position encoder interfaces.

First, I reviewed existing instruments in use or being developed. It is important to consider their specific requirements, for instance the supported encoder interface, their role (master or slave), the target platform (some runs on Xilinx Spartan2 FPGAs ...).

Then, I looked for details in current implementations. For instance, some implement special timeouts or framing extension as workaround for particular devices.

Finally, it was important to consider the projects to come, so the implementation was designed to be extensible.

This work resulted in a VHDL core dubbed absenc. It features both ENDAT, BISS and SSI interface. Due to its architecture, new interfaces are easily added. Also, the 3 interfaces can be enabled at synthesis while 1 is selected at runtime. As much as possible, resources common to the different interfaces are shared (counters, comparators...). It supports both master (ie. controller) and slave (ie. encoder) roles.

Now for some examples. The first one is an ADC to SSI converter:

The other one is a configurable encoder to encoder converter:

Due to my work environment, it made sense for me to put the project on the CERN OHWR repository . I also mirror the project contents on my personal repository.

For me, sharing this project is a good way to get feedbacks, especially regarding usage with hardware I do not have access to. So if you use it, have contribution, see missing features or have bug fix requests, please let me know !

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: