当前位置: 首页 > news >正文

基于Raspberry Pi Pico的超低功耗智能语音时钟DIY全攻略

1. 项目概述与核心思路

最近在捣鼓一个有点意思的小玩意儿:一个会说话的智能时钟。市面上能整点报时的音乐钟不少,但声音要么是固定的“布谷鸟”,要么是单调的“嘀嘀”声,想换成自己喜欢的音效,比如万圣节的鬼叫或者一段有趣的语音,基本没戏。这让我萌生了自己动手做一个的念头,核心诉求就两点:声音能自定义,以及用电池供电,续航要足够长,最好能挂在墙上一年都不用操心换电池。

要实现这个目标,微控制器是大脑,但选型是关键。常见的Arduino Uno功耗控制不够精细,ESP8266/ESP32的Wi-Fi功能在这里完全是累赘,徒增功耗。最终我锁定了Raspberry Pi Pico。理由很直接:第一,它支持USB MSC(大容量存储设备)模式,首次烧录固件就像往U盘里拖文件一样简单,无需安装任何专用软件,对新手极其友好。第二,它自带2MB的Flash,足够存储几十段短语音,省去了外挂存储芯片的麻烦和成本。第三,它的核心RP2040芯片在深度睡眠模式下的功耗理论值很低,为构建超低功耗系统提供了可能。

然而,理想很丰满,现实一测就骨感。实测发现,Pico即使进入深度睡眠(Deep Sleep),电流仍有1.6mA左右。对于两节AA电池(约2000mAh容量)来说,这意味著理论续航只有大约50天,离“用一年”的目标相差甚远。问题的根源在于,深度睡眠只是让CPU和大部分外设休眠,但芯片的电源域并未彻底关闭,仍有静态电流消耗。

因此,本项目的核心设计思路发生了关键转变:放弃依赖芯片自身的低功耗模式,转而设计一个外部“物理断电”电路。我们用一个石英钟机芯(带整点触发信号)作为“闹钟”和计时显示,用Pico专司语音播放。当整点到来时,钟机芯的触发信号瞬间唤醒整个系统,Pico上电、播放语音、然后立即命令外部电路将自己完全断电,等待下一个整点。通过这种方式,系统99.9%以上的时间都处于“零功耗”的彻底关机状态,从而将平均电流拉低到微安级别,实现超长续航。

2. 核心硬件设计与选型解析

整个系统的硬件可以划分为四个功能模块:主控与存储、电源管理与唤醒、音频输出、环境光检测。每一部分的选择都直接关系到最终的功能、功耗和可靠性。

2.1 主控芯片:Raspberry Pi Pico的深度考量

选择Raspberry Pi Pico,除了开头提到的三点,还有几个深层原因。RP2040的双核ARM Cortex-M0+处理器,应付音频解码绰绰有余,为后期功能扩展(如更复杂的音频处理)留有余地。其丰富的GPIO和ADC资源,为我们连接光传感器、控制电源电路提供了便利。最重要的是,其开放的生态同时支持MicroPython/CircuitPythonC/C++ SDK两种开发方式,这让我们可以针对“易用性”和“极致性能”两个维度,做出不同的工程实现,这也是本项目的一大亮点。

注意:Pico有多个版本,务必选择基础版(Raspberry Pi Pico),而非Pico W。Pico W集成的Wi-Fi/蓝牙模块会显著增加静态功耗,且在本项目中毫无用处,反而会成为功耗黑洞。

2.2 心脏与闹钟:石英钟机芯(带触发功能)

这是项目的“时钟”和“唤醒源”。我们需要的不是普通的石英机芯,而是必须带有“整点触发信号输出”的型号。通常,这类机芯内部有一个机械触点或电子开关,每当分针走到12点位置(即整点)时,会短暂地闭合(或输出一个脉冲)大约1-2秒。

  • 工作原理:这个短暂的闭合信号,就是我们整个系统的“起床铃”。它将用于触发后续的电源管理电路。
  • 选购要点:务必确认是“整点触发”(Once per hour at o‘clock),而不是“每秒触发”或“每半小时间隔触发”。输出类型一般是两根引线(常开触点),触发时短路。

