如何基于树莓派按钮实现摩尔斯电码输入并转换为英文?
如何基于树莓派按钮实现摩尔斯电码输入并转换为英文?
嘿,我完全懂你现在的卡点——刚把硬件连好,写了点基础代码,但摩尔斯电码的时间判断、间隔区分还有最后转英文的逻辑堆在一起就乱了对吧?别慌,咱们先把你现有代码的问题理清,再一步步补全核心逻辑。
首先,先聊聊你当前代码里的明显问题:
- 语法错误:
if button.is_pressed = False应该用双等号==做判断; - 逻辑缺失:你只处理了按键按下的时长(区分点/划),但完全没处理松开后的间隔——这可是摩尔斯电码里区分「字符内间隔(点和划之间)」「字母间隔」「单词间隔」的核心;
- 变量未定义:代码里没看到
button的初始化,还有dot_time这些时间变量也没明确赋值; - 没有转译逻辑:攒了
-和.后,没对应到英文字母的步骤。
接下来,咱们一步步把功能补全:
第一步:先把基础配置和摩尔斯字典搭好
先把必要的导入、硬件初始化、时间参数和摩尔斯字典定义好,这是后续逻辑的基础:
from gpiozero import Button import time # 摩尔斯电码时间参数(单位:秒,可根据你的按键习惯微调) dot_time = 0.15 # 点的按键时长 dash_time = 0.45 # 划的按键时长(通常是点的3倍) character_gap = 0.15 # 字符内的间隔(比如点和划之间的松开时间) letter_gap = 0.45 # 字母间的间隔(通常是点的3倍) word_gap = 1.05 # 单词间的间隔(通常是点的7倍) # 初始化按钮:这里假设你把按钮接在GPIO17引脚,根据实际接线改 button = Button(17) # 摩尔斯电码到英文字母/数字的字典 morse_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', '-----': '0', '.----': '1', '..---': '2', '...--': '3', '....-': '4', '.....': '5', '-....': '6', '--...': '7', '---..': '8', '----.': '9' }
第二步:核心逻辑实现(处理按键和间隔)
摩尔斯电码的核心是两个时间维度的判断:按键时长(点/划)、松开后的间隔时长(字符内/字母/单词)。我们需要跟踪这两种状态的时间,然后逐步攒出摩尔斯字符、英文字母、单词,最后拼成完整消息:
def morse_to_english(): full_message = "" current_word = "" current_morse_char = "" # 攒当前字母的摩尔斯码(比如".-"对应A) last_press_start = 0 # 记录按键按下的开始时间 last_release_start = 0 # 记录按键松开的开始时间 while True: if button.is_pressed: # 按钮刚被按下,先记录按下开始时间 if last_press_start == 0: last_press_start = time.time() # 处理上一次松开的间隔(如果有的话) if last_release_start != 0: release_duration = time.time() - last_release_start last_release_start = 0 # 根据松开时长判断是哪种间隔 if release_duration >= word_gap: # 单词间隔:把当前单词加入完整消息,重置当前单词 if current_word: full_message += current_word + " " current_word = "" elif release_duration >= letter_gap: # 字母间隔:把当前摩尔斯码转成字母,加入当前单词 if current_morse_char: # 用get避免未知摩尔斯码报错,返回"?" current_word += morse_dict.get(current_morse_char, "?") current_morse_char = "" # 小于letter_gap的是字符内间隔,不用处理,继续攒摩尔斯码 else: # 按钮松开,先处理按键按下的时长(判断是点还是划) if last_release_start == 0 and last_press_start != 0: press_duration = time.time() - last_press_start # 判断是点还是划 if press_duration <= dot_time: current_morse_char += "." elif press_duration <= dash_time: current_morse_char += "-" else: # 超过划的时长,视为误触,加"?"标记 current_morse_char += "?" # 重置按下时间,记录松开开始时间 last_press_start = 0 last_release_start = time.time() # 加个小休眠降低CPU占用,同时让判断更稳定 time.sleep(0.01) # 用Ctrl+C退出程序,退出前处理剩余的字符和单词 try: pass except KeyboardInterrupt: # 退出时把最后剩下的摩尔斯码和单词处理完 if current_morse_char: current_word += morse_dict.get(current_morse_char, "?") if current_word: full_message += current_word print(f"\n最终翻译结果: {full_message.strip()}") return full_message.strip() # 运行函数 if __name__ == "__main__": morse_to_english()
第三步:代码逻辑解释
- 按键按下时:先处理上一次松开的间隔(如果有的话),根据松开时长判断是单词间隔、字母间隔还是字符内间隔,执行对应的拼接逻辑;
- 按键松开时:计算刚才按下的时长,判断是点还是划,加到当前摩尔斯码字符串里;
- 退出处理:按下Ctrl+C时,把最后没处理完的摩尔斯码和单词都补全,输出最终的英文消息。
调试和优化建议
- 先测试点和划的判断:短按(≤0.15s)输出".", 长按(0.15s~0.45s)输出"-";
- 再测试字母拼接:比如按「点→松开短时间→划」,应该攒成".-",然后松开0.45s以上,就会转成"A";
- 最后测试单词拼接:比如输入"A"后,松开1.05s以上,再输入"B",就会拼成"A B";
- 时间参数可以根据你的按键习惯微调,比如把
dot_time改成0.2s,让判断更宽松。
备注:内容来源于stack exchange,提问作者Jester
相关产品推荐
相关产品推荐

