树莓派学习手记——制作一个空调遥控器(红外接收、发射的实现)

对博客平台有些失望,转语雀只当留档用了。

使用树莓派搭配红外管,进行接收、发射红外信号是很方便的,同时红外信号也有很广泛的用途。这次我们将总结使用树莓派制作一个空调红外遥控器的过程。

准备工具

  • 红外接收管(参考型号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_codesend 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 offname 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

空调会:

  1. 温度提升到25℃
  2. “滴”地响一声,然后什么都没发生,保持在24℃

很遗憾,后者发生了。

实际上遥控器每按下一次按钮发送的信息是一个“情景”,我刚才录制的 add 按钮实际上是表示“温度设为24℃、进入制冷模式、风速设为自动...”这样的一个“情景”。如果你在空调温度20℃时运行add命令,那么它就会一次性提升到24℃!

这意味着,如果你想要设置任意温度,你需要把每一度都录制一遍,因为 +- 命令根本就不存在。

当然,这也不全是坏事。

我录制了一个按钮 26C ,功能是将温度调到26℃。然后我意识到, 26C 这个按钮同时包含了开关状态的信息。是的!在空调关闭的情况下,如果我直接发送命令:

irsend SEND_ONCE aircon 26C

那么空调会打开,并且调整到26℃!

于是,我录制了一个按钮 Sleep ,它将空调设置为“26℃、风速设为低、开启扫风、开启静音睡眠模式”。睡前运行一次 irsend SEND_ONCE aircon Sleep ,感觉离智能家居又近了一步 23333 (•̀ω•́)✧。

小结

其实写完这篇总结还是有点慌的,因为不管是树莓派版本、软件版本、红外管型号还是空调的型号,大家都是不一样的,说不准哪一步我这么做放别人那就是错的呢。事实上,我自己在做的过程中参考的一些博客就和我的实际情况有些出入了。只能希望这篇总结能够有一定的参考价值。最后,感谢你阅读文章!

阅读 21.2k

推荐阅读
学习笔记
用户专栏

与你分享学习过程中的收获。

19 人关注
15 篇文章
专栏主页