2.3 电源管理电路:实现“物理断电”的关键

这是本项目低功耗设计的精髓所在,是一个巧妙的“自锁断电”电路,核心元件是一个N沟道MOSFET(如2N7000)。

电路原理与工作流程:

  1. 常态(关机):系统由两节AA电池(约3V)供电。MOSFET的栅极(G)通过一个上拉电阻(例如10MΩ)连接到电池正极(V+),因此栅极为高电平,MOSFET导通。MOSFET的漏极(D)连接到Pico的3V3_EN引脚,源极(S)接地。当MOSFET导通时,3V3_EN被拉低到地,这将禁用Pico板载的3.3V稳压器,导致Pico完全断电,电流消耗几乎为零(仅剩MOSFET和电阻的微小漏电流,约几十微安)。

  2. 唤醒(上电):当整点到来,钟机芯的触点闭合,将MOSFET的栅极瞬间对地短路。栅极电压被拉低,MOSFET关闭。3V3_EN引脚的上拉电阻(在Pico板载)使其变为高电平,Pico的3.3V稳压器使能,Pico开始上电启动。

  3. 自保持(运行):Pico启动后,必须立即(在main()boot.py的最开始)将一个GPIO(例如GPIO2)设置为输出低电平。这个GPIO通过一个二极管连接到MOSFET的栅极。当该GPIO为低电平时,它会将栅极电压钳位在低电平,即使钟机芯的触点已经断开(通常1-2秒后),MOSFET也会因为栅极为低而保持关闭状态,从而维持Pico的上电状态。

  4. 任务完成与关机:Pico播放完预设的语音文件后,将那个关键的GPIO(GPIO2)设置为高电平输出或高阻态。此时,栅极通过10MΩ的上拉电阻重新缓慢充电至高电平。一旦栅极电压超过MOSFET的开启阈值,MOSFET再次导通,将3V3_EN拉低,Pico的稳压器关闭,系统回到第1步的完全断电状态,等待下一个整点。

  • 电容的作用:在MOSFET栅极对地之间,需要并联一个电容(例如1µF)。这个电容有两个作用:一是与上拉电阻构成RC电路,决定栅极电压上升的速度,从而控制“播放完成后到断电”的延迟时间,确保Pico有足够时间执行完关机指令;二是起到滤波作用,防止因触点抖动或干扰导致误触发。

2.4 音频放大电路:从数字信号到声音

Pico通过PWM(脉冲宽度调制)在一个GPIO引脚上输出音频数字信号。这个信号电压低、驱动能力弱,无法直接推动扬声器。因此需要一个简单的放大电路。

我们采用经典的单管共发射极放大电路,使用一个NPN三极管(如2N2222A)。

  • PWM输出端:先经过一个由电阻和电容组成的低通滤波器(例如1kΩ电阻串联,对地接一个0.1µF电容)。这个滤波器至关重要,它能滤除PWM载波的高频噪声(通常是几十到几百kHz),只留下我们需要的音频信号(20Hz-20kHz),使声音更纯净,避免刺耳的嘶嘶声。
  • 放大环节:滤波后的音频信号通过一个耦合电容(隔直)送入三极管的基极,进行电流放大。放大后的信号从集电极输出,驱动一个8Ω、0.25W的小型扬声器。
  • 偏置电路:基极需要合适的偏置电阻,使三极管工作在放大区,避免信号失真。

2.5 环境光检测:避免深夜扰民

为了实现“只在白天播报”的礼貌功能,我们添加了一个光敏传感器(如TEPT5700)。它是一个对可见光敏感的光电二极管。

  • 连接方式:将其与一个固定电阻(如10kΩ)组成分压电路,连接至Pico的一个ADC(模数转换)引脚。
  • 工作原理:光照越强,光电二极管内阻越小,ADC读取到的电压值越高。Pico上电后,在决定播放前,先读取这个ADC值。如果电压低于设定的阈值(对应黑暗环境),则跳过播放,直接进入关机流程。
  • 校准:阈值需要在实际安装环境中进行校准。可以在傍晚天色渐暗时,通过串口打印出ADC读数,确定一个合适的“白天/黑夜”分界值。

