带 3D 打印外壳的电池供电电视遥控器
组件和用品
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 4 | |||
![]() |
| × | 3 | |||
| × | 4 | ||||
| × | 3 | ||||
![]() |
| × | 2 | |||
| × | 1 | ||||
| × | 6 | ||||
![]() |
| × | 1 |
必要的工具和机器
![]() |
| |||
![]() |
| |||
![]() |
| |||
|
关于这个项目
简介
我女朋友的电视遥控器坏了。她本可以在附近的商店买一个便宜的替代品,但后来她想:我们都是工程师,让我们一起做一个吧!
由于我们的技能非常互补,这是一种在锁定期间度过的不同但有趣的方式,它让我们有机会了解这项日常技术的工作原理。
哦,家里有一台小型 3D 打印机也起到了作用。
工作原理
首先,由于我们想根据 Arduino UNO 进行简单的设计,因此我们评估了操作电视所需的最少命令数。我们认为 6 个命令就足够了:ON/OFF 切换、源选择、Ch+、Ch-、Vol+、Vol-。
按钮阅读
为了避免使用额外的电阻器,该设计依赖于 Arduino 的内部上拉电阻器。如果遥控器未处于睡眠模式(见下文),则在每个循环周期中轮询每个按钮状态。为了避免计算多次命中,利用 millis()
实现了一个简单的去抖动例程 功能。
发送红外信号
红外通信由IRremote.h
处理 库(感谢编码人员!)。我们所要做的就是为我们的电视设置协议(不同的制造商已经开发了他们自己的协议)并在 Google 上搜索我们想要使用的不同命令的十六进制代码并将它们关联到按钮。由于涉及电路设计,为了让库中的命令有效地引导 IR LED,必须将其连接到 Arduino UNO 的 pin3。
目前,代码是为三种不同类型的电视编写的,可以通过注释/取消注释 #define
来选择 代码第一部分中的指令。
电池 保存
为了降低功耗,实施了一些策略,利用来自 avr/sleep.h
的命令 和 avr/power.h
图书馆。
在设置程序中关闭所有未使用的外设和接口(ADC、SPI、TWI、timer1、usart)。 PWM pin13 上的内置 LED 也关闭。我们还决定拆焊 Arduino UNO 的电源 LED,否则它总是亮着,尽管这不是推荐的操作。
此外,利用 millis()
, 如果 5 秒内没有按下任何按钮,遥控器将进入睡眠模式,再次按下开/关按钮时会唤醒该模式。
它是如何构建的
电子 组装
整个电路嵌入在原型板上,设计用于安装在 Arduino UNO 接头上。通过使用烙铁,根据遥控器上的最终位置焊接按钮。在底部,两个 47 欧姆电阻并联焊接,以达到通过 IR LED 的所需电流。
使用焊锡丝,在原型板上制作走线,将按钮引脚和红外 LED 连接到公排针。
通过这种方式,该板类似于一个使用排针安装在 Arduino UNO 上的屏蔽,确保所有正确的连接。
外壳 CAD 和 摄像头
外壳设计用于容纳电池、Arduino UNO + 原型板组件,仅暴露顶部的按钮和正面的 IR LED。
外壳由两部分组成,使用 SolidWorks CAD 软件设计,使用 Ultimaker Cura 切片软件进行预处理,最后使用 Anycubic Mega Zero 3D 打印机在 PLA 中进行 3D 打印。
Arduino UNO 使用 3 个 M2.5 螺钉固定在底座上,螺钉安装在底座内侧挤出的对齐孔中。固定好 Arduino 后,IR LED 将突出到原型板外,以便将其与专用内置孔对齐并在组装外壳的两个部分时将其保持在适当位置,添加了三个迷你柱以避免LED 引线的横向移动。电池压入专用空间。
盖子设计为只露出按钮,除了每个按钮外,盖子上还刻有一个符号来显示每个按钮的功能。
外壳的底座和盖子使用 4 个 M3 螺钉组装。
图片库




