-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsensors.py
More file actions
211 lines (177 loc) · 6.33 KB
/
sensors.py
File metadata and controls
211 lines (177 loc) · 6.33 KB
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
import time
import pigpio
from utils.POO import SingletonDecorator as Singleton
OFF = LOW = CLEAR = pigpio.OFF
ON = HIGH = SET = pigpio.ON
RISING_EDGE = pigpio.RISING_EDGE
FALLING_EDGE = pigpio.FALLING_EDGE
EITHER_EDGE = pigpio.EITHER_EDGE
INPUT = pigpio.INPUT
OUTPUT = pigpio.OUTPUT
# TODO :
#
# Donner acces a la liste des GPIOs libres
#
# Creer un decorateur ou une classe remplacant un circuit anti-rebonds
#
# Faire des blocks d'acces pour initialiser et utiliser des capteurs additionnels
# - set <variableName> to [init <Input|Output|PWM|Servo> on pin <0>: return object]
# voir wyliodrin (try without create account, and start a new project)
#
# Utiliser __enter__ et __exit__ pour initialiser les capteurs (surtout utile pour les capteurs de camera)
@Singleton
class PIGPIO(object):
#FreePINs = []
def __init__(self):
# Avoid reinitialisation in case of multiple call
if hasattr(self, '_pi') and self._pi: return
self._pi = pigpio.pi()
def __del__(self):
self._pi.stop()
self._pi = None
def __getattr__(self, attr):
return getattr(self._pi, attr)
class SensorInterface(object):
def read(self): pass
def write(self, level): pass
def set(self): self.write(ON)
def clear(self): self.write(OFF)
on = high = set
off = low = clear
def addProcess(self, function, edge=RISING_EDGE): pass
def delProcess(self, function): pass
def wait(self, level, timeout=0): pass
class Sensor(SensorInterface):
def __init__(self, pin, mode=INPUT):
self._mode = mode
self._pi = PIGPIO()
#self._pin = self._pi.get(pin)
self._pin = pin
self._callbacks = {}
self._pi.set_mode(pin, mode)
#def __del__(self):
# self._pi.put(self._pin)
def read(self):
return self._pi.read(self._pin)
def write(self, level):
if self._mode == INPUT:
raise AttributeError('write not permitted on INPUT GPIO')
self._pi.write(self._pin, level)
def set(self): self.write(ON)
def clear(self): self.write(OFF)
on = high = set
off = low = clear
def addProcess(self, function, edge=RISING_EDGE):
self._callbacks[function] = self._pi.callback(self._pin, edge, lambda p,l,t: function(self))
def delProcess(self, function):
self._callbacks[function].cancel()
self._callbacks.remove(function)
def wait(self, level=RISING_EDGE, timeout=0):
class _wait(pigpio._callback):
def __init__(this, pin, edge, timeout=0):
start = time.time()
this.triggered = False
pigpio._callback.__init__(this, self._pi._notify, pin, edge, this.trigger)
while (not this.triggered) and (not timeout or ((time.time()-start) < timeout)):
time.sleep(0.05)
this.cancel()
def trigger(this, pin, level, tick):
this.triggered = True
return _wait(self._pin, level, timeout).triggered
class Input(Sensor):
def __init__(self, pin):
super(Input, self).__init__(pin, INPUT)
class Output(Sensor):
def __init__(self, pin):
super(Output, self).__init__(pin, OUTPUT)
self.clear()
class PWMOutput(Output):
def __init__(self, pin, freq=100, range=100):
super(PWMOutput, self).__init__(pin)
self._pi.set_PWM_frequency(pin, freq)
self._pi.set_PWM_range(pin, range)
self.stop()
def set(self, value):
self._pi.set_PWM_dutycycle(self._pin, value)
def freq(self, value):
self._pi.set_PWM_frequency(self._pin, value)
def range(self, value):
self._pi.set_PWM_range(self._pin, value)
def stop(self):
self.clear()
# Servo is like PWM but
# - frequency is always 50Hz,
# - pulsewidth is always between 1ms and 2ms
# Exceptions are raised to protect servos when parameters are wrong
class ServoOutput(Output):
def __init__(self, pin, min=1000, max=2000):
super(ServoOutput, self).__init__(pin)
if min<500 or max>2500:
raise ValueError('min and max values can be exceed range [500:2500]')
if min>max:
raise ValueError('max must be greater than min')
self._min = min
self._max = max
self.stop()
def set(self, value=None, percent=None):
# Value is in milliseconds
if value is None and percent is None:
raise ValueError('value or percent must be set')
if value is not None and percent is not None:
raise ValueError('only one value or percent must be set')
if percent and (percent<0 or percent>100):
raise ValueError('percent must be in range [0:100]')
if value is None:
value = (self._max-self._min)*percent/100 + self._min
self._pi.set_servo_pulsewidth(self._pin, value)
def stop(self):
self._pi.set_servo_pulsewidth(self._pin, 0)
# TODO:
# Creer un decorateur ou une classe remplacant un circuit anti-rebonds pour la classe Input
if __name__ == '__main__':
def printState(sensor):
print sensor.read()
def test():
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_UP)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_DOWN)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_UP)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_DOWN)
time.sleep(10)
pi.set_pull_up_down(17, pigpio.PUD_UP)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_DOWN)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_UP)
time.sleep(1)
pi.set_pull_up_down(17, pigpio.PUD_DOWN)
pi = PIGPIO()
from threading import Thread
Thread(target=test).start()
s = Input(17)
s.addProcess(printState, EITHER_EDGE)
time.sleep(6)
print 'wait test'
print s.wait(timeout=2),
print 'returned'
import sys
sys.exit()
PIN_LEFT = 25
PIN_RIGHT = 4
pins = [ServoOutput(PIN_LEFT), ServoOutput(PIN_RIGHT)]
def stop():
for pin in pins:
pin.stop()
def move(speed_left=100, speed_right=100):
speed_left = -speed_left/2+50
speed_right = speed_right/2+50
pins[0].set(percent=speed_left)
pins[1].set(percent=speed_right)
for s in range(-100, 101, 10):
print 'speed:', s
move(s, s)
time.sleep(1)
stop()