3. 两种软件方案:CircuitPython 与 C/C++ SDK 的抉择

本项目提供了两种固件实现,分别基于CircuitPython和C/C++ SDK,它们代表了嵌入式开发中“开发效率”与“运行效率”的两个极端。

3.1 CircuitPython 版本:极致的易用性与灵活性

核心优势:文件系统即存储,拖拽即更新。CircuitPython(CP)将Pico的Flash呈现为一个USB可移动磁盘(U盘)。语音文件可以直接以MP3格式存放在这个磁盘里。程序代码(code.py)也以文本文件形式存在,可以直接修改。

实现流程:

  1. 启动:Pico上电,CP运行时启动(此过程需要约1-2秒)。
  2. 初始化:在code.py中,立即将控制电源的GPIO(如GPIO2)设置为输出低电平,以维持供电。然后初始化PWM音频输出模块(audiopwmio)和MP3解码模块(audiomp3)。
  3. 逻辑判断:读取光传感器ADC值。若为黑夜,则直接跳至第5步。
  4. 播放与索引管理:从文件系统中读取一个索引文件(如index.txt),里面记录着下一个要播放的MP3文件名。播放该文件。播放完成后,更新index.txt中的文件名(指向下一个文件),实现循环或顺序播放。
  5. 关机:将GPIO2设置为高电平,然后执行microcontroller.reset()或直接进入一个空循环,等待外部电源电路断电。注意:在断电前,必须确保文件操作(如更新索引)已完全完成并同步。

优点:

  • 无需编译:修改代码或更换语音文件,只需用文本编辑器改code.py,或向U盘拖入新的MP3文件。
  • 开发调试便捷:连接USB后,REPL(交互式命令行)即时可用,可以随时测试传感器、播放音频。
  • 存储效率高:MP3格式压缩率高,同样大小的Flash可以存储比WAV多10倍时长的音频。

缺点与注意事项:

  • 启动速度慢:CP运行时加载需要时间,导致从触发到开始播放有1秒以上的延迟。对于整点报时,可能听到“咔哒”触发声后要等一会儿才有语音,体验上有割裂感。
  • 功耗相对较高:CP解释器本身运行需要一定资源,相比纯C程序,完成相同任务功耗稍高(但在本场景中,由于播放后立即断电,此差异影响不大)。
  • 文件系统磨损:频繁写入同一个文件(如index.txt)可能影响Flash寿命。需要精心设计索引更新逻辑,例如仅在索引循环一轮后才写入一次,或者使用多个文件轮流记录。

3.2 C/C++ SDK 版本:极致的性能与功耗控制

核心优势:裸机运行,瞬间启动,精细控制。直接使用Raspberry Pi官方的Pico C/C++ SDK进行开发,代码编译后直接运行在硬件上,没有中间解释器。

实现流程:

  1. 启动:触发上电后,芯片从Flash直接加载程序,在毫秒级内即可进入main()函数。
  2. 立即锁存电源:在main()函数的第一条指令,就设置GPIO2为输出低电平,这个操作几乎在芯片供电稳定的瞬间完成,可靠性极高。
  3. 音频播放:音频数据需要预先处理。将WAV格式文件(必须是16位、单声道、44100Hz采样率)通过工具(如xxd或自定义脚本)转换成C语言数组,直接编译进程序二进制文件中。播放时,使用一个高优先级的定时器中断,精确控制PWM占空比,将数组中的音频数据“流式”输出。
  4. 关机:播放完毕,设置GPIO2为高电平。由于是裸机程序,此时可以直接调用__breakpoint()或进入一个极低功耗的循环(__wfi()),等待断电。代码控制力极强。

优点:

  • 启动极快:触发后几乎立即播放,用户体验连贯。
  • 功耗极致:对芯片和外设的控制粒度最细,可以关闭所有不需要的时钟和外围设备,实现理论上最低的运行功耗。
  • 性能强大:中断驱动保证了音频播放的流畅性,无卡顿。

缺点与注意事项:

  • 开发门槛高:需要配置C/C++开发环境(如VS Code + CMake),熟悉SDK API。
  • 更新语音困难:语音数据硬编码在程序里,要更换声音必须重新编译、下载整个固件,非常不便。
  • 存储效率低:使用未压缩的WAV格式,占用空间大,存储的音频总时长有限。

