Skip to content

Commit 91fa012

Browse files
authored
Merge pull request #195 from dplanella/master
Encoder: add logging, move docs to README.md
2 parents 335e105 + 6f19946 commit 91fa012

File tree

2 files changed

+189
-118
lines changed

2 files changed

+189
-118
lines changed

Adafruit_BBIO/Encoder.py

+92-118
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,9 @@
11
#!/usr/bin/python
22

3-
# ===========================================================================
4-
# Adafruit_BBIO.Encoder Class
5-
# ===========================================================================
6-
# refers to graycatlabs/PyBBIO/bbio/libraries/RotaryEncoder/rotary_encoder.py
7-
8-
# BeagleBone must boot with cape-universal enabled
9-
# and load the cape-universala overlay in order to
10-
# use all the eQEP pins
11-
#
12-
# Install the latest Device Tree overlays:
13-
# ========================================
14-
# sudo apt-get upgrade bb-cape-overlays
15-
#
16-
# File: /boot/uEnv.txt
17-
# ====================
18-
# uname_r=4.4.62-ti-r99
19-
# cmdline=coherent_pool=1M quiet cape_universal=enable
20-
# cape_enable=bone_capemgr.enable_partno=cape-universala
21-
#
22-
# File: /sys/devices/platform/bone_capemgr/slots
23-
# ==============================================
24-
# 0: PF---- -1
25-
# 1: PF---- -1
26-
# 2: PF---- -1
27-
# 3: PF---- -1
28-
# 4: P-O-L- 0 Override Board Name,00A0,Override Manuf,cape-universala
29-
#
30-
# eqep0: P9_27, P9_92
31-
# ===================
32-
# config-pin P9_27 qep
33-
# config-pin P9_92 qep # alias for P9_42.1
34-
# cat /sys/devices/platform/ocp/48300000.epwmss/48300180.eqep/position
35-
#
36-
# eqep1: P8.33, P8.35
37-
# ===================
38-
# config-pin P8.33 qep
39-
# config-pin P8.35 qep
40-
# cat /sys/devices/platform/ocp/48302000.epwmss/48302180.eqep/position
41-
#
42-
# eqep2: P8.11, P8.12
43-
# ===================
44-
# config-pin P8.11 qep
45-
# config-pin P8.12 qep
46-
# cat /sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position
47-
#
48-
# alternate pins for eqep2 (mutually exclusive)
49-
# eqep2b: P8.41, P8.42
50-
# ====================
51-
# config-pin P8.41 qep
52-
# config-pin P8.42 qep
53-
# cat /sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position
54-
55-
from subprocess import call
3+
from subprocess import check_output, STDOUT, CalledProcessError
564
import os
5+
import logging
6+
577

588
class QEP :
599

@@ -100,48 +50,63 @@ class RotaryEncoder(object):
10050
EQEP1 = 1
10151
EQEP2 = 2
10252
EQEP2b = 3
103-
53+
54+
def _run_cmd(self, cmd):
55+
'''Runs a command. If not successful (i.e. error code different than zero),
56+
print the stderr output as a warning.
57+
'''
58+
59+
try:
60+
output = check_output(cmd, stderr=STDOUT)
61+
self._logger.info("_run_cmd(): cmd='{}' return code={} output={}".format(
62+
" ".join(cmd), 0, output))
63+
except CalledProcessError as e:
64+
self._logger.warning(
65+
"_run_cmd(): cmd='{}' return code={} output={}".format(
66+
" ".join(cmd), e.returncode, e.output))
67+
10468
def config_pin(self, pin):
10569
'''
10670
config_pin()
10771
Config pin for QEP
10872
'''
109-
result = call(["config-pin", pin, "qep"])
110-
print("config_pin> pin={0} result={1}".format(pin, result))
111-
return result
112-
73+
74+
self._run_cmd(["config-pin", pin, "qep"])
75+
11376
def cat_file(self, path):
11477
'''
11578
cat_file()
11679
Print contents of file
11780
'''
118-
result = call(["cat", path])
119-
print("cat_file> path={0} result={1}".format(path, result))
120-
return result
121-
81+
82+
self._run_cmd(["cat", path])
83+
12284
def __init__(self, eqep_num):
12385
'''
12486
RotaryEncoder(eqep_num)
125-
Creates an instance of the class RotaryEncoder.
126-
eqep_num determines which eQEP pins are set up.
87+
Creates an instance of the class RotaryEncoder.
88+
eqep_num determines which eQEP pins are set up.
12789
eqep_num can be: EQEP0, EQEP1, EQEP2 or EQEP2b based on which pins \
12890
the rotary encoder is connected to.
12991
'''
130-
print(">>>>>>>> TEST CALL BEGIN")
13192

132-
###################################
133-
print(">>>>>> eqep0: P9_27, P9_92")
93+
self._logger = logging.getLogger(__name__)
94+
self._logger.addHandler(logging.NullHandler())
95+
96+
# Configure eqep0
97+
self._logger.info("Configuring eqep0, pins: P9.27, P9.92")
98+
13499
pin = "P9_27"
135100
self.config_pin(pin)
136101

