ラズパイで圧電スピーカーが思うように動作しない
Q&A
Closed
圧電スピーカーが上手く鳴らない
以下の実装で、圧電スピーカーの音が思い通りに鳴りません。
(5回に一回程度はなるので、回路ではなくコードの問題だと思います。)
Raspberry Pi 超音波測距センサー LEDライト 圧電スピーカーを組み合わせ、センサーから入力された距離によって異なる数のLEDを光らせます。そして10cm以下になると圧電スピーカーを鳴らしたいです。(またログから距離が測れていることは確認済み。)
自分で思いついた原因
- while文を一ループごとにTime.sleep(1)していることと以下が干渉?
alertor()
time.sleep(0.5)
stopAlertor()
- そもそもtime.sleep()している間はPWM信号が出力されていない?!
全コード
import RPi.GPIO as GPIO
import time
# Setting variables for ultrasonic range sensor
trigPin = 16
echoPin = 18
MAX_DISTANCE = 200
timeOut = MAX_DISTANCE*60
# Setting variables for LED
ledPins = [7, 11, 13, 15, 29]
firstRedPin = 7
secondRedPin = 11
thirdRedPin = 13
fourthRedPin = 15
greenPin = 29
# Setting variables for buzzer
buzzerPin = 38
def pulseIn(pin,level,timeOut):
t0 = time.time()
while(GPIO.input(pin) != level):
if((time.time() - t0) > timeOut*0.000001):
return 0;
t0 = time.time()
while(GPIO.input(pin) == level):
if((time.time() - t0) > timeOut*0.000001):
return 0;
pulseTime = (time.time() - t0)*1000000
return pulseTime
def getSonar():
GPIO.output(trigPin,GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(trigPin,GPIO.LOW)
pingTime = pulseIn(echoPin,GPIO.HIGH,timeOut)
distance = pingTime * 340.0 / 2.0 / 10000.0
return distance
def setup():
print ('Program is starting...')
GPIO.setmode(GPIO.BOARD)
# Sets for Ultrasonic masure
GPIO.setup(trigPin, GPIO.OUT)
GPIO.setup(echoPin, GPIO.IN)
# Sets for LED lights
for pin in ledPins:
GPIO.setup(pin, GPIO.OUT) # Set all ledPins' mode is output
GPIO.output(pin, GPIO.HIGH) # Set all ledPins to high(+3.3V) to off led
# Sets for buzzer
GPIO.setup(buzzerPin, GPIO.OUT)
global p
p = GPIO.PWM(buzzerPin, 5)
def loop():
while(True):
distance = getSonar()
print ("The distance is : %.2f cm"%(distance))
# Below LEDs
if distance > MAX_DISTANCE or 0:
for pin in ledPins:
GPIO.output(pin, GPIO.HIGH)
elif distance > 50:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.HIGH)
GPIO.output(thirdRedPin,GPIO.HIGH)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 40:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.HIGH)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 25:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 10:
print("under 10 cm")
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.LOW)
GPIO.output(greenPin,GPIO.HIGH)
# Below ringing buzzer
alertor()
time.sleep(0.5)
stopAlertor()
else:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.LOW)
GPIO.output(greenPin,GPIO.LOW)
time.sleep(1)
def alertor():
print("alertor() called")
p.start(50)
p.ChangeFrequency(220)
def stopAlertor():
print("stopAlertor() called")
p.stop()
def destroy():
GPIO.output(buzzerPin, GPIO.LOW)
for pin in ledPins:
GPIO.output(pin, GPIO.HIGH) # turn off all leds
GPIO.cleanup() # Release resource
if __name__ == '__main__':
setup()
try:
loop()
except KeyboardInterrupt:
destroy()
追記
お二方からいただいた助言、コードを元に以下のように書き直したところ、期待通りの動作をしました!入門者に温かい助言をいただけて大変嬉しかったです。ありがとうございます!
import RPi.GPIO as GPIO
import time
# Setting variables for ultrasonic range sensor
trigPin = 16
echoPin = 18
MAX_DISTANCE = 200
timeOut = MAX_DISTANCE*60
# Setting variables for LED
ledPins = [7, 11, 13, 15, 29]
firstRedPin = 7
secondRedPin = 11
thirdRedPin = 13
fourthRedPin = 15
greenPin = 29
# Setting variables for buzzer
buzzerPin = 21
def pulseIn(pin,level,timeOut):
t0 = time.time()
while(GPIO.input(pin) != level):
if((time.time() - t0) > timeOut*0.000001):
return 0;
t0 = time.time()
while(GPIO.input(pin) == level):
if((time.time() - t0) > timeOut*0.000001):
return 0;
pulseTime = (time.time() - t0)*1000000
return pulseTime
def getSonar():
GPIO.output(trigPin,GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(trigPin,GPIO.LOW)
pingTime = pulseIn(echoPin,GPIO.HIGH,timeOut)
distance = pingTime * 340.0 / 2.0 / 10000.0
return distance
def setup():
print ('Program is starting...')
GPIO.setmode(GPIO.BOARD)
# Sets for Ultrasonic masure
GPIO.setup(trigPin, GPIO.OUT)
GPIO.setup(echoPin, GPIO.IN)
# Sets for LED lights
for pin in ledPins:
GPIO.setup(pin, GPIO.OUT) # Set all ledPins' mode is output
GPIO.output(pin, GPIO.HIGH) # Set all ledPins to high(+3.3V) to off led
# Sets for buzzer
GPIO.setup(buzzerPin, GPIO.OUT, initial=GPIO.LOW)
global p
p = GPIO.PWM(buzzerPin, 220)
def loop():
while(True):
distance = getSonar()
print ("The distance is : %.2f cm"%(distance))
# Below LEDs
if distance > MAX_DISTANCE or 0:
for pin in ledPins:
GPIO.output(pin, GPIO.HIGH)
elif distance > 80:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.HIGH)
GPIO.output(thirdRedPin,GPIO.HIGH)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 60:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.HIGH)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 40:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.HIGH)
GPIO.output(greenPin,GPIO.HIGH)
elif distance > 20:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.LOW)
GPIO.output(greenPin,GPIO.HIGH)
else:
GPIO.output(firstRedPin,GPIO.LOW)
GPIO.output(secondRedPin,GPIO.LOW)
GPIO.output(thirdRedPin,GPIO.LOW)
GPIO.output(fourthRedPin,GPIO.LOW)
GPIO.output(greenPin,GPIO.LOW)
alertor()
time.sleep(0.05)
stopAlertor()
time.sleep(0.5)
def alertor():
print("alertor() called")
p.start(50)
def stopAlertor():
print("stopAlertor() called")
p.stop()
def destroy():
GPIO.output(buzzerPin, GPIO.LOW)
for pin in ledPins:
GPIO.output(pin, GPIO.HIGH) # turn off all leds
GPIO.cleanup() # Release resource
if __name__ == '__main__':
setup()
try:
loop()
except KeyboardInterrupt:
destroy()