实操心得:方案选择建议对于初学者、热衷于自定义声音和快速迭代的玩家,强烈推荐CircuitPython版本。它的易用性带来的快乐远超那一点启动延迟。对于追求极致响应速度、固定音效、并希望作为长期稳定产品使用的场景,C/C++ SDK版本是更专业的选择。我个人在原型机阶段使用CircuitPython快速验证功能,在最终定型时则迁移到了C++ SDK以实现最佳性能。

4. 详细实现步骤与核心代码解析

4.1 硬件组装与焊接要点

  1. PCB制作或万用板搭建:项目提供了单面PCB设计文件,可以用热转印或感光法自制。如果只是做一两个,用洞洞板(万用板)搭建更灵活。布局时,将电源管理部分(MOSFET、电阻电容)尽量靠近Pico的3V3_EN和电池输入,减少干扰。
  2. Pico的连接:建议使用排母和排针,将Pico以插拔方式连接,方便调试和更换。务必确认3V3_ENVSYS(电池正极输入)、GND的连接正确。
  3. 光传感器安装:TEPT5700具有方向性,凸面是感光面。安装时确保其能感受到环境光,而不是被内部元件或外壳遮挡。可以用热缩管或黑色胶带包裹其侧面,防止侧向漏光干扰判断。
  4. 扬声器连接:注意极性,虽然对于小扬声器影响不大,但按正负连接更规范。将扬声器固定在机壳内适当位置,有助于提升音量和音质。

4.2 CircuitPython 核心代码剖析 (code.py)

import board import digitalio import analogio import audiomp3 import audiopwmio import time import microcontroller # 1. 电源保持引脚 - 上电后必须立刻设置为低电平 keep_alive = digitalio.DigitalInOut(board.GP2) keep_alive.direction = digitalio.Direction.OUTPUT keep_alive.value = False # 关键!拉低以维持供电 # 2. 光传感器 light_sensor = analogio.AnalogIn(board.GP26) LIGHT_THRESHOLD = 15000 # 需根据实际环境校准,值越小代表光越暗 # 3. 检查是否为黑夜 def is_night(): # 读取多次取平均值,减少波动 readings = [light_sensor.value for _ in range(10)] avg_light = sum(readings) / len(readings) print(f"Light sensor value: {avg_light}") return avg_light < LIGHT_THRESHOLD # 4. 音频播放设置 audio = audiopwmio.PWMAudioOut(board.GP0) # PWM音频输出引脚 # 5. 文件索引管理 INDEX_FILE = "index.txt" SOUND_FILES = ["hour1.mp3", "hour2.mp3", "hour3.mp3", "hour4.mp3"] # 声音文件列表 def get_next_sound_index(): try: with open(INDEX_FILE, "r") as f: idx = int(f.read().strip()) except (OSError, ValueError): idx = 0 # 文件不存在或内容无效,从第一个开始 return idx def save_next_sound_index(idx): next_idx = (idx + 1) % len(SOUND_FILES) # 循环播放 with open(INDEX_FILE, "w") as f: f.write(str(next_idx)) print(f"Next index saved: {next_idx}") # 6. 主逻辑 def main(): print("System powered on!") # 如果是黑夜,不播放,直接准备关机 if is_night(): print("It's night time. Skipping playback.") # 可以在这里添加一个简短的“静音”提示音,或者直接跳过 # play_silent_beep() else: # 获取并播放当前索引的声音 current_idx = get_next_sound_index() sound_file = SOUND_FILES[current_idx] print(f"Playing: {sound_file}") try: with open(sound_file, "rb") as f: decoder = audiomp3.MP3Decoder(f) audio.play(decoder) while audio.playing: time.sleep(0.1) # 等待播放完成 except OSError as e: print(f"Error playing file: {e}") # 播放完成,更新索引 save_next_sound_index(current_idx) print("Playback finished. Powering down...") # 7. 准备断电:将保持引脚置高,然后等待一小段时间确保状态稳定 keep_alive.value = True time.sleep(0.1) # 短暂延时,确保电平稳定 # 此时,外部电路的电容器开始充电,稍后MOSFET导通,系统断电 # 程序执行到此,等待复位或断电。也可以进入一个空循环。 while True: pass # 或使用 microcontroller.reset() # 运行主程序 if __name__ == "__main__": main()

