I'm creating a simple script that outputs a text input to morse with an LED and a transducer via the GPIO pins on a Raspberry Pi 4 Model B. I tried to add input functionality with buttons that can change the frequency of the transducer while the program is running, however I ran into some problems doing this as the frequency only changes for the first dot or dash of each letter then defaults to the initial value
import RPi.GPIO as GPIO
from time import sleep
LED_GPIO = 17
BUZZER_GPIO = 14
BUTTON1_GPIO = 26
BUTTON2_GPIO = 13
freq = 1500
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_GPIO, GPIO.OUT)
GPIO.setup(BUZZER_GPIO,GPIO.OUT)
GPIO.setup(BUTTON1_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON2_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
MORSE_CODE_DICT = { 'A':'.-', 'B':'-...',
'C':'-.-.', 'D':'-..', 'E':'.',
'F':'..-.', 'G':'--.', 'H':'....',
'I':'..', 'J':'.---', 'K':'-.-',
'L':'.-..', 'M':'--', 'N':'-.',
'O':'---', 'P':'.--.', 'Q':'--.-',
'R':'.-.', 'S':'...', 'T':'-',
'U':'..-', 'V':'...-', 'W':'.--',
'X':'-..-', 'Y':'-.--', 'Z':'--..',
'1':'.----', '2':'..---', '3':'...--',
'4':'....-', '5':'.....', '6':'-....',
'7':'--...', '8':'---..', '9':'----.',
'0':'-----', ', ':'--..--', '.':'.-.-.-',
'?':'..--..', '/':'-..-.', '-':'-....-',
'(':'-.--.', ')':'-.--.-'}
def increase_freq(channel):
global freq
print("Incresaing frequency")
freq+=100
print(freq)
def decrease_freq(channel):
global freq
print("Decresaing frequency")
freq-=100
print(freq)
def set_led(state):
if state:
GPIO.output(LED_GPIO, True)
else:
GPIO.output(LED_GPIO, False)
def blink_morse(morse):
for char in morse:
set_led(True)
print(freq)
buzzer = GPIO.PWM(BUZZER_GPIO, freq)
buzzer.start(80)
if char == ".":
sleep(0.2)
else:
sleep(1)
set_led(False)
buzzer.stop()
sleep(0.2)
GPIO.add_event_detect(BUTTON1_GPIO, GPIO.FALLING, callback=increase_freq, bouncetime=500)
GPIO.add_event_detect(BUTTON2_GPIO, GPIO.FALLING, callback=decrease_freq, bouncetime=500)
while True:
try:
message=input("Enter message:\n>")
if message=="q":
break
message=message.upper()
for letter in message:
if letter == " ":
sleep(2)
else:
print(letter)
morse=MORSE_CODE_DICT[letter]
print(morse)
blink_morse(morse)
sleep(1)
finally:
pass
I think the problem lies in this function
def blink_morse(morse):
for char in morse:
set_led(True)
print(freq)
buzzer = GPIO.PWM(BUZZER_GPIO, freq)
buzzer.start(80)
if char == ".":
sleep(0.2)
else:
sleep(1)
set_led(False)
buzzer.stop()
sleep(0.2)
I redefine the buzzer every dot or dash so that every loop it is "checking" for an update in the frequency, however for example, if the letter in question is "s" which translates to "dot dot dot" the updated frequency will only sound for the first "dot" and then default to the original value. When it goes to the next letter it will also sound the updated frequency for the first dot or dash but then default back again.
I've done some checks and I'm sure that each time the
buzzer = GPIO.PWM(BUZZER_GPIO, freq)
line runs, the frequency is what I want it to be, but for some reason it only comes out correct in sound for the first dot or dash of each letter.
Anyone know why this is?