I have a rotary encoder with 64 pulses per revolution and am trying to run it at a variety of speeds with a max of 10000 rpm. I think the Raspberry Pi can handle these rotation rates and pulses and I am using the pigpio rotary encoder library/module but I am not getting the right counter/speed readouts. I get the same number (around 8000) regardless of the speed I run the motor at. It seems as though the counter simply counts time instead of actual pulses and I cannot figure out why? I believe this might be because the counter is not updating every time it there is a pulse. Is there any way to use interrupts on the Raspberry pi so I can count every single encoder pulse?
Alternatively, would appreciate any ideas or solutions as to why the speed readouts are inaccurate.
Thanks so much!
Motor control and encoder reading code:
'''
import RPi.GPIO as GPIO
import time
import pigpio
import rotary_encoder
import wiringpi
#Pins for Motor Driver Inputs
Motor1A = 24 # header 18, wpi 5
Motor1B = 23 # header 16, wpi 4
Motor1E = 13 # header 33, wpi 23
encA, encB = 27, 22 # these are BCM pins, headers 13 and 15, wPi 2 and 3
last_pos, curr_pos = 0, 0
start = 0
LOOP_TIME = .1 # how often RPM is calculated
CPR = 64 # 64 pulses per revolution
G = 6.3 # gear ratio on the motor
pi = pigpio.pi()
def callback(way):
global curr_pos
curr_pos += way
def setup():
wiringpi.wiringPiSetupGpio() # this sets all the pin inputs to wPi mode (as opposed to BCM or headers)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)
wiringpi.pwmSetRange(500) # arbitrary max value
wiringpi.pwmSetClock(2)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) #GPIO Numbering
GPIO.setup(Motor1A,GPIO.OUT) #All pins 2as Outputs
GPIO.setup(Motor1B,GPIO.OUT)
wiringpi.pinMode(Motor1E, wiringpi.GPIO.PWM_OUTPUT)
global pi
def loop():
global start
global last_pos
global decoder
decoder = rotary_encoder.decoder(pi, encA, encB, callback)
# reading the encoder data and measuring RPM
dt, dpos = time.time() - start, curr_pos - last_pos
if dt > LOOP_TIME:
start, last_pos = time.time(), curr_pos
rpm = (dpos*60)/(G*CPR*dt)
print("RPM = {}".format(rpm))
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
wiringpi.pwmWrite(Motor1E, 480)
time.sleep(.005)
def stop():
wiringpi.pwmWrite(Motor1E, 0)
def destroy():
GPIO.cleanup()
if __name__=='__main__': # Program start from here
setup()
try:
while True:
loop()
except KeyboardInterrupt:
destroy()