137102
pin = "P9_92"
138103
self.config_pin(pin)
139104

140105
path = "/sys/devices/platform/ocp/48300000.epwmss/48300180.eqep/position"
141-
self.cat_file(path);
106+
self.cat_file(path)
142107

143-
###################################
144-
print(">>>>>>> eqep1: P8.33, P8.35")
108+
# Configure eqep1
109+
self._logger.info("Configuring eqep1, pins: P8.33, P8.35")
145110

146111
pin = "P8.33"
147112
self.config_pin(pin)
@@ -152,8 +117,8 @@ def __init__(self, eqep_num):
152117
path = "/sys/devices/platform/ocp/48302000.epwmss/48302180.eqep/position"
153118
self.cat_file(path);
154119

155-
###################################
156-
print(">>>>>>> eqep2: P8.11, P8.12")
120+
# Configure eqep2
121+
self._logger.info("Configuring eqep2, pins: P8.11, P8.12")
157122

158123
pin = "P8.11"
159124
self.config_pin(pin)
@@ -164,8 +129,8 @@ def __init__(self, eqep_num):
164129
path = "/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position"
165130
self.cat_file(path);
166131

167-
###################################
168-
print(">>>>>>> eqep2b: P8.41, P8.42")
132+
# Configure eqep2b
133+
self._logger.info("Configuring eqep2, pins: P8.41, P8.42")
169134

170135
pin = "P8.41"
171136
self.config_pin(pin)
@@ -176,17 +141,17 @@ def __init__(self, eqep_num):
176141
path = "/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position"
177142
self.cat_file(path);
178143

179-
###################################
180-
print(">>>>>>>> TEST CALL END")
144+
self._logger.debug("RotaryEncoder(): eqep_num: {0}".format(eqep_num))
145+
self._logger.debug("RotaryEncoder(): self._eqep_dirs[0]: {0}".format(self._eqep_dirs[0]))
146+
self._logger.debug("RotaryEncoder(): self._eqep_dirs[1]: {0}".format(self._eqep_dirs[1]))
147+
self._logger.debug("RotaryEncoder(): self._eqep_dirs[2]: {0}".format(self._eqep_dirs[2]))
148+
self._logger.debug("RotaryEncoder(): self._eqep_dirs[eqep_num: {0}]: {1}".format(eqep_num, self._eqep_dirs[eqep_num]))
181149

182-
print("RotaryEncoder(): eqep_num: {0}".format(eqep_num))
183-
print("RotaryEncoder(): self._eqep_dirs[0]: {0}".format(self._eqep_dirs[0]))
184-
print("RotaryEncoder(): self._eqep_dirs[1]: {0}".format(self._eqep_dirs[1]))
185-
print("RotaryEncoder(): self._eqep_dirs[2]: {0}".format(self._eqep_dirs[2]))
186-
print("RotaryEncoder(): self._eqep_dirs[eqep_num: {0}]: {1}".format(eqep_num, self._eqep_dirs[eqep_num]))
187150
assert 0 <= eqep_num <= 3 , "eqep_num must be between 0 and 3"
151+
188152
self.base_dir = self._eqep_dirs[eqep_num]
189-
print("RotaryEncoder(): self.base_dir: {0}".format(self.base_dir))
153+
self._logger.debug("RotaryEncoder(): self.base_dir: {0}".format(self.base_dir))
154+
190155
self.enable()
191156

