twigg
twigg

Reputation: 3993

run two functions with loops in python

I'm running a cubieboard and accessing the GPIO pins. one GPIO pin has an output to an LED which turns it on and off every 1000ms when running this function:

def testRunning():
    while 1:
        wiringpi2.digitalWrite(pin3,HIGH)
        wiringpi2.delay(1000)
        wiringpi2.digitalWrite(pin3,LOW)
        wiringpi2.delay(1000)

next I have a function to listen for a button press on another GPIO pin and when this is set to high (1) it causes another red LED to flash 20 times (I'm not sure if this is the best way to go about it):

def stopButton():
    while 1:
        wiringpi2.pinMode(52,0) 
        stopBut = wiringpi2.digitalRead(52) 
        print (stopBut) # this is just for debugging
        wiringpi2.delay(500)
        if (stopBut == 1):
            break

    redBlink = int(0)
    while (redBlink < int(20)):
        wiringpi2.digitalWrite(pin2,HIGH) 
        wiringpi2.delay(50)
        wiringpi2.digitalWrite(pin2,LOW) 
        wiringpi2.delay(50)
        redBlink += int(1)
        print redBlink

Both of these work just as excepted when run separately.

Now I want to run both of these at the same time so the testRunning LED is blinking until the stopButton is pressed and the red LED blinks and the program stops. I've tried this:

from multiprocessing import Process
if __name__ == '__main__':
    Process(target = stopButton()).start()
    Process(target = testRunning()).start()

When running this code the stopButton is executed and sits waiting for the button press as expected but the testRunning code is not executed until the stoButton code has finished running (IE the button is pressed the LED is looped 20times and that function exits).

Upvotes: 1

Views: 1482

Answers (2)

Jeff Ferland
Jeff Ferland

Reputation: 18292

You need to use some sort of parallel processing for this to work as well as create a way to interrupt your running thread.

Read up on threading and create and start your two Thread objects, one for each method. The overall approach I'd take is to read a boolean in your testRunning() method and to write to it in your stopButton() method.

if not keepRunning:
    return

and insert that just before each of your wiringpi2.digitalWrite() calls. You can be a little more advanced by using notify() with a timeout to cause the stopButton() to end the testRunning() method instantly instead of on the delay.

Last tricky part: remember to join() your threads after starting them.

import threading
import sys

checkRunState = threading.Condition()
keepRunning = True

def stopButton():
    # since I didn't set up objects, use a global
    global keepRunning
    # block until the enter key is pressed
    sys.stdin.readline()
    keepRunning = False
    # acquire because that must be done before making an action
    # then notify anything that needs to know if we're still supposed
    # to keep running
    checkRunState.acquire()
    checkRunState.notifyAll()
    checkRunState.release()
    print "HAMMER TIME"

def blinky():
    global keepRunning
    checkRunState.acquire()
    redBlink = int(0)
    while (redBlink < int(20)):
        redBlink += int(1)
        # instead of a sleep(), use this for timing since it will
        # be woken up right away if the stop condition changes
        checkRunState.wait(.1)
        if not keepRunning:
            checkRunState.release()
            return
        print "blinky!"
    checkRunState.release()

stopper = threading.Thread(target=stopButton)
stopper.daemon = True
blinker = threading.Thread(target=blinky)

blinker.start()
stopper.start()

blinker.join()
# stopper() never unblocks. Setting it as a daemon thread
# means that python won't keep running because of it and we
# shouldn't try to join it

Upvotes: 1

Max Noel
Max Noel

Reputation: 8910

In Python, you can think of () as the call operator. Process(target = stopButton()).start() calls stopButton(), waits for it to complete, then passes its return value (None) to the Process constructor.

Use Process(target = stopButton).start() instead.

Upvotes: 1

Related Questions