Skip to content

Commit 696c949

Browse files
authored
Merge pull request #201 from dplanella/encoder-cleanup
Encoder: do kernel check, PEP8 cleanup
2 parents 503e839 + f8c730e commit 696c949

File tree

1 file changed

+183
-190
lines changed

1 file changed

+183
-190
lines changed

Adafruit_BBIO/Encoder.py

Lines changed: 183 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
import os
55
import logging
66
import itertools
7+
import platform
8+
9+
if not platform.release().startswith('4.4'):
10+
raise ImportError(
11+
'The Encoder module requires Linux kernel version >= 4.4.x.\n'
12+
'Please upgrade your kernel to use this module.\n'
13+
'Your Linux kernel version is {}.'.format(platform.release()))
714

815
eQEP0 = 0
916
eQEP1 = 1
@@ -60,193 +67,179 @@ def __init__(self, channel, pin_A, pin_B, sys_path):
6067

6168
class RotaryEncoder(object):
6269

63-
def _run_cmd(self, cmd):
64-
'''Runs a command. If not successful (i.e. error code different than zero),
65-
print the stderr output as a warning.
66-
'''
67-
68-
try:
69-
output = check_output(cmd, stderr=STDOUT)
70-
self._logger.info("_run_cmd(): cmd='{}' return code={} output={}".format(
71-
" ".join(cmd), 0, output))
72-
except CalledProcessError as e:
73-
self._logger.warning(
74-
"_run_cmd(): cmd='{}' return code={} output={}".format(
75-
" ".join(cmd), e.returncode, e.output))
76-
77-
def config_pin(self, pin):
78-
'''
79-
config_pin()
80-
Config pin for QEP
81-
'''
82-
83-
self._run_cmd(["config-pin", pin, "qep"])
84-
85-
def cat_file(self, path):
86-
'''
87-
cat_file()
88-
Print contents of file
89-
'''
90-
91-
self._run_cmd(["cat", path])
92-
93-
def __init__(self, eqep_num):
94-
'''
95-
RotaryEncoder(eqep_num)
96-
Creates an instance of the class RotaryEncoder.
97-
eqep_num determines which eQEP pins are set up.
98-
eqep_num can be: EQEP0, EQEP1, EQEP2 or EQEP2b based on which pins \
99-
the rotary encoder is connected to.
100-
'''
101-
102-
self._logger = logging.getLogger(__name__)
103-
self._logger.addHandler(logging.NullHandler())
104-
105-
# Configure eqep module
106-
self._eqep = eQEP.fromdict(_eQEP_DEFS[eqep_num])
107-
self._logger.info(
108-
"Configuring: {}, pin A: {}, pin B: {}, sys path: {}".format(
109-
self._eqep.channel, self._eqep.pin_A, self._eqep.pin_B,
110-
self._eqep.sys_path))
111-
112-
self.config_pin(self._eqep.pin_A)
113-
self.config_pin(self._eqep.pin_B)
114-
115-
self.base_dir = self._eqep.sys_path
116-
self._logger.debug(
117-
"RotaryEncoder(): self.base_dir: {0}".format(self.base_dir))
118-
119-
self.enable()
120-
121-
def enable(self):
122-
'''
123-
enable()
124-
Turns the eQEP hardware ON
125-
'''
126-
enable_file = "%s/enabled" % self.base_dir
127-
self._logger.debug("enable(): enable_file: {0}".format(enable_file))
128-
self._logger.warning(
129-
"enable(): TODO: not implemented, write 1 to {}".format(enable_file))
130-
#return sysfs.kernelFileIO(enable_file, '1')
131-
132-
def disable(self):
133-
'''
134-
disable()
135-
Turns the eQEP hardware OFF
136-
'''
137-
enable_file = "%s/enabled" % self.base_dir
138-
self._logger.debug("disable(): enable_file: {0}".format(enable_file))
139-
self._logger.warning(
140-
"disable(): TODO: not implemented, write 0 to {}".format(enable_file))
141-
#return sysfs.kernelFileIO(enable_file, '0')
142-
143-
def setAbsolute(self):
144-
'''
145-
setAbsolute()
146-
Set mode as Absolute
147-
The position starts at zero and is incremented or
148-
decremented by the encoder's movement
149-
'''
150-
mode_file = "%s/mode" % self.base_dir
151-
self._logger.debug("setAbsolute(): mode_file: {0}".format(mode_file))
152-
self._logger.warning(
153-
"setAbsolute(): TODO: not implemented, write 0 to {}".format(mode_file))
154-
#return sysfs.kernelFileIO(mode_file, '0')
155-
156-
def setRelative(self):
157-
'''
158-
setRelative()
159-
Set mode as Relative
160-
The position is reset when the unit timer overflows.
161-
'''
162-
mode_file = "%s/mode" % self.base_dir
163-
self._logger.debug("setRelative(): mode_file: {0}".format(mode_file))
164-
self._logger.warning(
165-
"setRelative(): TODO: not implemented, write 1 to {}".format(mode_file))
166-
#return sysfs.kernelFileIO(mode_file, '1')
167-
168-
def getMode(self):
169-
'''
170-
getMode()
171-
Returns the mode the eQEP hardware is in.
172-
'''
173-
mode_file = "%s/mode" % self.base_dir
174-
self._logger.debug("getMode(): mode_file: {0}".format(mode_file))
175-
self._logger.warning("getMode(): TODO: read mode_file")
176-
#return sysfs.kernelFileIO(mode_file)
177-
178-
def getPosition(self):
179-
'''
180-
getPosition()
181-
Get the current position of the encoder.
182-
In absolute mode, this attribute represents the current position
183-
of the encoder.
184-
In relative mode, this attribute represents the position of the
185-
encoder at the last unit timer overflow.
186-
'''
187-
self._logger.debug("Channel: {}".format(self._eqep.channel))
188-
position_file = "%s/position" % self.base_dir
189-
self._logger.debug("getPosition(): position_file: {0}".format(position_file))
190-
position_handle = open(position_file, 'r')
191-
self._logger.debug("getPosition(): position_handle: {0}".format(position_handle))
192-
position = position_handle.read()
193-
self._logger.debug("getPosition(): position: {0}".format(position))
194-
#return sysfs.kernelFileIO(position_file)
195-
196-
return position
197-
198-
def setFrequency(self, freq):
199-
'''
200-
setFrequency(freq)
201-
Set the frequency in Hz at which the driver reports new positions.
202-
'''
203-
period_file = "%s/period" % self.base_dir
204-
self._logger.debug("setFrequency(): period_file: {0}".format(period_file))
205-
self._logger.debug("setFrequency(): freq: {0}".format(freq))
206-
self._logger.debug("setFrequency(): 1000000000/freq: {0}".format(1000000000/freq))
207-
self._logger.debug("setFrequency(): str(1000000000/freq)): {0}".format(str(1000000000/freq)))
208-
self._logger.warning(
209-
"setFrequency(): TODO: not implemented, set {} to {}".format(
210-
period_file, str(1000000000/freq)))
211-
#return sysfs.kernelFileIO(period_file, str(1000000000/freq))
212-
213-
def setPosition(self, val):
214-
'''
215-
setPosition(value)
216-
Give a new value to the current position
217-
'''
218-
position_file = "%s/position" % self.base_dir
219-
self._logger.warning(
220-
"setPosition(): TODO: not implemented, write position to {}".format(
221-
position_file))
222-
#return sysfs.kernelFileIO(position_file, str(val))
223-
224-
def zero(self):
225-
'''
226-
zero()s
227-
Set the current position to 0
228-
'''
229-
return self.setPosition(0)
230-
231-
232-
#"""
233-
# encoder_test.py
234-
# Rekha Seethamraju
235-
# An example to demonstrate the use of the eQEP library
236-
# for PyBBIO.
237-
# This example program is in the public domain.
238-
#"""
239-
#from bbio import *
240-
#from bbio.libraries.RotaryEncoder import RotaryEncoder
241-
#
242-
#encoder = RotaryEncoder(RotaryEncoder.EQEP2b)
243-
#
244-
#def setup():
245-
# encoder.setAbsolute()
246-
# encoder.zero()
247-
#
248-
#def loop():
249-
# print("encoder position : "+encoder.getPosition())
250-
# delay(1000)
251-
#
252-
#run(setup, loop)
70+
def _run_cmd(self, cmd):
71+
'''Runs a command. If not successful (i.e. error code different than
72+
zero), print the stderr output as a warning.
73+
'''
74+
75+
try:
76+
output = check_output(cmd, stderr=STDOUT)
77+
self._logger.info(
78+
"_run_cmd(): cmd='{}' return code={} output={}".format(
79+
" ".join(cmd), 0, output))
80+
except CalledProcessError as e:
81+
self._logger.warning(
82+
"_run_cmd(): cmd='{}' return code={} output={}".format(
83+
" ".join(cmd), e.returncode, e.output))
84+
85+
def config_pin(self, pin):
86+
'''
87+
config_pin()
88+
Config pin for QEP
89+
'''
90+
91+
self._run_cmd(["config-pin", pin, "qep"])
92+
93+
def cat_file(self, path):
94+
'''
95+
cat_file()
96+
Print contents of file
97+
'''
98+
99+
self._run_cmd(["cat", path])
100+
101+
def __init__(self, eqep_num):
102+
'''
103+
RotaryEncoder(eqep_num)
104+
Creates an instance of the class RotaryEncoder.
105+
eqep_num determines which eQEP pins are set up.
106+
eqep_num can be: EQEP0, EQEP1, EQEP2 or EQEP2b based on which pins \
107+
the rotary encoder is connected to.
108+
'''
109+
110+
self._logger = logging.getLogger(__name__)
111+
self._logger.addHandler(logging.NullHandler())
112+
113+
# Configure eqep module
114+
self._eqep = eQEP.fromdict(_eQEP_DEFS[eqep_num])
115+
self._logger.info(
116+
"Configuring: {}, pin A: {}, pin B: {}, sys path: {}".format(
117+
self._eqep.channel, self._eqep.pin_A, self._eqep.pin_B,
118+
self._eqep.sys_path))
119+
120+
self.config_pin(self._eqep.pin_A)
121+
self.config_pin(self._eqep.pin_B)
122+
123+
self.base_dir = self._eqep.sys_path
124+
self._logger.debug(
125+
"RotaryEncoder(): self.base_dir: {0}".format(self.base_dir))
126+
127+
self.enable()
128+
129+
def enable(self):
130+
'''
131+
enable()
132+
Turns the eQEP hardware ON
133+
'''
134+
enable_file = "%s/enabled" % self.base_dir
135+
self._logger.debug("enable(): enable_file: {0}".format(enable_file))
136+
self._logger.warning(
137+
"enable(): TODO: not implemented, write 1 to {}".format(enable_file))
138+
# return sysfs.kernelFileIO(enable_file, '1')
139+
140+
def disable(self):
141+
'''
142+
disable()
143+
Turns the eQEP hardware OFF
144+
'''
145+
enable_file = "%s/enabled" % self.base_dir
146+
self._logger.debug("disable(): enable_file: {0}".format(enable_file))
147+
self._logger.warning(
148+
"disable(): TODO: not implemented, write 0 to {}".format(
149+
enable_file))
150+
# return sysfs.kernelFileIO(enable_file, '0')
151+
152+
def setAbsolute(self):
153+
'''
154+
setAbsolute()
155+
Set mode as Absolute
156+
The position starts at zero and is incremented or
157+
decremented by the encoder's movement
158+
'''
159+
mode_file = "%s/mode" % self.base_dir
160+
self._logger.debug("setAbsolute(): mode_file: {0}".format(mode_file))
161+
self._logger.warning(
162+
"setAbsolute(): TODO: not implemented, write 0 to {}".format(
163+
mode_file))
164+
# return sysfs.kernelFileIO(mode_file, '0')
165+
166+
def setRelative(self):
167+
'''
168+
setRelative()
169+
Set mode as Relative
170+
The position is reset when the unit timer overflows.
171+
'''
172+
mode_file = "%s/mode" % self.base_dir
173+
self._logger.debug("setRelative(): mode_file: {0}".format(mode_file))
174+
self._logger.warning(
175+
"setRelative(): TODO: not implemented, write 1 to {}".format(
176+
mode_file))
177+
# return sysfs.kernelFileIO(mode_file, '1')
178+
179+
def getMode(self):
180+
'''
181+
getMode()
182+
Returns the mode the eQEP hardware is in.
183+
'''
184+
mode_file = "%s/mode" % self.base_dir
185+
self._logger.debug("getMode(): mode_file: {0}".format(mode_file))
186+
self._logger.warning("getMode(): TODO: read mode_file")
187+
# return sysfs.kernelFileIO(mode_file)
188+
189+
def getPosition(self):
190+
'''
191+
getPosition()
192+
Get the current position of the encoder.
193+
In absolute mode, this attribute represents the current position
194+
of the encoder.
195+
In relative mode, this attribute represents the position of the
196+
encoder at the last unit timer overflow.
197+
'''
198+
self._logger.debug("Channel: {}".format(self._eqep.channel))
199+
position_file = "%s/position" % self.base_dir
200+
self._logger.debug(
201+
"getPosition(): position_file: {0}".format(position_file))
202+
position_handle = open(position_file, 'r')
203+
self._logger.debug(
204+
"getPosition(): position_handle: {0}".format(position_handle))
205+
position = position_handle.read()
206+
self._logger.debug("getPosition(): position: {0}".format(position))
207+
# return sysfs.kernelFileIO(position_file)
208+
209+
return position
210+
211+
def setFrequency(self, freq):
212+
'''
213+
setFrequency(freq)
214+
Set the frequency in Hz at which the driver reports new positions.
215+
'''
216+
period_file = "%s/period" % self.base_dir
217+
self._logger.debug(
218+
"setFrequency(): period_file: {0}".format(period_file))
219+
self._logger.debug("setFrequency(): freq: {0}".format(freq))
220+
self._logger.debug(
221+
"setFrequency(): 1000000000/freq: {0}".format(1000000000/freq))
222+
self._logger.debug("setFrequency(): str(1000000000/freq)): {0}".format(
223+
str(1000000000/freq)))
224+
self._logger.warning(
225+
"setFrequency(): TODO: not implemented, set {} to {}".format(
226+
period_file, str(1000000000/freq)))
227+
# return sysfs.kernelFileIO(period_file, str(1000000000/freq))
228+
229+
def setPosition(self, val):
230+
'''
231+
setPosition(value)
232+
Give a new value to the current position
233+
'''
234+
position_file = "%s/position" % self.base_dir
235+
self._logger.warning(
236+
"setPosition(): TODO: not implemented, write position to {}".format(
237+
position_file))
238+
# return sysfs.kernelFileIO(position_file, str(val))
239+
240+
def zero(self):
241+
'''
242+
zero()s
243+
Set the current position to 0
244+
'''
245+
return self.setPosition(0)

0 commit comments

Comments
 (0)