lilzz
Posts: 411
Joined: Sat Nov 30, 2013 5:27 pm

modification to the rotary encoder code

Sun Jun 22, 2014 9:48 pm

Code: Select all

import RPi.GPIO as GPIO

class RotaryEncoder:

	CLOCKWISE=1
	ANTICLOCKWISE=2
	BUTTONDOWN=3
	BUTTONUP=4

	rotary_a = 0
	rotary_b = 0
	rotary_c = 0
	last_state = 0
	direction = 0

	# Initialise rotary encoder object
	def __init__(self,pinA,pinB,button,callback):
		self.pinA = pinA
		self.pinB = pinB
		self.button = button
		self.callback = callback

		GPIO.setmode(GPIO.BCM)
		
		# The following lines enable the internal pull-up resistors
		# on version 2 (latest) boards
		GPIO.setwarnings(False)
		GPIO.setup(self.pinA, GPIO.IN, pull_up_down=GPIO.PUD_UP)
		GPIO.setup(self.pinB, GPIO.IN, pull_up_down=GPIO.PUD_UP)
		GPIO.setup(self.button, GPIO.IN, pull_up_down=GPIO.PUD_UP)

		# For version 1 (old) boards comment out the above four lines
		# and un-comment the following 3 lines
		#GPIO.setup(self.pinA, GPIO.IN)
		#GPIO.setup(self.pinB, GPIO.IN)
		#GPIO.setup(self.button, GPIO.IN)

		# Add event detection to the GPIO inputs
		GPIO.add_event_detect(self.pinA, GPIO.FALLING, callback=self.switch_event)
		GPIO.add_event_detect(self.pinB, GPIO.FALLING, callback=self.switch_event)
		GPIO.add_event_detect(self.button, GPIO.BOTH, callback=self.button_event, bouncetime=200)
		return

	# Call back routine called by switch events
	def switch_event(self,switch):
		if GPIO.input(self.pinA):
			self.rotary_a = 1
		else:
			self.rotary_a = 0

		if GPIO.input(self.pinB):
			self.rotary_b = 1
		else:
			self.rotary_b = 0

		self.rotary_c = self.rotary_a ^ self.rotary_b
		new_state = self.rotary_a * 4 + self.rotary_b * 2 + self.rotary_c * 1
		delta = (new_state - self.last_state) % 4
		self.last_state = new_state
		event = 0

		if delta == 1:
			if self.direction == self.CLOCKWISE:
				# print "Clockwise"
				event = self.direction
			else:
				self.direction = self.CLOCKWISE
		elif delta == 3:
			if self.direction == self.ANTICLOCKWISE:
				# print "Anticlockwise"
				event = self.direction
			else:
				self.direction = self.ANTICLOCKWISE
		if event > 0:
			self.callback(event)
		return


	# Push button up event
	def button_event(self,button):
		if GPIO.input(button): 
			event = self.BUTTONUP 
		else:
			event = self.BUTTONDOWN 
		self.callback(event)
		return

	# Get a switch state
	def getSwitchState(self, switch):
		return  GPIO.input(switch)

# End of RotaryEncoder class
right now it can tell whether the encoder got rotate to clockwise or anti clockwise.
But how would I modify it so it can shows what sector the wheel is at. the encoder is in the middle and would rotate was the wheel rotate.

The wheel is 12 sectors. So based on the old A , old B, A , B have 16 combinations which can take care of 12 sectors.

ame
Posts: 3172
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: modification to the rotary encoder code

Sun Jun 22, 2014 11:01 pm

You can't.

Either you must start the wheel in a known place and keep track of the pulses,

or you must have another sensor to detect the 'home' or 'zero' position.

lilzz
Posts: 411
Joined: Sat Nov 30, 2013 5:27 pm

Re: modification to the rotary encoder code

Mon Jun 23, 2014 4:01 am

ame wrote:You can't.

Either you must start the wheel in a known place and keep track of the pulses,

or you must have another sensor to detect the 'home' or 'zero' position.

how about using a gray code encoder instead?

ame
Posts: 3172
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: modification to the rotary encoder code

Mon Jun 23, 2014 4:14 am

lilzz wrote:
ame wrote:You can't.

Either you must start the wheel in a known place and keep track of the pulses,

or you must have another sensor to detect the 'home' or 'zero' position.

how about using a gray code encoder instead?
Yes, that will work.

PiGraham
Posts: 3939
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: modification to the rotary encoder code

Mon Jun 23, 2014 8:37 am

lilzz wrote:
ame wrote:You can't.

Either you must start the wheel in a known place and keep track of the pulses,

or you must have another sensor to detect the 'home' or 'zero' position.

how about using a gray code encoder instead?
Technically you already have a grey code encoder, but it's incremental not absolute. It is also only two bits.

You have two options:
1. Use an incremental encoder with an index sensor to reset the position count once per rev.
2. Use an absolute encoder.

Is this literally a 'Wheel of fortune' type wheel?

As discussed before, you can make an absolute encoder on the wheel with markers and sensors. You could paint a grey code pattern on the wheel and use some photodiodes to read the position.

Return to “Python”