-
Notifications
You must be signed in to change notification settings - Fork 1
/
ConveyorBelt.py
executable file
·157 lines (129 loc) · 5.01 KB
/
ConveyorBelt.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
# Salzburg Research ForschungsgesmbH
# Christoph Schranz & Armin Niedermueller
# Conveyor Belt Control
from time import sleep
from multiprocessing import Process
class ConveyorBelt:
def __init__(self):
self.state = "init"
self.distance = 0.0
self.showstate = 0
try:
import pigpio
except ModuleNotFoundError:
raise "Module pigpio not found."
self.CYCLE = 128
self.velocity = 0.05428 # Velocity of the belt im m/s (5.5cm/s)
self.DIR = 20 # Direction GPIO Pin
self.STEP = 21 # Step GPIO Pin
self.LEFT = 16 # GPIO pin of left
self.RIGHT = 19 # GPIO pin of right
self.RELAY = 12 # to control the relais
# Connect to pigpiod daemon
self.pi = pigpio.pi()
# Set up pins as an output
self.pi.set_mode(self.DIR, pigpio.OUTPUT)
self.pi.set_mode(self.STEP, pigpio.OUTPUT)
self.pi.set_mode(self.RELAY, pigpio.OUTPUT)
self.pi.write(self.RELAY, 1)
# Set up input switch
self.pi.set_mode(self.LEFT, pigpio.INPUT)
self.pi.set_mode(self.RIGHT, pigpio.INPUT)
self.pi.set_pull_up_down(self.LEFT, pigpio.PUD_UP)
self.pi.set_pull_up_down(self.RIGHT, pigpio.PUD_UP)
MODE = (14, 15, 18) # Microstep Resolution GPIO Pins
RESOLUTION = {'Full': (0, 0, 0),
'Half': (1, 0, 0),
'1/4': (0, 1, 0),
'1/8': (1, 1, 0),
'1/16': (0, 0, 1),
'1/32': (1, 0, 1)}
for i in range(3):
self.pi.write(MODE[i], RESOLUTION['Full'][i])
# Set duty cycle and frequency
self.pi.set_PWM_dutycycle(self.STEP, self.CYCLE) # PWM 1/2 On 1/2 Off
self.pi.set_PWM_frequency(self.STEP, 1000) # 500 pulses per second
def btn_is_left(self):
return not bool(self.pi.read(self.LEFT))
def btn_is_right(self):
return not bool(self.pi.read(self.RIGHT))
def write_state(self, state):
with open("state.log", "w") as f:
f.write(state)
def write_distance(self, distance):
with open("distance.log", "w") as f:
f.write(str(distance))
def move_left(self, distance = 0):
self.state = "left"
self.write_state(self.state)
self.pi.write(self.RELAY, 1)
self.pi.set_PWM_dutycycle(self.STEP,self.CYCLE) # PWM 1/2 On 1/2 Off
self.pi.write(self.DIR, 1)
def move_right(self, distance = 0):
self.state = "right"
self.write_state(self.state)
self.pi.write(self.RELAY, 1)
self.pi.set_PWM_dutycycle(self.STEP, self.CYCLE) # PWM 1/2 On 1/2 Off
self.pi.write(self.DIR, 0)
def halt(self):
self.state = "halt"
self.write_state(self.state)
self.pi.write(self.RELAY, 0)
self.pi.set_PWM_dutycycle(self.STEP, 0) # PWM off
def stop(self):
self.state = "stop"
self.write_state(self.state)
self.pi.set_PWM_dutycycle(self.STEP, 0) # PWM off
self.pi.write(self.RELAY, 0)
self.pi.stop()
def wait_for_it(self, time):
init_state = self.state
was_interrrupted = False
for _ in range(int(10*time)):
if self.state != init_state:
was_interrrupted = True
break
if init_state == "left":
self.distance += 0.1*self.velocity
self.write_distance(self.distance)
elif init_state == "right":
self.distance -= 0.1*self.velocity
self.write_distance(self.distance)
sleep(0.1)
if not was_interrrupted:
self.halt()
def move_left_for(self, distance=0):
self.move_left()
time = distance/self.velocity
waiting = Process(target=self.wait_for_it, args=(time,))
waiting.start()
def move_right_for(self, distance=0):
self.move_right()
time = distance/self.velocity
waiting = Process(target=self.wait_for_it, args=(time,))
waiting.start()
def manual_control(self, showstate):
self.showstate = showstate
manual = Process(target=self.manual_control_core(), args=())
manual.start()
def manual_control_core(self):
try:
while True:
oldstate = self.state
if self.btn_is_left():
self.move_left()
self.distance += 0.1*self.velocity
self.write_distance(self.distance)
elif self.btn_is_right():
self.move_right()
self.distance -= 0.1*self.velocity
self.write_distance(self.distance)
else:
self.halt()
if oldstate != self.state and self.showstate == 1:
print(self.state)
sleep(.1)
except KeyboardInterrupt:
print("\nCtrl-C pressed. Stopping PIGPIO and exiting...")
finally:
self.stop()