-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpio.py
217 lines (168 loc) · 7.34 KB
/
gpio.py
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
GPIO module
-----------
Created by hbldh <henrik.blidh@nedomkull.com> on 2016-04-14
Modified by lkasso <hello@mbientlab.com>
"""
from __future__ import division
from __future__ import print_function
from __future__ import absolute_import
import re
import logging
from pymetawear import libmetawear
from pymetawear import add_stream_logger, modules
from pymetawear.client import MetaWearClient
from mbientlab.metawear.cbindings import GpioPinChangeType, GpioPullMode, \
GpioAnalogReadParameters, GpioAnalogReadMode
from pymetawear.modules.base import PyMetaWearModule, data_handler
log = logging.getLogger(__name__)
def handle_gpio_notification(data):
# Handle a (epoch_time, int value) type.
epoch = data[0]
value = data[1]
print("[{0}] value: {1}".format(epoch, *value))
class GpioModule(PyMetaWearModule):
"""MetaWear gpio module implementation.
:param ctypes.c_long board: The MetaWear board pointer value.
:param int module_id: The module id of this accelerometer
component, obtained from ``libmetawear``.
:param bool debug: If ``True``, module prints out debug information.
"""
def __init__(self, board, module_id):
super(GpioModule, self).__init__(board)
self.module_id = module_id
self.current_pin = 0
self.current_mode = 0
self.current_read = 0
self.pin = {}
self.mode = {}
self.read = {}
gpio_pin_class = GpioPinChangeType
gpio_mode_class = GpioPullMode
gpio_read_class = GpioAnalogReadMode
if gpio_pin_class is not None:
# Parse possible pin outputs for GPIOs.
for key, value in vars(gpio_pin_class).items():
if re.search('^([A-Z]*)', key) and isinstance(value,int):
self.pin.update({key:value})
if gpio_mode_class is not None:
# Parse possible pull modes for GPIOs.
for key, value in vars(gpio_mode_class).items():
if re.search('^([A-Z]*)', key) and isinstance(value,int):
self.mode.update({key:value})
if gpio_read_class is not None:
# Parse possible analog read modes for GPIOs.
for key, value in vars(gpio_read_class).items():
if re.search('^([A-Z]*)', key) and isinstance(value,int):
self.read.update({key:value})
def __str__(self):
return "{0} {1}: Pin outputs: {2}, Pull modes: {3}, Read modes: {4}".format(
self.module_name, self.sensor_name,
[k for k in sorted(self.pin.keys())],
[k for k in sorted(self.mode.keys())],
[k for k in sorted(self.read.keys())])
def __repr__(self):
return str(self)
@property
def module_name(self):
return "Gpio"
@property
def sensor_name(self):
return self.module_name
@property
def data_signal(self):
# TODO: Fix this pin issue!
return libmetawear.mbl_mw_gpio_get_pin_monitor_data_signal(self.board, '0')
#if self.analog:
# return libmetawear.mbl_mw_gpio_get_analog_input_data_signal(self.board, 0)
#elif self.digital:
# return libmetawear.mbl_mw_gpio_get_analog_input_data_signal(
# self.board, pin)
#else:
# return libmetawear.mbl_mw_gpio_get_pin_monitor_data_signal(
# self.board)
def _get_pin(self, value):
if value.lower() in self.pin:
return self.pin.get(value.lower())
else:
raise ValueError(
"Requested Pin Change Type ({0}) was not part of possible values: {1}".format(
value.lower(), self.pin.keys()))
def _get_mode(self, value):
if value.lower() in self.mode:
return self.mode.get(value.lower())
else:
raise ValueError(
"Requested Pull Mode ({0}) was not part of possible values: {1}".format(
value.lower(), self.mode.keys()))
def _get_read(self, value):
if value.lower() in self.read:
return self.read.get(value.lower())
else:
raise ValueError(
"Requested Analog Read Mode ({0}) was not part of possible values: {1}".format(
value.lower(), self.read.keys()))
def get_current_settings(self):
return "Pin change type: {} pull mode: {} analog read mode: {}".format(self.current_pin, self.current_mode, self.current_read)
def get_possible_settings(self):
return {
'Pin change type': [x.lower() for x in sorted(
self.pin.keys(), key=lambda x:(x.lower()))],
'Pull mode': [x.lower() for x in sorted(
self.mode.keys(), key=lambda x:(x.lower()))],
'Analog read mode': [x.lower() for x in sorted(
self.read.keys(), key=lambda x:(x.lower()))]
}
def set_settings(self, pin, rmode=None, pmode=None, ptype=None):
if rmode is not None:
#rmode = self._get_read(rmode)
log.debug("Setting the Analog Read Mode to {0}".format(rmode))
self.current_mode = rmode
if pmode is not None:
self.current_ = pmode
if ptype is not None:
self.current_ = ptype
def set_pull_mode(self, pin=None, pmode=None):
libmetawear.mbl_mw_gpio_set_pull_mode(self.board, pin, pmode)
def set_digital_out(self, pin=None):
libmetawear.mbl_mw_gpio_set_digital_output(self.board, pin)
def clear_digital_out(self, pin=None):
libmetawear.mbl_mw_gpio_clear_digital_output(self.board, pin)
def set_pin_change(self, pin=None, ptype=None):
libmetawear.mbl_mw_gpio_set_pin_change_type(self.board, pin, ptype)
def notifications(self, callback=None):
"""Subscribe or unsubscribe to accelerometer notifications.
Convenience method for handling gpio usage.
Example:
.. code-block:: python
def handle_gpio_notification(data)
# Handle a (epoch_time, int value) type.
epoch = data[0]
value = data[1]
print("[{0}] value: {1}".format(epoch, *value))
mwclient.gpio.notifications(handle_gpio_notification)
:param callable callback: Gpio notification callback function.
If `None`, unsubscription to accelerometer notifications is registered.
"""
if callback is None:
self.stop()
super(GpioModule, self).notifications(None)
else:
super(GpioModule, self).notifications(data_handler(callback))
self.start()
def start(self, pin=None):
"""Switches the gpio to active mode."""
libmetawear.mbl_mw_gpio_start_pin_monitoring(self.board, pin)
def stop(self, pin=None):
"""Switches the gpio to standby mode."""
libmetawear.mbl_mw_gpio_stop_pin_monitoring(self.board, pin)
client = MetaWearClient("CC:3E:36:3A:4B:50", debug=True)
gp = GpioModule(client.board, libmetawear.mbl_mw_metawearboard_lookup_module(client.board, modules.Modules.MBL_MW_MODULE_GPIO))
settings = gp.get_possible_settings()
print("Possible accelerometer settings of client:")
for k, v in settings.items():
print(k, v)
gp.set_settings(pin=0, rmode='ADC', pmode=None, ptype=None)
gp.notifications(handle_gpio_notification)