4.3 C/C++ SDK 核心逻辑与代码片段

C++版本的核心在于中断驱动的PWM音频播放和极简的主循环。

关键步骤:

  1. 项目配置:使用CMake构建系统,确保链接了pico_stdlib,hardware_pwm,hardware_irq等必要的库。
  2. 音频数据准备:使用ffmpeg将声音文件转换为指定格式的WAV,然后用Python脚本或xxd -i命令将其转换为C数组(如const uint16_t audio_data[] = {...};)。
  3. 电源锁存:在main()函数入口,立即配置GPIO2为输出低电平。
  4. PWM音频初始化:配置一个PWM切片(Slice)工作在音频采样率(如44100Hz)下,并将其关联到指定的GPIO引脚。
  5. 定时器中断:设置一个高精度定时器,以音频采样率为周期触发中断。在中断服务程序(ISR)中,从audio_data数组中读取下一个样本值,更新PWM的比较捕获寄存器,从而输出对应的电压波形。
  6. 播放控制:主循环中,启动定时器中断,并等待一个标志位(表示音频播放完成)。播放完成后,设置GPIO2为高电平,并进入低功耗等待状态。

简化的主函数框架:

#include "pico/stdlib.h" #include "hardware/pwm.h" #include "hardware/irq.h" #define POWER_HOLD_PIN 2 #define AUDIO_PWM_PIN 0 // 外部定义的音频数据数组和长度 extern const uint16_t audio_data[]; extern const uint32_t audio_data_length; volatile uint32_t audio_index = 0; volatile bool playback_done = false; // 定时器中断服务程序 bool timer_callback(repeating_timer_t *rt) { if (audio_index < audio_data_length) { pwm_set_chan_level(pwm_gpio_to_slice_num(AUDIO_PWM_PIN), PWM_CHAN_A, audio_data[audio_index++]); } else { // 播放完成 playback_done = true; return false; // 停止定时器 } return true; } int main() { stdio_init_all(); // 初始化stdio,可用于调试打印 // 1. 立即锁存电源!!! gpio_init(POWER_HOLD_PIN); gpio_set_dir(POWER_HOLD_PIN, GPIO_OUT); gpio_put(POWER_HOLD_PIN, 0); // 输出低电平,维持供电 // 2. 初始化光传感器ADC(略) // 3. 检查环境光,若为黑夜则直接跳转到关机流程(略) // 4. 配置PWM用于音频输出 gpio_set_function(AUDIO_PWM_PIN, GPIO_FUNC_PWM); uint slice_num = pwm_gpio_to_slice_num(AUDIO_PWM_PIN); pwm_config config = pwm_get_default_config(); pwm_config_set_clkdiv(&config, 125.0f); // 根据系统时钟和采样率计算 pwm_config_set_wrap(&config, 255); // 8位分辨率 pwm_init(slice_num, &config, true); // 5. 设置并启动音频播放定时器(例如44100Hz) repeating_timer_t timer; add_repeating_timer_us(-1000000/44100, timer_callback, NULL, &timer); // 约22.7us周期 // 6. 等待播放完成 while (!playback_done) { tight_loop_contents(); } // 7. 播放完成,准备断电 gpio_put(POWER_HOLD_PIN, 1); // 输出高电平,允许断电 // 给电容充电一点时间 sleep_ms(50); // 程序在此结束,等待外部电路断电 // 实际应用中,可以进入WFI睡眠以降低最后时刻的功耗 while (1) { __wfi(); } }

5. 调试、优化与常见问题排查

5.1 功耗测量与优化

