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

  • 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 Mar 11 '18 at 13:47
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()
| improve this answer | |
  • 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 Mar 11 '18 at 14:42
  • Perhaps you are not using a rotary encoder? Although your description does suggest a rotary encoder is being used. – joan Mar 11 '18 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 Mar 11 '18 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 Mar 11 '18 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 Mar 11 '18 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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