Reputation: 1033
First of all, I learned Python on my own from online tutorials and (mostly) learning by doing, so I might did some strange things in my code. :) So, I am working om my first bigger project with Raspberry Pi, and for that I need codes running parallel. I wrote this part of my code for managing a simple D-pad:
Problematic code
import threading
import time
import pigpio
# input from the D-pad goes to these pins
BUTT_UP = 12
BUTT_LEFT = 16
BUTT_CENTER = 25
BUTT_RIGHT = 20
BUTT_DOWN = 21
class dpad_monitoring(threading.Thread):
'''thread for monitoring the D-Pad'''
def __init__(self, thread_ID, butt_up, butt_left, butt_center, butt_right, butt_down, res = 10.00):
threading.Thread.__init__(self)
self.running = True
self.thread_ID = thread_ID
# number of checks per sec
self.res = res
# key pins
self._pins = [butt_up, butt_left, butt_center, butt_right, butt_down]
#key monitor
self.last_pressed = 0
'''key numbers:
UP LEFT CENTER RIGHT DOWN
1 2 3 4 5 '''
# setting up GPIO
self.pi = pigpio.pi()
for i in range(0, len(self._pins)):
self.pi.set_mode(self._pins[i], pigpio.INPUT)
self.pi.set_pull_up_down(self._pins[i], pigpio.PUD_UP)
def stop(self):
'''stopping the thread cleanly'''
self.pi.stop()
self.running = False
def run(self):
'''checks which button is pressed as many times per sec as specified
in the res variable in init. If any of them is pressed, it suspends itself
until self.last_pressed is set to 0 again by main()'''
while self.running:
states = []
for i in range(0, len(self._pins)):
state = not self.pi.read(self._pins[i]) # pi.read returns 1L if the pin is high,
states.append(state) # what means the button is not pressed, 0L when pressed
for i in range(0, len(states)):
if states[i]:
self.last_pressed = i+1
'''UGLY AS SHIT but works now, will change to locks after the code works'''
if self.last_pressed != 0 :
while self.last_pressed != 0:
pass
else:
time.sleep(1/self.res)
print 'im groot' # for debugging
def main():
print 'ok' #debug
dpad = dpad_monitoring(0, BUTT_UP, BUTT_LEFT, BUTT_CENTER, BUTT_RIGHT, BUTT_DOWN)
dpad.run()
print 'okey' #debug again
while i != 3:
i = dpad.last_pressed
if i == 1:
print 'UP'
dpad.last_pressed = 0
if i == 2:
print 'LEFT'
dpad.last_pressed = 0
if i == 4:
print 'RIGHT'
dpad.last_pressed = 0
if i == 5:
print 'DOWN'
dpad.last_pressed = 0
print 'CENTER, stopping'
time.sleep(0.5)
dpad.stop()
if __name__ == '__main__':
main()
The problem is when I run the code, I get this:
ok
im groot
im groot
im groot
im groot
im groot
im groot
... (endless groot)
So it seems the code gets stuck at dpad.run(). Now AFAIK, the main point of threading is that the code continues after calling the run() function and can interact with the threading object, so I don't know what the he'll is going on. Could you, all experts, help me out please? (Since the code after dpad.run() never ran, I don't know if it works, it may be all garbage. :P
The strange thing is that this simple test code works with no problem:
Cool code:
import threading
import time
class thread1(threading.Thread):
def __init__(self, threadID, start_from):
threading.Thread.__init__(self)
self.threadID = threadID
self.i = start_from
self.running = True
def run(self):
while self.running:
time.sleep(1)
self.i = self.i+1
def stop(self):
self.running = False
class thread2(threading.Thread):
def __init__(self, threadID, start_from):
threading.Thread.__init__(self)
self.threadID = threadID
self.i = start_from
self.running = True
def run(self):
while self.running:
time.sleep(0.5)
self.i = self.i+10
def stop(self):
self.running = False
thread1 = thread1(1, 10)
thread2 = thread2(2, 1)
thread1.start()
thread2.start()
for j in range(30):
print thread1.i, thread2.i
time.sleep(0.3)
thread1.stop()
thread2.stop()
The output is
10 1
10 1
10 11
10 11
11 21
11 31
11 31
12 41
12 41
12 51
13 61
13 61
13 71
13 71
14 81
14 91
14 91
15 101
15 101
15 111
16 121
16 121
16 131
16 131
17 141
17 151
17 151
18 161
18 161
18 171
------------------
(program exited with code: 0)
Press return to continue
So there I got the main thread plus the two other run parallel, unlikely to the previous code. What the he'll is going on?
Upvotes: 0
Views: 110
Reputation: 1506
Instead of
dpad.run()
do
dpad.start()
When calling run() directly you are skipping the whole threading functionality and using it as a regular class.
Upvotes: 2