192157
def enable(self):
@@ -195,93 +160,102 @@ def enable(self):
195160
Turns the eQEP hardware ON
196161
'''
197162
enable_file = "%s/enabled" % self.base_dir
198-
print("enable(): enable_file: {0}".format(enable_file))
199-
print("enable(): TODO: write 1 to enable_file")
200-
#return sysfs.kernelFileIO(enable_file, '1')
201-
163+
self._logger.debug("enable(): enable_file: {0}".format(enable_file))
164+
self._logger.warning(
165+
"enable(): TODO: not implemented, write 1 to {}".format(enable_file))
166+
#return sysfs.kernelFileIO(enable_file, '1')
167+
202168
def disable(self):
203169
'''
204170
disable()
205171
Turns the eQEP hardware OFF
206172
'''
207173
enable_file = "%s/enabled" % self.base_dir
208-
print("disable(): enable_file: {0}".format(enable_file))
209-
print("disable(): TODO: write 0 to enable_file")
174+
self._logger.debug("disable(): enable_file: {0}".format(enable_file))
175+
self._logger.warning(
176+
"disable(): TODO: not implemented, write 0 to {}".format(enable_file))
210177
#return sysfs.kernelFileIO(enable_file, '0')
211178

212179
def setAbsolute(self):
213180
'''
214181
setAbsolute()
215182
Set mode as Absolute
216-
The position starts at zero and is incremented or
183+
The position starts at zero and is incremented or
217184
decremented by the encoder's movement
218185
'''
219186
mode_file = "%s/mode" % self.base_dir
220-
print("setAbsolute(): mode_file: {0}".format(mode_file))
221-
print("setAbsolute(): TODO: write 0 to mode_file")
187+
self._logger.debug("setAbsolute(): mode_file: {0}".format(mode_file))
188+
self._logger.warning(
189+
"setAbsolute(): TODO: not implemented, write 0 to {}".format(mode_file))
222190
#return sysfs.kernelFileIO(mode_file, '0')
223-
191+
224192
def setRelative(self):
225193
'''
226194
setRelative()
227195
Set mode as Relative
228196
The position is reset when the unit timer overflows.
229197
'''
230198
mode_file = "%s/mode" % self.base_dir
231-
print("setRelative(): mode_file: {0}".format(mode_file))
232-
print("setRelative(): TODO: write 1 to mode_file")
199+
self._logger.debug("setRelative(): mode_file: {0}".format(mode_file))
200+
self._logger.warning(
201+
"setRelative(): TODO: not implemented, write 1 to {}".format(mode_file))
233202
#return sysfs.kernelFileIO(mode_file, '1')
234-
203+
235204
def getMode(self):
236205
'''
237206
getMode()
238207
Returns the mode the eQEP hardware is in.
239208
'''
240209
mode_file = "%s/mode" % self.base_dir
241-
print("getMode(): mode_file: {0}".format(mode_file))
242-
print("getMode(): TODO: read mode_file")
210+
self._logger.debug("getMode(): mode_file: {0}".format(mode_file))
211+
self._logger.warning("getMode(): TODO: read mode_file")
243212
#return sysfs.kernelFileIO(mode_file)
244213

245214
def getPosition(self):
246215
'''
247216
getPosition()
248217
Get the current position of the encoder.
249-
In absolute mode, this attribute represents the current position
250-
of the encoder.
251-
In relative mode, this attribute represents the position of the
218+
In absolute mode, this attribute represents the current position
219+
of the encoder.
220+
In relative mode, this attribute represents the position of the
252221
encoder at the last unit timer overflow.
253222
'''
254223
position_file = "%s/position" % self.base_dir
255-
print("getPosition(): position_file: {0}".format(position_file))
224+
self._logger.debug("getPosition(): position_file: {0}".format(position_file))
256225
position_handle = open(position_file, 'r')
257-
print("getPosition(): position_handle: {0}".format(position_handle))
226+
self._logger.debug("getPosition(): position_handle: {0}".format(position_handle))
258227
position = position_handle.read()
259-
print("getPosition(): position: {0}".format(position))
228+
self._logger.debug("getPosition(): position: {0}".format(position))
260229
#return sysfs.kernelFileIO(position_file)
230+
261231
return position
262-
263-
def setFrequency(self,freq):
232+
233+
def setFrequency(self, freq):
264234
'''
265235
setFrequency(freq)
266236
Set the frequency in Hz at which the driver reports new positions.
267237
'''
268238
period_file = "%s/period" % self.base_dir
269-
print("setFrequency(): period_file: {0}".format(period_file))
270-
print("setFrequency(): freq: {0}".format(period_file))
271-
print("setFrequency(): freq: {0}".format(freq))
272-
print("setFrequency(): 1000000000/freq: {0}".format(1000000000/freq))
273-
print("setFrequency(): str(1000000000/freq)): {0}".format(str(1000000000/freq)))
274-
print("setFrequency(): TODO: set period_file: {0}".format(str(1000000000/freq)))
239+
self._logger.debug("setFrequency(): period_file: {0}".format(period_file))
240+
self._logger.debug("setFrequency(): freq: {0}".format(freq))
241+
self._logger.debug("setFrequency(): 1000000000/freq: {0}".format(1000000000/freq))
242+
self._logger.debug("setFrequency(): str(1000000000/freq)): {0}".format(str(1000000000/freq)))
243+
self._logger.warning(
244+
"setFrequency(): TODO: not implemented, set {} to {}".format(
245+
period_file, str(1000000000/freq)))
275246
#return sysfs.kernelFileIO(period_file, str(1000000000/freq))
276-
277-
def setPosition(self,val):
278-
'''
247+
248+
def setPosition(self, val):
249+
'''
279250
setPosition(value)
280251
Give a new value to the current position
281252
'''
282253
position_file = "%s/position" % self.base_dir
254+
self._logger.warning(
255+
"setPosition(): TODO: not implemented, write position to {}".format(
256+
position_file))
283257
#return sysfs.kernelFileIO(position_file, str(val))
284-
258+
285259
def zero(self):
286260
'''
287261
zero()s
@@ -291,7 +265,7 @@ def zero(self):
291265

292266

293267
#"""
294-
# encoder_test.py
268+
# encoder_test.py
295269
# Rekha Seethamraju
296270
# An example to demonstrate the use of the eQEP library
297271
# for PyBBIO.
@@ -305,9 +279,9 @@ def zero(self):
305279
#def setup():
306280
# encoder.setAbsolute()
307281
# encoder.zero()
308-
#
282+
#
309283
#def loop():
310284
# print("encoder position : "+encoder.getPosition())
311285
# delay(1000)
312-
#
286+
#
313287
#run(setup, loop)

0 commit comments

Comments
 (0)