Amit2001
Posts: 2
Joined: Sat Dec 08, 2018 2:32 pm

Help - Incorrect reading of magnetic encoder

Sat Dec 08, 2018 2:54 pm

Hi everyone, I am a beginner having trouble to read a magnetic encoder. I have found the following code I found that I am using in order to read the encoder values:

Code: Select all

#!/usr/bin/env python

import pigpio

class decoder:

   """Class to decode mechanical rotary encoder pulses."""

   def __init__(self, pi, gpioA, gpioB, callback):

      """
      Instantiate the class with the pi and gpios connected to
      rotary encoder contacts A and B.  The common contact
      should be connected to ground.  The callback is
      called when the rotary encoder is turned.  It takes
      one parameter which is +1 for clockwise and -1 for
      counterclockwise.

      EXAMPLE

      import time
      import pigpio

      import rotary_encoder

      pos = 0

      def callback(way):

         global pos

         pos += way

         print("pos={}".format(pos))

      pi = pigpio.pi()

      decoder = rotary_encoder.decoder(pi, 7, 8, callback)

      time.sleep(300)

      decoder.cancel()

      pi.stop()

      """

      self.pi = pi
      self.gpioA = gpioA
      self.gpioB = gpioB
      self.callback = callback

      self.levA = 0
      self.levB = 0

      self.lastGpio = None

      self.pi.set_mode(gpioA, pigpio.INPUT)
      self.pi.set_mode(gpioB, pigpio.INPUT)

      self.pi.set_pull_up_down(gpioA, pigpio.PUD_UP)
      self.pi.set_pull_up_down(gpioB, pigpio.PUD_UP)

      self.cbA = self.pi.callback(gpioA, pigpio.EITHER_EDGE, self._pulse)
      self.cbB = self.pi.callback(gpioB, pigpio.EITHER_EDGE, self._pulse)

   def _pulse(self, gpio, level, tick):

      """
      Decode the rotary encoder pulse.

                   +---------+         +---------+      0
                   |         |         |         |
         A         |         |         |         |
                   |         |         |         |
         +---------+         +---------+         +----- 1

             +---------+         +---------+            0
             |         |         |         |
         B   |         |         |         |
             |         |         |         |
         ----+         +---------+         +---------+  1
      """

      if gpio == self.gpioA:
         self.levA = level
      else:
         self.levB = level;

      if gpio != self.lastGpio: # debounce
         self.lastGpio = gpio

         if   gpio == self.gpioA and level == 1:
            if self.levB == 1:
               self.callback(1)
         elif gpio == self.gpioB and level == 1:
            if self.levA == 1:
               self.callback(-1)

   def cancel(self):

      """
      Cancel the rotary encoder decoder.
      """

      self.cbA.cancel()
      self.cbB.cancel()

if __name__ == "__main__":

   import time
   import pigpio

   import rotary_encoder

   pos = 0

   def callback(way):

      global pos

      pos += way

      print("pos={}".format(pos))

   pi = pigpio.pi()

   decoder = rotary_encoder.decoder(pi, 7, 8, callback)

   time.sleep(300)

   decoder.cancel()

   pi.stop()

However when I run this code I do get pos values but they are incorrect the encoders I am using are:
encoders: https://www.pololu.com/product/3081
motors: https://didacticaselectronicas.com/inde ... aft-detail

I am aware to the fact this is a quiet high rpm motor, but I get readings of about 1000 per one revolution of the wheel when I should get (if my calculations are correct) 12 * 298. I tried using lower speeds of rotation, and also to print the reading only once at the end of the run but it is still much lower reading values than expected. Any ideas on how can I fix it or where I am wrong?

User avatar
przemof
Posts: 161
Joined: Mon Dec 30, 2013 6:43 pm

Re: Help - Incorrect reading of magnetic encoder

Sat Dec 08, 2018 8:40 pm

I'd start with fixing the code: you have class decoder and variable decoder. On top of that you don't use that class? Try flake8, autopep8, pylint to check your code. You wrote the code?

Amit2001
Posts: 2
Joined: Sat Dec 08, 2018 2:32 pm

Re: Help - Incorrect reading of magnetic encoder

Sat Dec 08, 2018 11:24 pm

przemof wrote:
Sat Dec 08, 2018 8:40 pm
I'd start with fixing the code: you have class decoder and variable decoder. On top of that you don't use that class? Try flake8, autopep8, pylint to check your code. You wrote the code?
I did not write the code I found it online after looking for code to read an encoder. The code works ok, I do not get any errors while running it and In addition I do use the class in the main program. I tried changing the variable decoder but it is still the same. I get values but they are incorrect. The code is taken from here http://abyz.me.uk/rpi/pigpio/examples.h ... hon%20code

User avatar
przemof
Posts: 161
Joined: Mon Dec 30, 2013 6:43 pm

Re: Help - Incorrect reading of magnetic encoder

Sun Dec 09, 2018 10:06 am

If you're sure the code is OK then the hardware is not OK - i can't help with that.
You use the class decoder in some other part of the program? If you use that class in the code you posted, could you point me to that part?
You have name redefinition from class to variable. No errors doesn't meant that the code is OK.
Last edited by przemof on Sun Dec 09, 2018 10:13 am, edited 1 time in total.

User avatar
przemof
Posts: 161
Joined: Mon Dec 30, 2013 6:43 pm

Re: Help - Incorrect reading of magnetic encoder

Sun Dec 09, 2018 10:13 am

Also, can you try to read the output diirectly and check that the encoder works as expected? Just print out the gpios and turn the encoder slowly
Last edited by przemof on Sun Dec 09, 2018 10:25 am, edited 1 time in total.

User avatar
joan
Posts: 14074
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Help - Incorrect reading of magnetic encoder

Sun Dec 09, 2018 10:16 am

I wrote that code. As long as it wasn't altered it works just fine.

Python has namespaces. decoder is not the same as rotary_encoder.decoder.

Once instantiated the class is triggered by events on GPIO 7/8 for 5 minutes (notice the sleep).

Code: Select all

   decoder = rotary_encoder.decoder(pi, 7, 8, callback)

   time.sleep(300)

   decoder.cancel()

User avatar
przemof
Posts: 161
Joined: Mon Dec 30, 2013 6:43 pm

Re: Help - Incorrect reading of magnetic encoder

Sun Dec 09, 2018 10:23 am

:D Great! It's PEP8/F811 error. The code might work, I'm not saying it's a hard error.

What's under the import rotary_encoder? I can't find any code and it's not a standard library. And where you use that decoder class? There is some external rotary_encoder module?


User avatar
przemof
Posts: 161
Joined: Mon Dec 30, 2013 6:43 pm

Re: Help - Incorrect reading of magnetic encoder

Sun Dec 09, 2018 12:49 pm

Thanks! Now I understand what you've done: there is rotary_encoder.py python file (the code OP posted), providing "decoder" class that is redefined in the __main__ section to "decoder" variable. Also in the rotary_encoder.py you use import rotary_encoder! That's why I thought there is some external module named rotary_encoder! :twisted: :twisted: :twisted:

Side note: broken link in Hardware section: Rotary Encoder 2013-06-09

Return to “General discussion”