iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

ESP32 Micropython 從入門到實用系列 第 19

19.紅外線遙控接收

  • 分享至 

  • xImage
  •  

紅外線遙控在家電的使用非常的普遍,主要利用紅外線 LED 來發射大約在 940nm 波長的紅外線以傳送訊息,詳細的說明可以參閱 wiki 有關紅外線遙控的部分。

有時候,當遙控器不動作的時候,我們常常會看看是否遙控器發出了紅外光,這時候我們可以使用手機的攝影功能來看 LED,請看 這篇文章:用手機看紅外線 的說明。由於在週遭的環境中有紅外線的產生,因此干擾的雜訊也不少。

在變頻風扇 DIY 實作的專案中,我們只使用到接收的部分,因此在 Micropython 程式上,我們也只考慮到從遙控器上接收紅外線信號。

我看到很多書或文章指出,使用 Python 語言最主要的原因之一是開發快速,而且又有豐富的程式庫可以用,當然,這代表前人的貢獻很多,我們是站在巨人的肩膀上面。然而,Micropython 並未到達這個地步,目前支援的驅動或是程式庫還很有限,比較齊全的反而是 Adafruit 的 CircuitPython,畢竟 Adafruit 也在銷售各式各樣的感測器元件,也有詳細的教學。這也是我常常引導您善用 google 搜索,並且選取您使用的感測器規格書,以及評估可用的驅動模組,這有些好處,很多感測器並不見得相容,您多看看這些訊息,會逐漸增強您 DIY 的功力,而不只是 copy & paste 而已。

紅外線遙控器的發射與接收,必須是遵循著某些通信協議,這樣彼此才能溝通。但非常可惜的是,這樣的通信協議並沒有一個國際標準,通常是廠商的 de facto standard,所以我們常聽說的有 Philip 的,有 NEC 的,有 Sony 的,...,等等。我們今天主要以 NEC 的紅外線遙控器協議來說明。

NEC 協議使用的是 38K 的載波,因此我們可以把非 38K 頻率的信號都當作是雜訊,這樣就可以大幅的過濾掉雜訊,而且這樣的功能已經被整合成 IC 了:
https://ithelp.ithome.com.tw/upload/images/20231004/20140037zknee1eOwf.png
而最便宜的莫過於 VS1838 這個型號的 紅外線感測器元件,這元件看起來有三枝腳,但其實已經是積體電路(IC)。
我們從 VS1838 的規格書看應用電路節錄如下:
https://ithelp.ithome.com.tw/upload/images/20231004/20140037kUP2yykO4Z.png
標示 >20K 歐姆的是上拉電阻,這部分越靠近開發板越好,100 歐姆是供電給紅外線 IC 的電源保護,我們有時候會將紅外線感測器拉出一段距離,以便接收到訊號,在這麼常的距離裡,若是拉出的電線有短路,這 100 歐姆的電阻也起到了保護的作用,因此這電阻也是越接近開發板越好。至於有兩個電容,主要是電源與訊號濾波之用,這部分是越接近紅外線元件越好。其實,在實驗中,接線到麪包板,這些電阻與電容都沒接,應該也沒關係!

我們上網搜尋 “micropython remote control" 或者中文 "micropython 紅外線遙控",可以查到很多訊息,我建議您可以參考一下兩個教學:

接下來,我們把 VS1838 紅外線感測器的 OUT 接腳,連接到 ESP32-S3 的 GPIO 2,依照上面兩個教材說明,看看您是否可以把 VS1838 用起來!

Micropython 紅外線遙控器程式庫模組補充說明

前面兩個說明教材,不約而同的使用了 Micripython 大神級的開發者 Peter Hinch 所開發出來的程式庫模組:micropython_ir。這位大神的 Github 也有許多其它的寶藏等着您去探索。

我這裡列出 https://github.com/peterhinch/micropython_ir/blob/master/ir_rx/init.py 的程式碼:

# ir_rx __init__.py Decoder for IR remote control using synchronous code
# IR_RX abstract base class for IR receivers.

# Author: Peter Hinch
# Copyright Peter Hinch 2020-2021 Released under the MIT license

from machine import Timer, Pin
from array import array
from utime import ticks_us

# Save RAM
# from micropython import alloc_emergency_exception_buf
# alloc_emergency_exception_buf(100)


# On 1st edge start a block timer. While the timer is running, record the time
# of each edge. When the timer times out decode the data. Duration must exceed
# the worst case block transmission time, but be less than the interval between
# a block start and a repeat code start (~108ms depending on protocol)

class IR_RX():
    # Result/error codes
    # Repeat button code
    REPEAT = -1
    # Error codes
    BADSTART = -2
    BADBLOCK = -3
    BADREP = -4
    OVERRUN = -5
    BADDATA = -6
    BADADDR = -7

    def __init__(self, pin, nedges, tblock, callback, *args):  # Optional args for callback
        self._pin = pin
        self._nedges = nedges
        self._tblock = tblock
        self.callback = callback
        self.args = args
        self._errf = lambda _ : None
        self.verbose = False

        self._times = array('i',  (0 for _ in range(nedges + 1)))  # +1 for overrun
        pin.irq(handler = self._cb_pin, trigger = (Pin.IRQ_FALLING | Pin.IRQ_RISING))
        self.edge = 0
        self.tim = Timer(-1)  # Sofware timer
        self.cb = self.decode

    # Pin interrupt. Save time of each edge for later decode.
    def _cb_pin(self, line):
        t = ticks_us()
        # On overrun ignore pulses until software timer times out
        if self.edge <= self._nedges:  # Allow 1 extra pulse to record overrun
            if not self.edge:  # First edge received
                self.tim.init(period=self._tblock , mode=Timer.ONE_SHOT, callback=self.cb)
            self._times[self.edge] = t
            self.edge += 1

    def do_callback(self, cmd, addr, ext, thresh=0):
        self.edge = 0
        if cmd >= thresh:
            self.callback(cmd, addr, ext, *self.args)
        else:
            self._errf(cmd)

    def error_function(self, func):
        self._errf = func

    def close(self):
        self._pin.irq(handler = None)
        self.tim.deinit()

您可以看出,在 IR_RX class 中使用了 Timer,使用了 GPIO 中斷等等,是否覺得有點熟悉呢?或許您慢慢的這些程式就全看懂了,甚至還有能力修改!


上一篇
18.GPIO驅動能力
下一篇
20.連接外部週邊的匯流排-I2C
系列文
ESP32 Micropython 從入門到實用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言