使用树莓派搭配红外管,进行接收、发射红外信号是很方便的,同时红外信号也有很广泛的用途。这次我们将总结使用树莓派制作一个空调红外遥控器的过程。
准备工具
- 红外接收管(参考型号HS0038B)
- 红外发射管(参考型号TSAL6200)
- 遥控器(或能使用万能遥控器的手机)
- 用作开关的三极管、限流电阻(非必须、参考型号S9013)
使用开关三极管可以有效增强红外发射管的性能,但不是必须的。不使用三极管也能在三五米范围内成功遥控空调。这些材料总共费用不超过1块钱,反而是快递费比较贵了。
看到遥控器、接收管、发射管,相信已经有人明白了制作遥控器的原理。是的,我们只需要事先把遥控器发射出的红外信号记录下来,然后通过树莓派依样画葫芦地把这个信号发射出去,一个“克隆”版的遥控器就做好了。
硬件连接
*注意:两个GPIO引脚是固定的,与后续安装的软件有关。
接收管信号输出脚 OUT → GPIO18
发射管正极(不使用开关三极管的情况下) → GPIO17
如果你手头上没有开关三极管,直接将红外发射管正极接在GPIO17,如下所示:
如果接入三极管,用GPIO17连接基极,控制发射极和集电极的通断:
(偷懒了没有接入限流电阻,在意的同学自行接入)
安装lirc
解决方案来自: LIRC: Linux Infrared Remote Control for Raspberry Pi
sudo apt update
sudo apt install lirc
修改CONFIG.TXT
修改文件 /boot/config.txt
:
sudo nano /boot/config.txt
找到 lirc-rpi module
的部分,修改为:
# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=18,gpio_in_pull=up
!!!注意:config.txt的配置内容,似乎根据不同Linux内核版本有微妙的变化,手头上暂时没有其他平台可以测试。如果后续测试时出问题,请Google关键词“lirc lirc-rpi gpio-ir”查阅相关资料。
修改驱动配置
修改文件 /etc/lirc/lirc_options.conf
:
sudo nano /etc/lirc/lirc_options.conf
# 把:
driver = devinput
device = auto
# 修改为:
driver = default
device = /dev/lirc0
最后,重启树莓派。
简单测试是否正常
# 必须停止lircd服务才能进入接收红外信号模式
sudo service lircd stop
mode2 -d /dev/lirc0
运行上述命令后,用遥控器对着接收管随便按一些按钮,如果出现形式如下的输出就表示正常:
space 16777215
pulse 8999
space 4457
pulse 680
space 1627
......
录入红外信号
解决方案来自: How to Control Your Air Conditioner with Raspberry Pi Board and ANAVI Infrared pHAT
lirc有一个自动录入红外信号、生成遥控器文件的功能。但此方法只适用于简单设备,比如风扇,这里就不记录过程了。有需要的直接运行 irrecord -d /dev/lirc0 --disable-namespace
,按提示做完后把生成的文件放到 /etc/lirc/lircd.conf.d/
目录就行了。
这边就主要针对空调这种复杂设备,记录录入红外信号的过程。
另外,简单了解一下红外NEC协议可以帮助你理解配置的过程。
为什么无法直接录制复杂设备的红外控制信号?
因为空调遥控器每次发送的信号不是单纯的一个"byte",与其说它是“控制信号”,不如说是一个“状态”、“情景”。后文还会有实例帮助你理解。
生成遥控器配置文件的样板
空调这类复杂设备的遥控器配置文件,是需要自己手动输入的。但不可能整个文件都自己写——我们连格式都不知道。
所以我们需要用刚才提到的自动录入功能生成一个样板,但请记住,这个样板中记录的信号极可能是不正确的!我们只是通过它来了解配置内容的格式。
开始自动录制:
# 请cd到有读写权限的目录下,因为需要创建一个遥控器配置文件
# 参数-f --force 表示 Force raw mode
irrecord -f -d /dev/lirc0 --disable-namespace
认真阅读提示信息,根据提示按Enter、输入 遥控器名称
、按Enter、按照要求随机按遥控器、输入 按钮名称
、按对应的遥控器按钮。由于只是为了生成样板,所以录制一个按钮就够了。完成录制后,当前目录下会生成一个遥控器配置文件 遥控器名称.lircd.conf
。
如果发现录制过程十分缓慢,最后提示“未发现gap”之类的信息,请尝试跳过自动生成这一步,复制下面的配置文件当做生成的配置,直接进入下一步。(我在录制一些老式空调的命令时遇到了这种问题,只能这样解决,如果你有什么想法恳请提出)
我在录制时输入的 遥控器名称
是aircon,录制的一个按钮是on,所以配置文件的内容形式如下:
begin remote
name aircon
flags RAW_CODES
eps 30
aeps 100
gap 19991
begin raw_codes
name on
9042 4438 700 1602 705 526
678 528 681 531 674 527
679 528 679 528 677 527
677 528 679 528 678 528
677 1632 676 529 676 531
676 531 649 556 672 532
650 558 654 552 652 553
649 558 648 1661 650 558
648 558 648 1661 649 562
644 558 647 558 648 1657
651 558 647 1659 650 557
653 553 648 1660 648 557
649
end raw_codes
end remote
如果你阅读了红外NEC协议,就能马上意识到,这一串数字其实就是红外信号脉冲(pulse)、空白(space)的持续时间。
手动编辑遥控器配置文件
打开刚才生成的样板文件 遥控器名称.lircd.conf
,很容易发现 begin raw_codes
和 end raw_codes
之间的内容就是需要我们手动修改的内容。刚才也提到过,样板中记录的信号极可能是不正确的,所以我们先把自动生成的 on
按钮下方的信号数据删除掉。
还记得刚才测试时使用的mode2命令吗。我们现在需要做的就是使用mode2命令接收遥控器发出的信号,然后将其加入到文件 遥控器名称.lircd.conf
中。首先,我们来录入正确的 on
按钮的信号数据:
# -m --mode 使用行列显示模式,不显示pulse、space
mode2 -m -d /dev/lirc0
按下遥控器上的“开”按钮,得到形式如下的输出:
16777215
9059 4432 706 1604 706 528
679 524 681 1603 703 526
680 1602 715 1596 704 526
679 527 679 527 680 527
679 1604 705 530 673 530
674 529 682 529 675 530
674 532 674 532 650 557
648 556 654 1653 676 533
649 559 647 1667 639 559
648 558 656 553 647 1658
648 558 650 1659 649 559
647 559 648 1659 648 558
646 19991
648 558 648 558 650 567
638 557 648 1668 640 557
649 558 650 558 646 1660
650 556 649 557 649 559
654 552 648 1657 651 558
647 554 660 549 649 559
647 557 649 559 648 559
647 557 644 561 648 559
648 556 647 560 648 556
652 563 642 1658 648 1661
649 1660 646 1658 650
除去第一行很大的那个数,把其他数据全部复制,粘贴到配置文件的 name on
下方。例如现在我必须删除“16777215”这个数,剩下的内容粘贴到配置文件的 name on
下方。
重复上述操作,增加更多的按钮,例如 name off
、 name 26C
等。最后我录制了3个按钮,配置文件编辑成了这样:
begin remote
name aircon
flags RAW_CODES
eps 30
aeps 100
gap 19991
begin raw_codes
name on
9059 4432 706 1604 706 528
679 524 681 1603 703 526
680 1602 715 1596 704 526
679 527 679 527 680 527
679 1604 705 530 673 530
674 529 682 529 675 530
674 532 674 532 650 557
648 556 654 1653 676 533
649 559 647 1667 639 559
648 558 656 553 647 1658
648 558 650 1659 649 559
647 559 648 1659 648 558
646 19991
648 558 648 558 650 567
638 557 648 1668 640 557
649 558 650 558 646 1660
650 556 649 557 649 559
654 552 648 1657 651 558
647 554 660 549 649 559
647 557 649 559 648 559
647 557 644 561 648 559
648 556 647 560 648 556
652 563 642 1658 648 1661
649 1660 646 1658 650
name off
9029 4432 715 1594 706 526
682 523 681 525 680 526
681 1601 708 1607 699 524
688 519 682 526 678 527
681 1601 708 524 687 520
682 525 677 527 677 529
675 531 676 531 674 532
651 558 646 1659 650 557
648 557 650 1659 653 554
650 559 647 558 649 1657
649 558 648 1661 648 557
646 562 645 1666 643 558
649 19992
651 555 650 558 648 562
645 557 648 1661 653 552
646 560 650 557 648 1657
649 561 647 557 647 558
650 556 650 1659 649 559
647 557 649 558 648 559
647 557 651 564 642 559
646 557 649 557 657 552
647 557 648 558 650 557
645 560 653 1653 646 1661
650 1659 648 558 647
name 26C
9026 4430 705 1604 706 528
679 535 670 1604 705 527
675 532 679 1607 702 530
673 531 683 1625 672 535
672 1633 676 530 673 534
649 558 648 563 642 556
651 556 650 558 672 532
649 556 652 1659 648 558
656 551 646 1659 650 558
648 558 648 558 649 1658
649 561 648 1659 647 559
650 556 648 1660 646 559
647 19990
648 1659 649 558 648 558
647 558 650 1658 650 557
650 555 650 558 648 558
649 555 652 561 667 534
648 559 648 1658 656 550
650 557 672 533 649 555
650 559 649 558 647 559
648 558 648 566 641 558
647 558 648 558 650 558
648 558 648 1660 646 558
648 558 646 562 647
end raw_codes
end remote
是的,如果你想要实现完整的控制,你就需要把所有按钮都录制一遍。如果你对配置文件中开头的eps、aeps等参数感兴趣,或者最后遥控不太正常,阅读lircd.conf manual或许能帮到你。我使用的是默认的数值,一切工作正常。
最后,把配置文件复制到指定目录 /etc/lirc/lircd.conf/
并重启lircd服务:
sudo cp aircon.lircd.conf /etc/lirc/lircd.conf.d/
sudo service lircd restart
*后续步骤出现问题的同学可以使用service lircd status查看服务启动的log,帮助定位bug。
发射信号
终于,我们可以尝试着使用树莓派控制空调了。如果你没有使用开关三极管,你可能需要把树莓派拿到靠近空调的地方,并且把红外发射管对准空调。如果你使用了三极管,那么注意树莓派和空调之间不要有明显的物体阻隔即可。
# 发射命令:irsend SEND_ONCE 遥控器名称 按钮名称
irsend SEND_ONCE aircon on
如果前面的步骤一切正常,但在发射信号时报错“transmission failed”。请检查生成的遥控器配置文件,查看flags项,若是flags RAW_CODES|CONST_LENGTH
,请尝试将其修改成flags RAW_CODES
并重启lircd服务。再测试能否发射信号。
按钮?不如说是情景
最后,我们来讨论一个比较有意思的东西。
考虑一下这种情况:我为了录入 +
按钮,运行mode2命令开始录制。在遥控器显示温度23℃时按 +
,然后按照前面的方法编辑配置文件,写入了按钮 name add
。
此时空调屏幕上显示温度是24℃。提问:如果我运行
irsend SEND_ONCE aircon add
空调会:
- 温度提升到25℃
- “滴”地响一声,然后什么都没发生,保持在24℃
很遗憾,后者发生了。
实际上遥控器每按下一次按钮发送的信息是一个“情景”,我刚才录制的 add
按钮实际上是表示“温度设为24℃、进入制冷模式、风速设为自动...”这样的一个“情景”。如果你在空调温度20℃时运行add命令,那么它就会一次性提升到24℃!
这意味着,如果你想要设置任意温度,你需要把每一度都录制一遍,因为 +
、 -
命令根本就不存在。
当然,这也不全是坏事。
我录制了一个按钮 26C
,功能是将温度调到26℃。然后我意识到, 26C
这个按钮同时包含了开关状态的信息。是的!在空调关闭的情况下,如果我直接发送命令:
irsend SEND_ONCE aircon 26C
那么空调会打开,并且调整到26℃!
于是,我录制了一个按钮 Sleep
,它将空调设置为“26℃、风速设为低、开启扫风、开启静音睡眠模式”。睡前运行一次 irsend SEND_ONCE aircon Sleep
,感觉离智能家居又近了一步 23333 (•̀ω•́)✧。
小结
其实写完这篇总结还是有点慌的,因为不管是树莓派版本、软件版本、红外管型号还是空调的型号,大家都是不一样的,说不准哪一步我这么做放别人那就是错的呢。事实上,我自己在做的过程中参考的一些博客就和我的实际情况有些出入了。只能希望这篇总结能够有一定的参考价值。最后,感谢你阅读文章!