1. 项目概述与设计初衷几年前我帮一位视力不太好的长辈调试新电视那个标配的遥控器让我印象深刻——密密麻麻的按键每个都小得可怜标识更是需要凑得很近才能看清。对于视障或手部活动不便的用户来说这几乎是个无法独立使用的设备。这件事一直搁在我心里直到后来接触到一些开源辅助技术项目才让我下定决心为什么不自己做一个真正简单、好用、而且特别省电的遥控器呢于是就有了这个以ATtiny84微控制器为核心的超低功耗红外遥控器项目。它的目标非常明确只保留最核心的功能开关、音量、三个常用频道通过硕大、有明确触感的按键来提升可操作性并且依靠精心的低功耗设计让两节最普通的AA电池就能驱动它工作好几年。我选择了在飞利浦电视中广泛使用的RC6红外协议作为通信标准确保了兼容性。整个项目从电路板设计、固件编写到3D打印的外壳全部开源。我希望它不仅仅是一个可复制的制作指南更能成为一个引子启发更多人关注并动手改善我们身边那些“不够友好”的日常科技产品。2. 核心硬件选型与低功耗架构解析为什么是ATtiny84在开始画原理图之前这个选择是经过一番权衡的。市面上常见的8位MCU很多比如更经典的ATmega328PArduino Uno的核心或者更小的ATtiny85。选择ATtiny84主要基于以下几点考量2.1 微控制器ATtiny84的独特优势首先I/O引脚数量。我们需要驱动6个独立按键需要6个输入引脚和1个红外发射电路至少1个输出引脚。ATtiny85只有6个可用I/O口捉襟见肘。ATtiny84拥有12个可编程I/O口绰绰有余为未来功能扩展比如增加一个状态指示灯预留了空间。其次功耗特性。ATtiny84系列在深度睡眠Power-down模式下的电流消耗可以低至100nA0.1微安级别这对于我们追求“数年续航”的目标至关重要。虽然ATtiny85也能做到类似的睡眠功耗但ATtiny84在活动模式下的功耗与性能平衡更好。再者内部资源。它具备一个硬件USI通用串行接口虽然本项目未使用但为调试或未来升级如通过红外学习功能提供了可能。其内部的8MHz RC振荡器精度足够用于红外信号调制省去了外部晶振既简化了设计又降低了功耗和成本。注意采购时请认准“ATtiny84A”这是新一代产品工作电压范围更宽1.8-5.5V在低电压下的性能更好与AA电池放电特性更匹配。2.2 红外发射电路效率与驱动的平衡红外遥控的本质是用一个高频载波通常是38kHz来调制代表指令的数字信号。这个载波需要由MCU的定时器精确产生并通过一个功率足够的红外发光二极管IR LED发射出去。直接使用MCU的I/O口驱动IR LED是行不通的。ATtiny84的单个I/O引脚拉电流能力有限通常20mA左右而为了确保足够的发射距离和角度IR LED在工作时常需要100mA甚至更大的瞬时电流。因此必须使用三极管开关电路。我选择了一个常见的S8050NPN型三极管。其基极通过一个限流电阻我用了100Ω连接到MCU的PB2引脚。当PB2输出高电平时三极管饱和导通相当于将IR LED和阳极电阻直接接到了电源正极。这个阳极电阻的取值是关键它决定了流过IR LED的电流。假设电源电压为3V两节AA电池IR LED正向压降约为1.2V三极管饱和压降约为0.2V那么电阻两端的电压约为1.6V。若期望电流为100mA根据欧姆定律 R V / I 1.6V / 0.1A 16Ω。我最终选择了15Ω的电阻实测发射距离在无遮挡情况下超过8米完全满足客厅使用需求。2.3 电源与按键设计极简与可靠电源就是两节AA电池串联提供约3V电压。这里没有使用任何线性稳压器如LDO目的是避免稳压器自身的静态电流损耗即使低功耗LDO也有几个微安。ATtiny84在3V下工作完全正常。所有按键一端接地另一端通过一个10kΩ的上拉电阻接到MCU的I/O口并配置为内部上拉禁用、外部上拉使能。当按键未按下时I/O口被上拉到高电平3V按下时直接接地变为低电平。这种设计简单可靠。一个关键的细节是所有按键对应的I/O口必须被配置为“电平变化中断PCINT”唤醒源。这是实现超低功耗的基石——MCU在睡眠时只有这部分电路在监测按键动作消耗极微的电流。3. 超低功耗固件设计与实现细节固件的核心思想是让MCU在99.99%的时间里处于最深度的睡眠状态仅在按键被按下时瞬间醒来发送完红外信号后立刻回去睡觉。听起来简单但实现上有几个坑需要避开。3.1 睡眠模式与中断唤醒配置ATtiny84最省电的模式是PWR_DOWN模式。在此模式下核心时钟、几乎所有模块都停止工作只有外部中断、看门狗等少数电路可以唤醒它。我们的唤醒源就是按键产生的电平变化中断。#include avr/sleep.h #include avr/interrupt.h // 初始化按键引脚为输入启用内部上拉可选我们用了外部上拉 void setup_pins() { // 假设按键连接在PA0-PA5 DDRA ~((1PA0)|(1PA1)|(1PA2)|(1PA3)|(1PA4)|(1PA5)); // 设为输入 PORTA | ((1PA0)|(1PA1)|(1PA2)|(1PA3)|(1PA4)|(1PA5)); // 启用内部上拉作为辅助主上拉是外部的10kΩ } // 配置引脚变化中断 void setup_pcint() { PCMSK0 | (1PCINT0)|(1PCINT1)|(1PCINT2)|(1PCINT3)|(1PCINT4)|(1PCINT5); // 使能PA0-PA5的引脚变化中断 GIMSK | (1PCIE0); // 使能PCINT0中断向量 sei(); // 开启全局中断 } // 进入深度睡眠 void enter_sleep() { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); // 程序在此挂起等待中断唤醒 // 唤醒后继续执行下一条指令 sleep_disable(); } void loop() { // 发送红外信号... // 发送完成后准备下一次睡眠 delay_ms(10); // 一个小延时防止按键抖动导致误唤醒 enter_sleep(); }3.2 RC6协议编码与38kHz载波生成RC6协议相对复杂它使用相位编码每位数据中间都有一次跳变。一个完整的RC6帧包括引导码、模式位、控制位和数据位。我们需要用代码精确地模拟出这个波形。38kHz载波相当于周期约26.3微秒。我们可以使用ATtiny84的定时器1TC1在CTC模式下生成这个频率的PWM信号。当需要发送逻辑“1”或“0”时就开启或关闭这个PWM输出到驱动三极管的I/O口。// 简化的RC6信号发送函数示例发送一位 void send_rc6_bit(uint8_t bit) { if (bit) { // 发送逻辑“1”的波形例如先高后低 IR_ON(); // 开启38kHz载波 delay_us(444); // RC6一位的典型时长的一部分 IR_OFF(); delay_us(889 - 444); IR_ON(); delay_us(444); IR_OFF(); } else { // 发送逻辑“0”的波形例如先低后高 IR_OFF(); delay_us(444); IR_ON(); delay_us(889 - 444); IR_OFF(); delay_us(444); } }实操心得在调试红外信号时最直接的方法不是用示波器当然有的话更好而是用手机的摄像头。打开手机相机将遥控器的IR LED对准镜头按下按键。在手机屏幕上你会看到IR LED发出明显的、人眼不可见的闪烁白光。这是一个快速验证发射电路是否工作的好方法。更精确的测试则需要用到像TSOP1138这样的红外接收头和一个串口调试工具来解码和验证发送的协议是否正确。3.3 功耗实测与优化在完成所有焊接并刷入固件后我用万用表的微安档串联进电池供电回路进行了测量。深度睡眠电流稳定在1.2 - 1.5 µA之间。这个电流主要来自ATtiny84自身的Power-down漏电流、外部10kΩ上拉电阻的分流电流每个约 3V/10kΩ 300µA但6个按键并联在睡眠时只有被监测的那个引脚有微弱电流且MCU内部输入阻抗很高实际贡献很小以及PCB本身的微小漏电。这个数值非常理想。发射瞬时电流按下按键时电流峰值瞬间达到110mA左右这与之前计算的IR LED驱动电流吻合。每次发射持续时间很短约几十毫秒。续航估算两节AA碱性电池总容量约3000mAh。假设每天按键100次每次发射耗时100ms则每天活跃时间仅10秒耗电约 (0.11A * 10s / 3600s) ≈ 0.3mAh。睡眠功耗每天耗电约 (0.0015mA * 24h) 0.036mAh。每日总耗电约0.336mAh。理论续航可达 3000mAh / 0.336mAh/天 ≈ 8928天超过24年当然这是理想情况电池自放电、环境温度等因素会缩短实际寿命但用上好几年是绝对有保障的。4. 从设计到实物PCB与外壳制作4.1 定制PCB设计要点为了追求极致的紧凑和可靠我放弃了万能板选择了设计一块定制PCB。使用KiCad这类开源EDA工具就能完成。布局将MCU放在板子中央6个按键围绕其排列成易于盲操的布局例如电源键在顶部音量键在右侧频道键在左侧。IR LED和三极管驱动电路放在板子的一端朝向发射方向。电池座放在底部以平衡重心。走线电源线VCC和GND适当加粗。在MCU的VCC和GND引脚附近放置一个100nF的陶瓷去耦电容这对于稳定MCU工作、降低噪声至关重要尤其是在大电流发射的瞬间。ISP编程接口我留出了一个标准的6针AVR ISP接口MOSI, MISO, SCK, RESET, VCC, GND。即使焊接了电池座也能方便地连接编程器进行固件烧录。生成制造文件设计完成后在KiCad中生成Gerber文件和钻孔文件就可以提交给嘉立创、JLCPCB等制造商进行打样。双面板、沉金工艺5块板子的成本通常不到20元人民币。4.2 3D打印外壳的设计与装配外壳的设计目标就三个牢固、手感好、装配简单。我用Fusion 360进行建模。内部结构外壳内部需要精确的立柱来定位PCB以及卡槽来固定6个微动开关防止其移动。电池仓需要设计弹簧片卡槽。我在顶部和底部外壳对接处设计了螺丝柱使用M2x7mm的自攻螺丝固定。按键设计这是提升体验的关键。我设计了比原装遥控器大得多的圆形按键帽顶部有凸起的圆点或条纹作为触觉标识。按键帽与微动开关之间留有0.5mm的预行程间隙确保按下时有清晰的手感。一个巧妙的电池接触设计我没有使用整体的电池座而是利用了从废旧电池座上拆下来的弹簧片。在外壳内部对应电池正负极的位置设计了一个可以嵌入M3螺母的方槽。将弹簧片焊上一段导线导线另一端压接一个O型端子然后用一颗短的M3螺丝将端子紧固在嵌入的M3螺母上。这样既节省了空间又获得了非常可靠的电气连接。打印与后处理使用普通的PLA材料层高0.2mm填充率20%即可。打印完成后需要仔细清理支撑材料并用小锉刀或砂纸打磨螺丝柱和卡扣部位确保装配顺畅。在打印上盖时需要在 slicer 软件中设置“暂停”在打印到嵌入螺母的那一层时暂停打印机手动放入M3螺母然后继续打印让后续的塑料层将螺母包裹固定住。5. 烧录、调试与个性化适配5.1 首次烧录与熔丝位设置新的ATtiny84出厂默认使用内部1MHz时钟并开启了8分频运行速度很慢。我们需要将其设置为使用内部8MHz RC振荡器且不分频。连接USBasp等ISP编程器到板子的6针接口。使用avrdude命令行工具。首先读取当前熔丝位确认状态avrdude -c usbasp -p t84 -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h设置低速熔丝位为0xE2这将启用内部8MHz时钟并禁用时钟分频器CKDIV81avrdude -c usbasp -p t84 -U lfuse:w:0xE2:m再次读取熔丝位验证是否写入成功。重要提示熔丝位配置错误可能导致MCU无法再次被编程俗称“锁死”。hfuse和efuse通常保持默认值0xDF和0xFF即可切勿随意修改特别是RSTDISBL禁用复位引脚和DWEN调试线使能位一旦误操作恢复起来非常麻烦。5.2 使用PlatformIO进行开发与上传对于不熟悉AVR命令行开发的朋友PlatformIO是绝佳选择。它是一个嵌入在VS Code中的专业嵌入式开发平台。在VS Code中安装PlatformIO IDE扩展。打开本项目固件所在的文件夹。platformio.ini配置文件已经写好了指定了芯片型号attiny84、编程工具usbasp和框架arduino或直接使用avr-libc。点击底栏的“编译”对勾图标检查代码。连接编程器点击“上传”右箭头图标PlatformIO会自动完成编译和烧录。5.3 适配其他品牌电视捕获红外码如果你想用这个遥控器控制非飞利浦的电视就需要捕获原装遥控器的红外码。我制作了一个简单的“红外嗅探器”工具。硬件一块Raspberry Pi Pico一个TSOP1138或VS1838B红外接收头。接收头的输出脚接Pico的GPIO15VCC和GND分别接3.3V和地。软件在Pico上运行一个开源红外库如IRremotefor Pico的示例代码。它会监听GPIO15当收到红外信号时自动解析其协议NEC、Sony、RC5、RC6等和具体码值并通过串口打印出来。操作用原装遥控器对准接收头按下你想要的按键如电源串口监视器就会显示类似Protocol: NEC, Address: 0x00, Command: 0x45的信息。记录下这些值。修改固件回到ATtiny84的固件中找到存储红外码的数组或常量定义将对应的协议和码值替换为你刚刚捕获到的。不同协议的数据结构和发送函数不同可能需要调整send_ir_signal()函数。这就是为什么项目源码结构清晰很重要的原因。6. 常见问题排查与进阶优化在实际制作和使用的过程中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案按下按键电视完全无反应1. 电源问题2. IR LED未工作3. 协议或码值错误1. 用万用表测量电池电压确保2.4V。检查电池触点焊接是否牢固。2.用手机摄像头观察IR LED按下按键时应看到闪烁。若无检查三极管、电阻焊接及MCU输出引脚配置。3. 使用“红外嗅探器”工具接收本遥控器信号检查发送的协议和码值是否正确。遥控距离很短1米1. IR LED驱动电流不足2. IR LED方向性或被遮挡3. 电池电量不足1. 测量发射时流过IR LED的电流可用万用表电流档串联。适当减小与IR LED串联的限流电阻如从15Ω降到10Ω但注意不要超过IR LED最大额定电流。2. 确保IR LED前方外壳开孔通透无遮挡。IR LED有一定指向性尽量对准电视。3. 更换新电池。偶尔按键失灵或连发1. 按键抖动2. 电源噪声1. 在固件的按键检测中断服务程序或主循环中加入软件消抖检测到按键后延时10-20ms再读取状态。2. 确保MCU的VCC和GND之间的100nF去耦电容已焊接且靠近MCU引脚。尝试在电池两端并联一个100µF的电解电容以稳定电压。睡眠电流偏高10µA1. I/O口配置不当2. PCB漏电3. 外部上拉电阻过小1. 确保所有未使用的I/O口设置为输出低电平或输入并启用内部上拉避免浮空。浮空的引脚会因感应交流电而轻微导通增加功耗。2. 用酒精清洗PCB确保无焊锡渣等导电杂质。3. 检查外部上拉电阻是否为10kΩ或更大。无法通过ISP编程1. 编程器连接错误2. 熔丝位配置错误3. 复位引脚被占用1. 仔细核对MOSI、MISO、SCK、RESET、VCC、GND六根线的连接切勿接反。2. 如果误操作了熔丝位如禁用了SPI可能需要使用高压并行编程器来恢复。3. 确保复位引脚PB3没有对地短路并且上拉电阻通常10kΩ已连接。进阶优化思路增加触觉反馈可以在外壳内部增加一个微型振动马达用另一个三极管驱动在按键按下并成功发送信号后提供一个短暂的振动反馈这对视障用户非常友好。学习型遥控将红外接收头也集成到遥控器中通过一个“学习”模式键让用户可以自行录制任意遥控器的信号。这需要更大的存储空间可能需要ATtiny84的EEPROM或换用其他型号MCU和更复杂的固件逻辑。无线升级如果预留一个光敏电阻或红外接收头理论上可以通过电视屏幕闪烁特定图案的方式向遥控器传输新的配置数据实现“无接触”升级。外壳材料对于经常使用的设备可以考虑使用更耐磨、手感更好的材料进行3D打印如PETG、TPU柔性材料适合做防滑套甚至尼龙。这个项目的乐趣在于它从一个具体的需求出发融合了嵌入式编程、硬件设计、3D建模等多个领域的技能最终做出一个实实在在、能解决实际问题且能耗极低的产品。当你看到自己制作的遥控器成功控制电视并且知道它里面的电池可能比你想象中耐用得多的时候那种成就感是纯粹的。更重要的是它的开源特性意味着任何人都可以基于此进行修改、优化让它去适配更多的设备服务更多的人。这或许就是创客精神最打动人的地方。
基于ATtiny84的超低功耗红外遥控器设计与实现
1. 项目概述与设计初衷几年前我帮一位视力不太好的长辈调试新电视那个标配的遥控器让我印象深刻——密密麻麻的按键每个都小得可怜标识更是需要凑得很近才能看清。对于视障或手部活动不便的用户来说这几乎是个无法独立使用的设备。这件事一直搁在我心里直到后来接触到一些开源辅助技术项目才让我下定决心为什么不自己做一个真正简单、好用、而且特别省电的遥控器呢于是就有了这个以ATtiny84微控制器为核心的超低功耗红外遥控器项目。它的目标非常明确只保留最核心的功能开关、音量、三个常用频道通过硕大、有明确触感的按键来提升可操作性并且依靠精心的低功耗设计让两节最普通的AA电池就能驱动它工作好几年。我选择了在飞利浦电视中广泛使用的RC6红外协议作为通信标准确保了兼容性。整个项目从电路板设计、固件编写到3D打印的外壳全部开源。我希望它不仅仅是一个可复制的制作指南更能成为一个引子启发更多人关注并动手改善我们身边那些“不够友好”的日常科技产品。2. 核心硬件选型与低功耗架构解析为什么是ATtiny84在开始画原理图之前这个选择是经过一番权衡的。市面上常见的8位MCU很多比如更经典的ATmega328PArduino Uno的核心或者更小的ATtiny85。选择ATtiny84主要基于以下几点考量2.1 微控制器ATtiny84的独特优势首先I/O引脚数量。我们需要驱动6个独立按键需要6个输入引脚和1个红外发射电路至少1个输出引脚。ATtiny85只有6个可用I/O口捉襟见肘。ATtiny84拥有12个可编程I/O口绰绰有余为未来功能扩展比如增加一个状态指示灯预留了空间。其次功耗特性。ATtiny84系列在深度睡眠Power-down模式下的电流消耗可以低至100nA0.1微安级别这对于我们追求“数年续航”的目标至关重要。虽然ATtiny85也能做到类似的睡眠功耗但ATtiny84在活动模式下的功耗与性能平衡更好。再者内部资源。它具备一个硬件USI通用串行接口虽然本项目未使用但为调试或未来升级如通过红外学习功能提供了可能。其内部的8MHz RC振荡器精度足够用于红外信号调制省去了外部晶振既简化了设计又降低了功耗和成本。注意采购时请认准“ATtiny84A”这是新一代产品工作电压范围更宽1.8-5.5V在低电压下的性能更好与AA电池放电特性更匹配。2.2 红外发射电路效率与驱动的平衡红外遥控的本质是用一个高频载波通常是38kHz来调制代表指令的数字信号。这个载波需要由MCU的定时器精确产生并通过一个功率足够的红外发光二极管IR LED发射出去。直接使用MCU的I/O口驱动IR LED是行不通的。ATtiny84的单个I/O引脚拉电流能力有限通常20mA左右而为了确保足够的发射距离和角度IR LED在工作时常需要100mA甚至更大的瞬时电流。因此必须使用三极管开关电路。我选择了一个常见的S8050NPN型三极管。其基极通过一个限流电阻我用了100Ω连接到MCU的PB2引脚。当PB2输出高电平时三极管饱和导通相当于将IR LED和阳极电阻直接接到了电源正极。这个阳极电阻的取值是关键它决定了流过IR LED的电流。假设电源电压为3V两节AA电池IR LED正向压降约为1.2V三极管饱和压降约为0.2V那么电阻两端的电压约为1.6V。若期望电流为100mA根据欧姆定律 R V / I 1.6V / 0.1A 16Ω。我最终选择了15Ω的电阻实测发射距离在无遮挡情况下超过8米完全满足客厅使用需求。2.3 电源与按键设计极简与可靠电源就是两节AA电池串联提供约3V电压。这里没有使用任何线性稳压器如LDO目的是避免稳压器自身的静态电流损耗即使低功耗LDO也有几个微安。ATtiny84在3V下工作完全正常。所有按键一端接地另一端通过一个10kΩ的上拉电阻接到MCU的I/O口并配置为内部上拉禁用、外部上拉使能。当按键未按下时I/O口被上拉到高电平3V按下时直接接地变为低电平。这种设计简单可靠。一个关键的细节是所有按键对应的I/O口必须被配置为“电平变化中断PCINT”唤醒源。这是实现超低功耗的基石——MCU在睡眠时只有这部分电路在监测按键动作消耗极微的电流。3. 超低功耗固件设计与实现细节固件的核心思想是让MCU在99.99%的时间里处于最深度的睡眠状态仅在按键被按下时瞬间醒来发送完红外信号后立刻回去睡觉。听起来简单但实现上有几个坑需要避开。3.1 睡眠模式与中断唤醒配置ATtiny84最省电的模式是PWR_DOWN模式。在此模式下核心时钟、几乎所有模块都停止工作只有外部中断、看门狗等少数电路可以唤醒它。我们的唤醒源就是按键产生的电平变化中断。#include avr/sleep.h #include avr/interrupt.h // 初始化按键引脚为输入启用内部上拉可选我们用了外部上拉 void setup_pins() { // 假设按键连接在PA0-PA5 DDRA ~((1PA0)|(1PA1)|(1PA2)|(1PA3)|(1PA4)|(1PA5)); // 设为输入 PORTA | ((1PA0)|(1PA1)|(1PA2)|(1PA3)|(1PA4)|(1PA5)); // 启用内部上拉作为辅助主上拉是外部的10kΩ } // 配置引脚变化中断 void setup_pcint() { PCMSK0 | (1PCINT0)|(1PCINT1)|(1PCINT2)|(1PCINT3)|(1PCINT4)|(1PCINT5); // 使能PA0-PA5的引脚变化中断 GIMSK | (1PCIE0); // 使能PCINT0中断向量 sei(); // 开启全局中断 } // 进入深度睡眠 void enter_sleep() { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); // 程序在此挂起等待中断唤醒 // 唤醒后继续执行下一条指令 sleep_disable(); } void loop() { // 发送红外信号... // 发送完成后准备下一次睡眠 delay_ms(10); // 一个小延时防止按键抖动导致误唤醒 enter_sleep(); }3.2 RC6协议编码与38kHz载波生成RC6协议相对复杂它使用相位编码每位数据中间都有一次跳变。一个完整的RC6帧包括引导码、模式位、控制位和数据位。我们需要用代码精确地模拟出这个波形。38kHz载波相当于周期约26.3微秒。我们可以使用ATtiny84的定时器1TC1在CTC模式下生成这个频率的PWM信号。当需要发送逻辑“1”或“0”时就开启或关闭这个PWM输出到驱动三极管的I/O口。// 简化的RC6信号发送函数示例发送一位 void send_rc6_bit(uint8_t bit) { if (bit) { // 发送逻辑“1”的波形例如先高后低 IR_ON(); // 开启38kHz载波 delay_us(444); // RC6一位的典型时长的一部分 IR_OFF(); delay_us(889 - 444); IR_ON(); delay_us(444); IR_OFF(); } else { // 发送逻辑“0”的波形例如先低后高 IR_OFF(); delay_us(444); IR_ON(); delay_us(889 - 444); IR_OFF(); delay_us(444); } }实操心得在调试红外信号时最直接的方法不是用示波器当然有的话更好而是用手机的摄像头。打开手机相机将遥控器的IR LED对准镜头按下按键。在手机屏幕上你会看到IR LED发出明显的、人眼不可见的闪烁白光。这是一个快速验证发射电路是否工作的好方法。更精确的测试则需要用到像TSOP1138这样的红外接收头和一个串口调试工具来解码和验证发送的协议是否正确。3.3 功耗实测与优化在完成所有焊接并刷入固件后我用万用表的微安档串联进电池供电回路进行了测量。深度睡眠电流稳定在1.2 - 1.5 µA之间。这个电流主要来自ATtiny84自身的Power-down漏电流、外部10kΩ上拉电阻的分流电流每个约 3V/10kΩ 300µA但6个按键并联在睡眠时只有被监测的那个引脚有微弱电流且MCU内部输入阻抗很高实际贡献很小以及PCB本身的微小漏电。这个数值非常理想。发射瞬时电流按下按键时电流峰值瞬间达到110mA左右这与之前计算的IR LED驱动电流吻合。每次发射持续时间很短约几十毫秒。续航估算两节AA碱性电池总容量约3000mAh。假设每天按键100次每次发射耗时100ms则每天活跃时间仅10秒耗电约 (0.11A * 10s / 3600s) ≈ 0.3mAh。睡眠功耗每天耗电约 (0.0015mA * 24h) 0.036mAh。每日总耗电约0.336mAh。理论续航可达 3000mAh / 0.336mAh/天 ≈ 8928天超过24年当然这是理想情况电池自放电、环境温度等因素会缩短实际寿命但用上好几年是绝对有保障的。4. 从设计到实物PCB与外壳制作4.1 定制PCB设计要点为了追求极致的紧凑和可靠我放弃了万能板选择了设计一块定制PCB。使用KiCad这类开源EDA工具就能完成。布局将MCU放在板子中央6个按键围绕其排列成易于盲操的布局例如电源键在顶部音量键在右侧频道键在左侧。IR LED和三极管驱动电路放在板子的一端朝向发射方向。电池座放在底部以平衡重心。走线电源线VCC和GND适当加粗。在MCU的VCC和GND引脚附近放置一个100nF的陶瓷去耦电容这对于稳定MCU工作、降低噪声至关重要尤其是在大电流发射的瞬间。ISP编程接口我留出了一个标准的6针AVR ISP接口MOSI, MISO, SCK, RESET, VCC, GND。即使焊接了电池座也能方便地连接编程器进行固件烧录。生成制造文件设计完成后在KiCad中生成Gerber文件和钻孔文件就可以提交给嘉立创、JLCPCB等制造商进行打样。双面板、沉金工艺5块板子的成本通常不到20元人民币。4.2 3D打印外壳的设计与装配外壳的设计目标就三个牢固、手感好、装配简单。我用Fusion 360进行建模。内部结构外壳内部需要精确的立柱来定位PCB以及卡槽来固定6个微动开关防止其移动。电池仓需要设计弹簧片卡槽。我在顶部和底部外壳对接处设计了螺丝柱使用M2x7mm的自攻螺丝固定。按键设计这是提升体验的关键。我设计了比原装遥控器大得多的圆形按键帽顶部有凸起的圆点或条纹作为触觉标识。按键帽与微动开关之间留有0.5mm的预行程间隙确保按下时有清晰的手感。一个巧妙的电池接触设计我没有使用整体的电池座而是利用了从废旧电池座上拆下来的弹簧片。在外壳内部对应电池正负极的位置设计了一个可以嵌入M3螺母的方槽。将弹簧片焊上一段导线导线另一端压接一个O型端子然后用一颗短的M3螺丝将端子紧固在嵌入的M3螺母上。这样既节省了空间又获得了非常可靠的电气连接。打印与后处理使用普通的PLA材料层高0.2mm填充率20%即可。打印完成后需要仔细清理支撑材料并用小锉刀或砂纸打磨螺丝柱和卡扣部位确保装配顺畅。在打印上盖时需要在 slicer 软件中设置“暂停”在打印到嵌入螺母的那一层时暂停打印机手动放入M3螺母然后继续打印让后续的塑料层将螺母包裹固定住。5. 烧录、调试与个性化适配5.1 首次烧录与熔丝位设置新的ATtiny84出厂默认使用内部1MHz时钟并开启了8分频运行速度很慢。我们需要将其设置为使用内部8MHz RC振荡器且不分频。连接USBasp等ISP编程器到板子的6针接口。使用avrdude命令行工具。首先读取当前熔丝位确认状态avrdude -c usbasp -p t84 -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h设置低速熔丝位为0xE2这将启用内部8MHz时钟并禁用时钟分频器CKDIV81avrdude -c usbasp -p t84 -U lfuse:w:0xE2:m再次读取熔丝位验证是否写入成功。重要提示熔丝位配置错误可能导致MCU无法再次被编程俗称“锁死”。hfuse和efuse通常保持默认值0xDF和0xFF即可切勿随意修改特别是RSTDISBL禁用复位引脚和DWEN调试线使能位一旦误操作恢复起来非常麻烦。5.2 使用PlatformIO进行开发与上传对于不熟悉AVR命令行开发的朋友PlatformIO是绝佳选择。它是一个嵌入在VS Code中的专业嵌入式开发平台。在VS Code中安装PlatformIO IDE扩展。打开本项目固件所在的文件夹。platformio.ini配置文件已经写好了指定了芯片型号attiny84、编程工具usbasp和框架arduino或直接使用avr-libc。点击底栏的“编译”对勾图标检查代码。连接编程器点击“上传”右箭头图标PlatformIO会自动完成编译和烧录。5.3 适配其他品牌电视捕获红外码如果你想用这个遥控器控制非飞利浦的电视就需要捕获原装遥控器的红外码。我制作了一个简单的“红外嗅探器”工具。硬件一块Raspberry Pi Pico一个TSOP1138或VS1838B红外接收头。接收头的输出脚接Pico的GPIO15VCC和GND分别接3.3V和地。软件在Pico上运行一个开源红外库如IRremotefor Pico的示例代码。它会监听GPIO15当收到红外信号时自动解析其协议NEC、Sony、RC5、RC6等和具体码值并通过串口打印出来。操作用原装遥控器对准接收头按下你想要的按键如电源串口监视器就会显示类似Protocol: NEC, Address: 0x00, Command: 0x45的信息。记录下这些值。修改固件回到ATtiny84的固件中找到存储红外码的数组或常量定义将对应的协议和码值替换为你刚刚捕获到的。不同协议的数据结构和发送函数不同可能需要调整send_ir_signal()函数。这就是为什么项目源码结构清晰很重要的原因。6. 常见问题排查与进阶优化在实际制作和使用的过程中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案按下按键电视完全无反应1. 电源问题2. IR LED未工作3. 协议或码值错误1. 用万用表测量电池电压确保2.4V。检查电池触点焊接是否牢固。2.用手机摄像头观察IR LED按下按键时应看到闪烁。若无检查三极管、电阻焊接及MCU输出引脚配置。3. 使用“红外嗅探器”工具接收本遥控器信号检查发送的协议和码值是否正确。遥控距离很短1米1. IR LED驱动电流不足2. IR LED方向性或被遮挡3. 电池电量不足1. 测量发射时流过IR LED的电流可用万用表电流档串联。适当减小与IR LED串联的限流电阻如从15Ω降到10Ω但注意不要超过IR LED最大额定电流。2. 确保IR LED前方外壳开孔通透无遮挡。IR LED有一定指向性尽量对准电视。3. 更换新电池。偶尔按键失灵或连发1. 按键抖动2. 电源噪声1. 在固件的按键检测中断服务程序或主循环中加入软件消抖检测到按键后延时10-20ms再读取状态。2. 确保MCU的VCC和GND之间的100nF去耦电容已焊接且靠近MCU引脚。尝试在电池两端并联一个100µF的电解电容以稳定电压。睡眠电流偏高10µA1. I/O口配置不当2. PCB漏电3. 外部上拉电阻过小1. 确保所有未使用的I/O口设置为输出低电平或输入并启用内部上拉避免浮空。浮空的引脚会因感应交流电而轻微导通增加功耗。2. 用酒精清洗PCB确保无焊锡渣等导电杂质。3. 检查外部上拉电阻是否为10kΩ或更大。无法通过ISP编程1. 编程器连接错误2. 熔丝位配置错误3. 复位引脚被占用1. 仔细核对MOSI、MISO、SCK、RESET、VCC、GND六根线的连接切勿接反。2. 如果误操作了熔丝位如禁用了SPI可能需要使用高压并行编程器来恢复。3. 确保复位引脚PB3没有对地短路并且上拉电阻通常10kΩ已连接。进阶优化思路增加触觉反馈可以在外壳内部增加一个微型振动马达用另一个三极管驱动在按键按下并成功发送信号后提供一个短暂的振动反馈这对视障用户非常友好。学习型遥控将红外接收头也集成到遥控器中通过一个“学习”模式键让用户可以自行录制任意遥控器的信号。这需要更大的存储空间可能需要ATtiny84的EEPROM或换用其他型号MCU和更复杂的固件逻辑。无线升级如果预留一个光敏电阻或红外接收头理论上可以通过电视屏幕闪烁特定图案的方式向遥控器传输新的配置数据实现“无接触”升级。外壳材料对于经常使用的设备可以考虑使用更耐磨、手感更好的材料进行3D打印如PETG、TPU柔性材料适合做防滑套甚至尼龙。这个项目的乐趣在于它从一个具体的需求出发融合了嵌入式编程、硬件设计、3D建模等多个领域的技能最终做出一个实实在在、能解决实际问题且能耗极低的产品。当你看到自己制作的遥控器成功控制电视并且知道它里面的电池可能比你想象中耐用得多的时候那种成就感是纯粹的。更重要的是它的开源特性意味着任何人都可以基于此进行修改、优化让它去适配更多的设备服务更多的人。这或许就是创客精神最打动人的地方。