[Dprglist] Encoder decoding, 2nd attempt

Murray Altheim murray18 at altheim.com
Tue Feb 9 23:00:21 PST 2021


On 10/02/21 6:28 pm, David Anderson via DPRGlist wrote:
> I realized my previous post doesn't make much sense without the context.
>  So here is maybe a better attempt at context.
> 
> This is derived from an email exchange with Murray and Dave Ackley.
>  It concerns decoding quadrature encoder signals. [...]
Hi David,

To answer your question, I think that my Decoder class does basically
the same thing. I have an instance of a Motor class for my port and
starboard motors, and each Motor creates its own Decoder instance,
which in its init() declares two pigpio callbacks to an internal _pulse()
function to react to trigger pulses on the GPIO pins for A and B, then
checking the logic of the other channel before incrementing or
decrementing the step counters in each Motor by calling the Motor's
callback, which was supplied as an argument on the Decoder.

There's no explicit XOR in the code but I believe it operates the same
way as you and Dave describe, certainly seems to in practice. Here's the
relevant snippet from the Decoder class:

  class Decoder(object):
      def __init__(self, pi, orientation, gpio_a, gpio_b, callback, level):
          # ...
          self.cbA = self._pi.callback(self._gpio_a, _edge, self._pulse_a)
          self.cbB = self._pi.callback(self._gpio_b, _edge, self._pulse_b)

      def _pulse_a(self, gpio, level, tick):
          self._level_a = level
          if level == 1 and self._level_b == 1:
              self.callback(1)

      def _pulse_b(self, gpio, level, tick):
          self._level_b = level;
          if level == 1 and self._level_a == 1:
              self.callback(-1)

      def _pulse(self, gpio, level, tick):
          if gpio == self._gpio_a:
             self._level_a = level
          else:
             self._level_b = level;
          if gpio != self._last_gpio: # debounce
             self._last_gpio = gpio
             if gpio == self._gpio_a and level == 1:
                if self._level_b == 1:
                   self.callback(1)
             elif gpio == self._gpio_b and level == 1:
                if self._level_a == 1:
                   self.callback(-1)

source:   https://github.com/ifurusato/ros/blob/master/lib/decoder.py

I *may* be getting half as many triggers as Dave but I don't believe that's
the case, only because while fiddling around with the code over the past
year I think the only change I've ever made was to halve the count, never
double it. I'm getting 494 steps per motor revolution and that's a pretty
good constant.

Cheers,

Murray

...........................................................................
Murray Altheim <murray18 at altheim dot com>                       = =  ===
http://www.altheim.com/murray/                                     ===  ===
                                                                    = =  ===
     In the evening
     The rice leaves in the garden
     Rustle in the autumn wind
     That blows through my reed hut.
            -- Minamoto no Tsunenobu



More information about the DPRGlist mailing list