0

Here's the code, it communicates with Sonic Pi, don't know if that matters:

  import RPi.GPIO as GPIO
import time
import signal
import sys
from pythonosc import udp_client
from pythonosc import osc_message_builder
#from scipy.interpolate import interpld

# use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BCM)

# set GPIO Pins
pinTrigger = 18
pinEcho = 24
sender = udp_client.SimpleUDPClient('127.0.0.1', 4559)

def close(signal, frame):
    print("\nTurning off ultrasonic distance detection...\n")
    GPIO.cleanup() 
    sys.exit(0)

lastpitch1=60
lastpitch2=64
lastpitch3=67
lastpitch4=72
lastpitch5=69
pitch1 =60
pitch2 =64
pitch3 =67
pitch4 =72
pitch5 =69

signal.signal(signal.SIGINT, close)

# set GPIO input and output channels
GPIO.setup(pinTrigger, GPIO.OUT)
GPIO.setup(pinEcho, GPIO.IN)


while True:
    # set Trigger to HIGH
    GPIO.output(pinTrigger, True)
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(pinTrigger, False)

    startTime = time.time()
    stopTime = time.time()

    abortTime = time.time() + 0.5

    while 0 == GPIO.input(pinEcho):
        startTime = time.time()
        if startTime > abortTime:
            exit

    abortTime = time.time() + 0.5

    while 1 == GPIO.input(pinEcho):
        stopTime = time.time()
        if stopTime > abortTime:
            exit

    # time difference between start and arrival
    TimeElapsed = stopTime - startTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    distance = (TimeElapsed * 34300) / 2

    print ("Distance: %.1f cm" % distance)
    if distance < 10:
            pitch1=lastpitch1
            pitch2=lastpitch2
            pitch3=lastpitch3
            pitch4=lastpitch4
            pitch5=lastpitch5
    elif 10 < distance < 50:
            pitch1 = 60
            pitch2 = 64
            pitch3 = 67
            pitch4 = 72
            pitch5 = 69
            lastpitch1=pitch1
            lastpitch2=pitch2
            lastpitch3=pitch3
            lastpitch4=pitch4
            lastpitch5=pitch5
    elif 51 < distance < 100:
            pitch1 = 65
            pitch2 = 69
            pitch3 = 72
            pitch4 = 75
            pitch5 = 74
            lastpitch1=pitch1
            lastpitch2=pitch2
            lastpitch3=pitch3
            lastpitch4=pitch4
            lastpitch5=pitch5
    elif 101 < distance < 150:
            pitch1 = 67
            pitch2 = 71
            pitch3 = 74
            pitch4 = 65
            pitch5 = 76
            lastpitch1=pitch1
            lastpitch2=pitch2
            lastpitch3=pitch3
            lastpitch4=pitch4
            lastpitch5=pitch5
    elif 150 < distance:
            pitch1 = lastpitch1
            pitch2 = lastpitch2
            pitch3 = lastpitch3
            pitch4 = lastpitch4
            pitch5 = lastpitch5
    sender.send_message('/note_a', pitch1-24)
    sender.send_message('/note_b', pitch2-24)
    sender.send_message('/note_c', pitch3-24)
    sender.send_message('/note_d', pitch4-24)
    sender.send_message('/note_e', pitch5-24)
    #print ("Pitch: " + pitch1 + ", Pitch2: " + pitch2 + ", Pitch3: " + pitch3)
    time.sleep(.0001)

1 Answers1

1

This code just does not work on the Raspberry Pi. It was probably copied from Arduino code with no understanding of the difference between the two systems.

Arduino: single user, single running program.

Pi: multi-user, multi-tasking operating system.

# save start time
while 0 == GPIO.input(pinEcho):
    startTime = time.time()

# save time of arrival
while 1 == GPIO.input(pinEcho):
    stopTime = time.time()

On the Pi it is likely that the code will eventually get stuck in one of those while loops.

The most likely point is the first. The freeze scenario is the program sends the trigger and then gets scheduled out. By the time the program is rescheduled the trigger pulse has been completed and the echo has been received.

You need to timeout each of those while loops, either with a timeout or just execute them a maximum number of times.

abortTime = time.time() + 0.5

while 0 == GPIO.input(pinEcho):
     startTime = time.time()
     if startTime > abortTime:
        exit

abortTime = time.time() + 0.5

while 1 == GPIO.input(pinEcho):
    stopTime = time.time()
    if stopTime > abortTime:
        exit
joan
  • 71,852
  • 5
  • 76
  • 108