代码
- TV_remote.ino
TV_remote.inoArduino
#include#include #include // 引脚定义// IR LED 必须连接到 Arduino PWM 引脚 3#define OnOff 1# define Source 0#define CH_plus 4#define CH_minus 5#define Vol_plus 6#define Vol_minus 7#define Interrupt_Pin 2 //Arduino Uno 上只有 pin 2 或 3 // 电视模型定义//#define LG_TV//#define SAMSUNG_TV#define SONY_TV//代码定义#ifdef LG_TV unsigned long on_off_code =551489775; // HEX 20DF10EF unsigned long vol_plus_code =551502015; //HEX 20DF40BF unsigned long vol_minus_code =551534655; //HEX 20DFC03F unsigned long ch_plus_code =551485695; //HEX 20DF00FF unsigned long ch_minus_code =551518335; //HEX 20DF807F unsigned long source_code =551538735; //HEX 20DFD02F#endif#ifdef SAMSUNG_TV unsigned long on_off_code =3772793023; // HEX E0E040BF unsigned long vol_plus_code =3772833823; //HEX E0E0E01F unsigned long vol_minus_code =3772829743; //HEX E0E0D02F unsigned long ch_plus_code =3772795063; //HEX E0E048B7 unsigned long ch_minus_code =3772778743; //HEX E0E008F7 unsigned long source_code =3772809343; //HEX E0E0807F#endif#ifdef SONY_TV unsigned long on_off_code =2704; //HEX A90 unsigned long vol_plus_code =1168; //HEX 490 unsigned long vol_minus_code =3216; //HEX C90 unsigned long ch_plus_code =144; //HEX 090 unsigned long ch_minus_code =2192; //HEX 890 unsigned long source_code =2640; //HEX A50#endif//启用调试//#define DEBUG//IRsend irsend; //创建IR对象unsigned long debounce_time;unsigned long last_time;void setup() {analogWrite(13,0); //关闭内置led //noInterrupts(); //禁用中断 //CLKPR =_BV(CLKPCE); //启用时钟预分频器设置 //CLKPR =_BV(CLKPS0); //设置时钟预分频器 =2 --> 8 MHz //interrupts(); pinMode(OnOff,INPUT_PULLUP); pinMode(Source,INPUT_PULLUP); pinMode(CH_plus,INPUT_PULLUP); pinMode(CH_minus,INPUT_PULLUP); pinMode(Vol_plus,INPUT_PULLUP); pinMode(Vol_minus,INPUT_PULLUP); pinMode(Interrupt_Pin,INPUT_PULLUP); //省电 power_adc_disable(); //禁用所有ADC power_spi_disable(); //禁用SPI power_timer1_disable(); //禁用定时器1(0代表millis(),2代表irmote.h) power_usart0_disable(); //禁用串行电源_twi_disable(); //禁用TWI #ifdef DEBUG Serial.begin(9600); #endif}void loop() { //检查 OnOff if (!digitalRead(OnOff)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(OnOff)) { #ifdef LG_TV irsend.sendNEC(on_off_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(on_off_code, 32); #endif #ifdef SONY_TV irsend.sendSony(on_off_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("OnOff"); #endif } } //检查源 if (!digitalRead(Source)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(Source)) { #ifdef LG_TV irsend.sendNEC(source_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(source_code, 32); #endif #ifdef SONY_TV irsend.sendSony(source_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("Source"); #endif } } //检查CH_plus if (!digitalRead(CH_plus)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(CH_plus)) { #ifdef LG_TV irsend.sendNEC(ch_plus_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(ch_plus_code, 32); #endif #ifdef SONY_TV irsend.sendSony(ch_plus_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("CH+"); #endif } } //检查CH_minus if (!digitalRead(CH_minus)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(CH_minus)) { #ifdef LG_TV irsend.sendNEC(ch_minus_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(ch_minus_code, 32); #endif #ifdef SONY_TV irsend.sendSony(ch_minus_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("CH-"); #endif } } //检查Vol_plus if (!digitalRead(Vol_plus)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(Vol_plus)) { #ifdef LG_TV irsend.sendNEC(vol_plus_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(vol_plus_code, 32); #endif #ifdef SONY_TV irsend.sendSony(vol_plus_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("Vol+"); #endif } } //检查Vol_minus if (!digitalRead(Vol_minus)) { debounce_time =millis(); while (millis() - debounce_time <40 ) {; } if (!digitalRead(Vol_minus)) { #ifdef LG_TV irsend.sendNEC(vol_minus_code, 32); #endif #ifdef SAMSUNG_TV irsend.sendSAMSUNG(vol_minus_code, 32); #endif #ifdef SONY_TV irsend.sendSony(vol_minus_code, 12); #endif last_time =millis(); //最后一次按下按钮 #ifdef DEBUG Serial.println("Vol-"); #endif } } if (millis()-last_time> 5000) { //一个按钮没有被按下 10 秒 #ifdef DEBUG Serial.println("Going to sleep..."); #endif going_to_sleep(); //进入睡眠模式#ifdef DEBUG Serial.println("醒来..."); #endif }}//睡眠模式functionvoid going_to_sleep() { sleep_enable(); //启用睡眠模式 attachInterrupt(digitalPinToInterrupt(Interrupt_Pin),wake_up, LOW); //中断唤醒-->将中断引脚配置为有线NOR!!! set_sleep_mode(SLEEP_MODE_PWR_DOWN); //完全睡眠模式 sleep_cpu(); //激活睡眠模式}//唤醒函数voidwake_up(){sleep_disable(); //禁用睡眠模式 detachInterrupt(digitalPinToInterrupt(Interrupt_Pin)); //去除中断}
定制零件和外壳
示意图

制造工艺