2

So I have rpi wheeled robot, with wheel encoders and I want to always keep the track of the encoders and to be able to access the value when ever I need it.

Basically, I created a thread, which always keeps incrementing global variable on a change of encoder. There are 12 stripes on a wheel, I tested just on main and it works good, it kept track of all 12 and stopped at exactly the same point as it started. However, I need to be able to track both of them at the same time. With threads, its so slow, that it misses about 30% of High/Low and it is bad. However, with multiprocessing it kept track of both of them accurately, but I cant access the memory whenever I need.

def countRightEncoder():
global countRight
flag=0
while True:
    if encoderRight() == True and flag!=True:
        countRight+=1
        flag=True
    elif encoderRight() == False and flag!=False:
        countRight+=1
        flag=False
    print countRight

This loop will just always go, it wont stop and I just want to get the countRight value really often.

I was just wondering does anyone have any suggestions on how I could manage to do this without loosing any data? Maybe there is an easy way to get the value from multiprocessing?

Thank you

1
  • Perhaps part of the issue is that python is a bit hamstrung when it comes to multi-threading: toptal.com/python/… ("While this is much faster, it is worth mentioning that only one thread was executing at a time throughout this process due to the GIL.")
    – goldilocks
    Commented Mar 11, 2018 at 13:47

1 Answer 1

2

Perhaps try different software?

I've used (my) Python rotary encoder software to read multiple encoders.

If that doesn't work you will probably have to code your application in C.

If all you want to do is count pulses then just use a simple callback. The following code will set up a default callback on GPIO 2 and GPIO 19. The count (tally) of pulses is checked every second.

#!/usr/bin/env python

import time
import pigpio

pi = pigpio.pi()
if not pi.connected:
   exit()

cb1 = pi.callback(2)
cb2 = pi.callback(19)

stop_time = time.time() + 60

while time.time() < stop_time:
   print("cb1={} cb2={}".format(cb1.tally(), cb2.tally()))
   time.sleep(1)

cb1.cancel()
cb2.cancel()
pi.stop()
6
  • As I can see it was made for servo and with 2 inputs. How would you change the code just for 1 input? And I need this to be done continuously, should I just pop it in a thread and it should work or?
    – Dungy
    Commented Mar 11, 2018 at 14:42
  • Perhaps you are not using a rotary encoder? Although your description does suggest a rotary encoder is being used.
    – joan
    Commented Mar 11, 2018 at 16:20
  • Its for wheels. I have a IR sensor for black and white stripes which sends high if its white and low if its black
    – Dungy
    Commented Mar 11, 2018 at 16:33
  • If you have a spec for this it would be useful if you added a link. It would be an odd system which only gave a pulse without telling you the rotation direction.
    – joan
    Commented Mar 11, 2018 at 16:42
  • I dont need the direction, because it only goes forward. I just need to be able to always count the number of highs and lows, while the main is being executed. Threads sometimes just dont do anything at all for some time
    – Dungy
    Commented Mar 11, 2018 at 17:01

Your Answer

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

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