功耗是项目的生命线。你需要一个万用表,最好能测量微安级电流。

  1. 测量静态电流:在电源管理电路正常工作、Pico完全断电的状态下,将万用表串联在电池正极与电路之间,测量电流。目标应低于100µA。如果过高,检查:

    • MOSFET的栅极漏电流是否过大?尝试更换一个型号。
    • 上拉电阻(10MΩ)是否阻值太小?可以尝试增大到22MΩ或47MΩ,但注意这会延长电容充电时间,影响关机速度。
    • 是否有其他漏电路径?检查PCB或焊点是否有污渍、锡渣导致轻微短路。
  2. 测量工作电流:在Pico播放语音时测量电流。这取决于音频放大电路的增益和音量。通常在几十到一百多毫安。确保你的AA电池能提供足够的瞬时电流。

5.2 音频质量优化

  1. PWM噪声(嘶嘶声)

    • 确保低通滤波器(LPF)已正确连接,电阻电容值匹配你的PWM基频。Pico的PWM基频通常为系统时钟(125MHz)除以分频和周期值。一个简单的RC滤波器(如1kΩ + 0.1µF,截止频率约1.6kHz)能滤除大部分高频噪声,但对音频高频也有衰减。可以尝试使用更高阶的滤波器或调整PWM频率。
    • 将PWM输出引脚远离模拟电路和电源线,减少耦合干扰。
    • 在Pico的3V3GND之间靠近芯片处,并联一个10µF电解电容和一个0.1µF陶瓷电容,用于电源去耦。
  2. 音量小或失真

    • 检查三极管放大电路的偏置电阻,确保三极管工作在放大区线性部分。可以用示波器观察基极和集电极的波形。
    • 尝试增大放大电路的增益(减小发射极电阻,如果存在的话)。
    • 确认扬声器阻抗匹配(8Ω)。

5.3 常见问题速查表

问题现象可能原因排查步骤与解决方案
系统无法上电1. 电池电量不足。
2. 钟机芯触点未闭合或接触不良。
3. 电源管理电路MOSFET损坏或焊接错误。
4. Pico3V3_EN引脚未正确连接。
1. 测量电池电压。
2. 用万用表通断档测量钟机芯触点在整点是否导通。
3. 检查MOSFET(2N7000)的D、S、G极是否接反。测量栅极电压变化。
4. 检查3V3_EN到MOSFET D极的连线。
上电后立即断电1. Pico程序未能及时将保持引脚(GPIO2)拉低。
2. 保持引脚电路连接错误或虚焊。
3. 栅极电容太小,充电过快。
1. 在代码最开始加调试灯或串口打印,确认程序是否运行。
2. 用示波器或逻辑分析仪抓取GPIO2上电后的电平。
3. 适当增大栅极对地电容(如从1µF增至2.2µF)。
播放完不关机1. Pico程序未将保持引脚(GPIO2)置高。
2. 栅极上拉电阻断路或阻值太大。
3. MOSFET损坏(无法导通)。
1. 检查代码关机逻辑是否执行。
2. 测量播放完成后GPIO2电平是否为高。
3. 测量栅极电压是否能缓慢上升至V+。
有触发但偶尔不播放1. 光传感器在临界值附近波动,误判为黑夜。
2. 文件系统错误(CircuitPython版)。
3. 音频文件损坏或格式不支持。
1. 增加光传感器读取的平均次数,或设置一个迟滞区间(如“低于A值算黑夜,高于B值算白天”)。
2. 重新安全弹出U盘或修复文件系统。
3. 确认音频格式:CP版用MP3,C++版用特定格式WAV。
声音有爆音或断续1. 电源电压不足,电池电量低。
2. PWM中断处理时间过长,丢失数据。
3. 音频数据读取速度跟不上(C++版)。
1. 更换新电池。
2. 优化C++中断服务程序,只做最必要的操作。
3. 确保音频数据存放在RAM中,而非从Flash缓慢读取。
续航远短于预期1. 静态电流测量不准确,实际过大。
2. 系统被意外唤醒(如触点抖动)。
3. 电池自放电严重或质量差。
1. 用精度更高的万用表或电流计测量静态电流。
2. 在钟机芯触点两端并联一个0.1µF电容,消除抖动。
3. 使用质量好的碱性电池或低自放电镍氢电池。

5.4 外壳制作与安装建议

