0
votes

I'm trying to use proximity sensors on a Raspberry Pi2 and I want each sensor to run on a different thread, so I'm using threading module. If I only use 2 threads, everything works fine but when I try to run 3 threads, I get this error:

Exception in thread Thread-3: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 505, in run self.__target(*self.__args, **self.__kwargs) File "range_sensor.py", line 52, in measure pulse_duration = pulse_end - pulse_start UnboundLocalError: local variable 'pulse_start' referenced before assignment

Here is the code, I don't understand what is wrong

tuples = [(1, 'Bagno Cla', 'Toilet paper', 23, 24),
          (1, 'Bagno Ladispe', 'Trash', 25, 8),
          (2,'Bagno inventato', 'Soap', 16,20)]

def measure(bathroomFloor, bathroomId, item, TRIG, ECHO):
#     getting raspberry and sensors ready
    GPIO.setup(TRIG,GPIO.OUT)
    GPIO.setup(ECHO,GPIO.IN)
    GPIO.output(TRIG, False)
    print "Waiting For Sensor To Settle"
    time.sleep(2)

    T=60
    while True:     
        print "Distance Measurement In Progress"
        time.sleep(5) #sampling period    
        GPIO.output(TRIG, True) 
        time.sleep(0.00001)
        GPIO.output(TRIG, False)

        while GPIO.input(ECHO)==0:
            pulse_start = time.time()
        while GPIO.input(ECHO)==1:
            pulse_end = time.time()

        pulse_duration = pulse_end - pulse_start
        distance = pulse_duration * 17150
        distance = round(distance, 2)
        print "Measured distance in "+bathroomId+":",distance,"cm"
        print "Time of measure in "+bathroomId+":",time.strftime("%H:%M")

GPIO.cleanup()
return


# this is the part of code that launches each thread
try: #launching threads
    i = 0
    while i < len(tuples):
    t = threading.Thread(target=measure, args=tuples[i])
    t.start();
    i+=1

except:
    print "Error: unable to start thread"
1

1 Answers

1
votes

You should always try & reduce an example to the minimal working one. Then it becomes quite clear what happens:

while True
    if False: # not reached
        pulse_start = time.time()
    else:
        pulse_end = time.time()
    print pulse_end - pulse_start # undbound local error!

This has nothing to do with threads as such, but probably the GPIO's state are different due to sensor crosstalk, and thus you don't define puse_start before it is used. The usual workaround is to pre-set a value - either to something useful, or a sentinel-value, e.g. None

pulse_start = None
pulse_end = None    
while True:
   if <condition>:
      pulse_start = time.time()
   else:
      pulse_end = time.time()
   if pulse_start is not None and pulse_end is not None:
      print "length", pulse_end - pulse_start
      pulse_end = None # reset pulse_end to prevent printing out a negative length if you started with the second execution path