I want to implement an RS485 absolute encoder, values 0-2048, on a canvas rapid door. The controller MCU that reads the encoder, which I will programm, may not be powered all the time, but it should be aware of door position on power on. Limit switches will not be installed. The door's movement will never translate to more than 360 degrees revolution on the encoder. It is expected that maximum movement will have a span of around 1600 values.

The installer will set the lowest and highest positions during a setup procedure: Move the door to its lowest position, store the encoder value, move the door to its highest position, store the encoder value, setup completed.

The lowest position can translate to any value on the encoder due to the fact that the canvas is fitted on the roll bar without knowledge of encoder position. So it can have a lowest position at encoder value of 100 or 1000 or 2000. This means that in normal movement, the value will wrap around 2048. Moreover the installer can fit the motor on the left or right side of the roll bar, so the encoder value might increment while the door goes up, or vice versa. To complicate matters even more, the door might move further from the lowest position, due to break heating, gear oil temperature change etc, so if its lowest value was 50, it could wrap over zero and reach a bottom value of 1950.

Considering the above description and scenarios where lowest (Lxxx) and highest (Hxxx) position have corresponding value pairs of: L200-H1400, L800-H300, L10-H1500 and the reverse movement of those L1400-H200, L300-H800, L1500-H10.

What algorithm - conditions would you use to stop the motor at the lowest and highest positions?

  • \$\begingroup\$ I suggest that there exists an offset value that will make whatever you read extremely ambiguous. The approach sounds kind of bad to me. Much better to address this at assembly, and come up with a setup procedure that puts your encoder in range without rolling over. \$\endgroup\$ Aug 22, 2016 at 12:26

1 Answer 1


Variable list.

  • H: door high. (Stored in EEPROM.)
  • L: door low. (Stored in EEPROM.)
  • Z: zero offset. (Stored in EEPROM.)
  • TL: temp low.
  • TM: temp mid.
  • TH: temp high.
  • E: encoder reading.
  • P: position (corrected encoder reading).
  • D: direction (boolean). 0 = increasing count means up. 1 = decreasing count is up. (Stored in EEPROM.)

  • Move door to bottom. Press TEACH.
  • TL = E.
  • Move door to middle. Press TEACH.
  • TM = E.
  • Move door to top. Press TEACH.
  • TH = E.

enter image description here

Figure 1. There are four possible results from the teach procedure. (a) and (b) are clockwise for up. (c) and (d) are anti-clockwise for up. Note that (a) and (c) do not rollover the zero point whereas (b) and (d) do. (Diagram shows 2000 steps per revolution whereas encoder actually has 2048.)

Since you will have to store H and L values you can also store an Z (zero-offset) position.

if (TH > TL) {                          // it's (a) or (d)
  if ( (TM > TL) && (TM < TH) ) {       // it's (a)
    D = 0;                              // increasing count is up
  } else {                              // it's (d)
    D = 1;                              // increasing count is down
  Z = TH - 200;                         // Save to eeprom.
} else {                                // it's (b) or (c)
  if ( (TM > TH) && (TM < TL) ) {       // it's (c)
    D = 1;                              // increasing count is down
  } else {                              // it's (b)
    D = 0;                              // increasing count is up
  Z = TH - 200;                         // save to eeprom.

do {
  P = (E + 2048 - Z) MODULO 2048        // bring into range and avoid rollover.

The do loop will bring all readings into range 0 to 2047 with a comfortable 200 count safety margin at the top and bottom.

The rest is up to you!

  • \$\begingroup\$ I like this answer, as it solves my main struggle, the offset and encoder correction. If you notice, L always evaluates to 200, so H > L and D = 0 always. But I don't really mind that, I will measure the average speed filtering out any rollover and evaluate P accordingly. Thank you for the help! \$\endgroup\$
    – George P.
    Aug 22, 2016 at 13:08
  • \$\begingroup\$ See the major update. I hadn't covered all eventualities. The diagram may help straighten out your thinking. \$\endgroup\$
    – Transistor
    Aug 22, 2016 at 13:19
  • \$\begingroup\$ Whoa, that's some serious work you've done there. Great answer, and great explanation! \$\endgroup\$
    – George P.
    Aug 23, 2016 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.