一个美观耐用的外壳能极大提升项目的完成度。

  1. 材料选择:木板、亚克力板或3D打印外壳都是不错的选择。确保有开口让光传感器感知环境光,并为扬声器预留出声孔。
  2. 时钟机芯安装:在面板中心开一个直径约7-8mm的圆孔,用于固定钟机芯的轴。机芯本体藏在壳内。
  3. 电池仓:使用独立的2xAA电池盒,方便更换。如果追求一体化,可以设计卡扣式电池仓。
  4. 调试接口:建议在外壳上留一个隐蔽的Micro-USB接口,方便后期连接电脑更新程序或调试,不用每次都拆开。
  5. 时间校准:安装指针前,先让机芯运行,等到整点听到“咔哒”声时,立即将时针、分针、秒针都对准12点方向装上。这样语音报时就能和指针时间同步。

这个项目从构思到实现,充满了硬件和软件交织的乐趣。最大的成就感来自于用简单的电路解决了关键的低功耗难题,以及通过两种不同的编程范式实现了同一功能,让我对嵌入式系统的“效率”与“便利”有了更深的体会。当你第一次听到它在整点用自己定制的声音报时,并且知道它可能安静地工作一整年时,那种感觉非常美妙。如果想让项目更进一步,可以考虑加入温度传感器实现“天气播报”,或者通过蓝牙在手机上远程更新语音库,让这个会说话的时钟拥有更多可能性。

http://www.zskr.cn/news/1440349.html

相关文章:

  • 终极指南:如何用LinkSwift免费获取九大网盘直链下载地址
  • 如何快速访问Steam创意工坊:跨平台玩家的完整解决方案
  • 图形学“光栅化”的字面意思
  • 一个“清官”在人情与王法之间的系统性溃败
  • 树莓派实体记忆游戏:从GPIO、SPI到数据库的嵌入式系统实战
  • code-server:浏览器里运行 VS Code,随时随地云端开发
  • 华硕笔记本性能控制新选择:告别臃肿系统,拥抱10MB轻量神器
  • 西门子LOGO! PLC入门指南:从软件安装到梯形图编程实战
  • 猜猜 AI 写“最长无重复子串“会犯什么错?第一版差点 O(n³)
  • 19.从行内到类名:JavaScript 修改 CSS 样式的两种核心方式对比
  • 大模型面试题:LLM预训练阶段有哪几个关键步骤?
  • Kafka InconsistentClusterIdException 导致容器无限重启,磁盘打满排查与修复
  • 终极指南:如何通过RMSProp优化器和EMA权重平均提升cspdarknet53.ra_in1k训练稳定性
  • 大模型面试题:LangChain Token计数有什么问题?如何解决?
  • 2026年留学生实习期求职机构推荐,五大全流程服务优质品牌 - 资讯焦点
  • LoRa无线通信入门:基于AT命令的REYAX RYLR998模块配置与实战
  • 深度伪造视频监管空白正在扩大(2024全球立法进度白皮书首发)
  • NVIDIA Profile Inspector深度解析:解锁显卡隐藏性能的专业调优指南
  • Apollo-7B横空出世:革命性多语言医疗AI模型如何赋能全球60亿人?
  • 2026年国内厨卫电器消费市场现状及消费者选购参考指南 - 资讯焦点
  • 从代码到落地:BailingMoeV2_5模型架构的MoE稀疏专家系统详解 [特殊字符]
  • 企业背调怎么查?2026年企业常用的3种背调方式 - 资讯快报
  • MiniCPM4-0.5B在企业级应用中的3大实战案例
  • DeBERTa-v3-base-prompt-injection-v2开发者指南:如何自定义训练和微调你的提示注入检测模型
  • 别再用默认样式了!Unity Toggle组件从‘能用’到‘好看’的完整美化指南(附UI动效)
  • 燃气灶嵌入式还是台式灶好 2026年市场调研及选购参考 - 资讯焦点
  • Mysql实验之——建库建表、插入数据、查询(练习3)
  • 如何使用tsdae-lemone-mbert-base进行法律文本特征提取:5分钟快速入门 [特殊字符]
  • 2026年靠谱的句容双面印花头巾/全涤头巾用户口碑推荐厂家 - 品牌宣传支持者
  • 创客教育中的电路设计:从原理到实践,打造智能生活项目