1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| import RPi.GPIO as GPIO
# setup GPIO options...
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
# Audio generate import
import math
import struct
import pyaudio
//import sonpy
class RotaryEnc:
'Base Class for Rotary Encoder on the RPi GPIO Pins'
def __init__(self,PinA,PinB,button,Position,REmin,REmax,inc):
self.PinA = PinA # GPIO Pin for encoder PinA
self.PinB = PinB # GPIO Pin for encoder PinB
self.button = button # GPIO Pin for encoder push button
self.Position = Position # encoder 'position'
self.min = REmin # Max value
self.max = REmax # Min value
self.inc = inc # increment
self.old_button = 1 # start value for previous button state
self.oldPinA = 1 # start value for previous PinA state
self.button_release = 0 # initialise outputs
self.button_down = 0 # initialise outputs
GPIO.setup(self.PinA, GPIO.IN) # setup IO bits...
GPIO.setup(self.PinB, GPIO.IN) #
GPIO.setup(self.button, GPIO.IN) #
#
def read(self): # Function to Read encoder...
encoderPinA=GPIO.input(self.PinA) # get inputs...
encoderPinB=GPIO.input(self.PinB) #
if encoderPinA and not self.oldPinA: # Transition on PinA?
if not encoderPinB: # Yes: is PinB High?
self.Position=self.Position+self.inc # No - so we're going clockwise
if self.Position > self.max: # limit maximum value
self.Position = self.max #
#
else: #
#
self.Position=self.Position-self.inc # Yes - so we're going anti-clockwise
if self.Position < self.min: # limit minimum value
self.Position = self.min #
self.oldPinA=encoderPinA # No: just save current PinA state for next time
#
def read_button(self): # Function to Read encoder button...
button=GPIO.input(self.button) # get input...
if button and not self.old_button: # 'Upward' transition on button?
self.button_release=1 # Yes - so set release output
else: #
self.button_release=0 # No - so clear it
if not button and self.old_button: # 'Downward' transition on button?
self.button_down = 1 # Yes - so set 'down' button
else: #
self.button_down = 0 # No - so clear it
self.old_button=button # Save current button state for next time
def play_tone(frequency, amplitude, duration, fs, stream):
N = int(fs / frequency)
T = int(frequency * duration) # repeat for T cycles
dt = 1.0 / fs
# 1 cycle
tone = (amplitude * math.sin(2 * math.pi * frequency * n * dt)
for n in xrange(N))
# todo: get the format from the stream; this assumes Float32
data = ''.join(struct.pack('f', samp) for samp in tone)
for n in xrange(T):
stream.write(data)
fs = 4400
p = pyaudio.PyAudio()
stream = p.open(
format=pyaudio.paFloat32,
channels=1,
rate=fs,
output=True)
# -------------------------------------------------------------------------------------------------------------------
# Here's a simple example of how to use the RotaryEnc Class ...
#
# Set up Rotary Encoder...
# format is : RotaryEnc(PinA,PinB,button,Position,REmin,REmax,inc):
Position = 1 # Position is also used as a variable
RE1 = RotaryEnc(12,16,18,Position,0,10,1) # Instatiate the encoder
# Main Operating Loop...
while True:
RE1.read() # Read the encoder
if Position <> RE1.Position: # has the position changed?
print RE1.Position # Yes: so print new value
Position = RE1.Position # and update it
play_tone(RE1.Position, 0.5, 0.75, fs, stream)
RE1.read_button() # Read the button
if RE1.button_down: # Has it been pressed?
print 'Button Pressed' # Yes: so print a message
if RE1.button_release: # Has it been released
print 'Button Released' # Yes: so print a messa
stream.close()
p.terminate() |
Partager