You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于树莓派按钮实现摩尔斯电码输入并转换为英文?

如何基于树莓派按钮实现摩尔斯电码输入并转换为英文?

嘿,我完全懂你现在的卡点——刚把硬件连好,写了点基础代码,但摩尔斯电码的时间判断、间隔区分还有最后转英文的逻辑堆在一起就乱了对吧?别慌,咱们先把你现有代码的问题理清,再一步步补全核心逻辑。

首先,先聊聊你当前代码里的明显问题:

  1. 语法错误:if button.is_pressed = False 应该用双等号 == 做判断;
  2. 逻辑缺失:你只处理了按键按下的时长(区分点/划),但完全没处理松开后的间隔——这可是摩尔斯电码里区分「字符内间隔(点和划之间)」「字母间隔」「单词间隔」的核心;
  3. 变量未定义:代码里没看到 button 的初始化,还有 dot_time 这些时间变量也没明确赋值;
  4. 没有转译逻辑:攒了 - 和 . 后,没对应到英文字母的步骤。

接下来,咱们一步步把功能补全:

第一步:先把基础配置和摩尔斯字典搭好

先把必要的导入、硬件初始化、时间参数和摩尔斯字典定义好,这是后续逻辑的基础:

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()

第三步:代码逻辑解释

  1. 按键按下时:先处理上一次松开的间隔(如果有的话),根据松开时长判断是单词间隔、字母间隔还是字符内间隔,执行对应的拼接逻辑;
  2. 按键松开时:计算刚才按下的时长,判断是点还是划,加到当前摩尔斯码字符串里;
  3. 退出处理:按下Ctrl+C时,把最后没处理完的摩尔斯码和单词都补全,输出最终的英文消息。

调试和优化建议

  • 先测试点和划的判断:短按(≤0.15s)输出".", 长按(0.15s~0.45s)输出"-";
  • 再测试字母拼接:比如按「点→松开短时间→划」,应该攒成".-",然后松开0.45s以上,就会转成"A";
  • 最后测试单词拼接:比如输入"A"后,松开1.05s以上,再输入"B",就会拼成"A B";
  • 时间参数可以根据你的按键习惯微调,比如把dot_time改成0.2s,让判断更宽松。

备注:内容来源于stack exchange,提问作者Jester

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 13:45:29