1
1
#!/usr/bin/python
2
2
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
56
4
import os
5
+ import logging
6
+
57
7
58
8
class QEP :
59
9
@@ -100,48 +50,63 @@ class RotaryEncoder(object):
100
50
EQEP1 = 1
101
51
EQEP2 = 2
102
52
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
+
104
68
def config_pin (self , pin ):
105
69
'''
106
70
config_pin()
107
71
Config pin for QEP
108
72
'''
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
+
113
76
def cat_file (self , path ):
114
77
'''
115
78
cat_file()
116
79
Print contents of file
117
80
'''
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
+
122
84
def __init__ (self , eqep_num ):
123
85
'''
124
86
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.
127
89
eqep_num can be: EQEP0, EQEP1, EQEP2 or EQEP2b based on which pins \
128
90
the rotary encoder is connected to.
129
91
'''
130
- print (">>>>>>>> TEST CALL BEGIN" )
131
92
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
+
134
99
pin = "P9_27"
135
100
self .config_pin (pin )
136
101
137
102
pin = "P9_92"
138
103
self .config_pin (pin )
139
104
140
105
path = "/sys/devices/platform/ocp/48300000.epwmss/48300180.eqep/position"
141
- self .cat_file (path );
106
+ self .cat_file (path )
142
107
143
- ###################################
144
- print ( ">>>>>>> eqep1: P8.33, P8.35" )
108
+ # Configure eqep1
109
+ self . _logger . info ( "Configuring eqep1, pins : P8.33, P8.35" )
145
110
146
111
pin = "P8.33"
147
112
self .config_pin (pin )
@@ -152,8 +117,8 @@ def __init__(self, eqep_num):
152
117
path = "/sys/devices/platform/ocp/48302000.epwmss/48302180.eqep/position"
153
118
self .cat_file (path );
154
119
155
- ###################################
156
- print ( ">>>>>>> eqep2: P8.11, P8.12" )
120
+ # Configure eqep2
121
+ self . _logger . info ( "Configuring eqep2, pins : P8.11, P8.12" )
157
122
158
123
pin = "P8.11"
159
124
self .config_pin (pin )
@@ -164,8 +129,8 @@ def __init__(self, eqep_num):
164
129
path = "/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position"
165
130
self .cat_file (path );
166
131
167
- ###################################
168
- print ( ">>>>>>> eqep2b : P8.41, P8.42" )
132
+ # Configure eqep2b
133
+ self . _logger . info ( "Configuring eqep2, pins : P8.41, P8.42" )
169
134
170
135
pin = "P8.41"
171
136
self .config_pin (pin )
@@ -176,17 +141,17 @@ def __init__(self, eqep_num):
176
141
path = "/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position"
177
142
self .cat_file (path );
178
143
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 ]))
181
149
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 ]))
187
150
assert 0 <= eqep_num <= 3 , "eqep_num must be between 0 and 3"
151
+
188
152
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
+
190
155
self .enable ()
191
156
192
157
def enable (self ):
@@ -195,93 +160,102 @@ def enable(self):
195
160
Turns the eQEP hardware ON
196
161
'''
197
162
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
+
202
168
def disable (self ):
203
169
'''
204
170
disable()
205
171
Turns the eQEP hardware OFF
206
172
'''
207
173
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 ))
210
177
#return sysfs.kernelFileIO(enable_file, '0')
211
178
212
179
def setAbsolute (self ):
213
180
'''
214
181
setAbsolute()
215
182
Set mode as Absolute
216
- The position starts at zero and is incremented or
183
+ The position starts at zero and is incremented or
217
184
decremented by the encoder's movement
218
185
'''
219
186
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 ))
222
190
#return sysfs.kernelFileIO(mode_file, '0')
223
-
191
+
224
192
def setRelative (self ):
225
193
'''
226
194
setRelative()
227
195
Set mode as Relative
228
196
The position is reset when the unit timer overflows.
229
197
'''
230
198
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 ))
233
202
#return sysfs.kernelFileIO(mode_file, '1')
234
-
203
+
235
204
def getMode (self ):
236
205
'''
237
206
getMode()
238
207
Returns the mode the eQEP hardware is in.
239
208
'''
240
209
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" )
243
212
#return sysfs.kernelFileIO(mode_file)
244
213
245
214
def getPosition (self ):
246
215
'''
247
216
getPosition()
248
217
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
252
221
encoder at the last unit timer overflow.
253
222
'''
254
223
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 ))
256
225
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 ))
258
227
position = position_handle .read ()
259
- print ("getPosition(): position: {0}" .format (position ))
228
+ self . _logger . debug ("getPosition(): position: {0}" .format (position ))
260
229
#return sysfs.kernelFileIO(position_file)
230
+
261
231
return position
262
-
263
- def setFrequency (self ,freq ):
232
+
233
+ def setFrequency (self , freq ):
264
234
'''
265
235
setFrequency(freq)
266
236
Set the frequency in Hz at which the driver reports new positions.
267
237
'''
268
238
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 )))
275
246
#return sysfs.kernelFileIO(period_file, str(1000000000/freq))
276
-
277
- def setPosition (self ,val ):
278
- '''
247
+
248
+ def setPosition (self , val ):
249
+ '''
279
250
setPosition(value)
280
251
Give a new value to the current position
281
252
'''
282
253
position_file = "%s/position" % self .base_dir
254
+ self ._logger .warning (
255
+ "setPosition(): TODO: not implemented, write position to {}" .format (
256
+ position_file ))
283
257
#return sysfs.kernelFileIO(position_file, str(val))
284
-
258
+
285
259
def zero (self ):
286
260
'''
287
261
zero()s
@@ -291,7 +265,7 @@ def zero(self):
291
265
292
266
293
267
#"""
294
- # encoder_test.py
268
+ # encoder_test.py
295
269
# Rekha Seethamraju
296
270
# An example to demonstrate the use of the eQEP library
297
271
# for PyBBIO.
@@ -305,9 +279,9 @@ def zero(self):
305
279
#def setup():
306
280
# encoder.setAbsolute()
307
281
# encoder.zero()
308
- #
282
+ #
309
283
#def loop():
310
284
# print("encoder position : "+encoder.getPosition())
311
285
# delay(1000)
312
- #
286
+ #
313
287
#run(setup, loop)
0 commit comments