MicroPython 作為輕量級的 Python 實作,在物聯網和嵌入式系統開發中扮演著重要的角色。本文著重探討 MicroPython 在紅外線和無線電通訊技術的應用,比較兩者在傳輸距離、功耗和應用場景上的差異。紅外線通訊部分,以 Circuit Playground Express 開發板為例,示範如何利用內建的紅外線發射器和接收器,結合 Morse Code 實作訊息傳輸,並解析程式碼的關鍵部分,例如 Morse Code 編碼、PWM 輸出控制和訊號解碼。無線電通訊部分,則以 micro:bit 為例,講解無線電模組的引陣列態、訊息傳送與接收,並進一步探討如何利用 micro:bit 建立對等網狀網路,實作室內廣播系統等進階應用。
網路通訊技術與MicroPython的應用
紅外線與無線電通訊技術的比較
在物聯網(IoT)與嵌入式系統的世界中,裝置之間的通訊方式多種多樣。紅外線(Infrared, IR)與無線電(Radio Frequency, RF)是兩種常見的通訊技術。
紅外線技術利用紅外光來傳輸資料,通常需要直接視線(Line of Sight),且傳輸距離較短。紅外線遙控器就是一個典型的例子,它透過調變38 kHz的紅外光來編碼資料。Adafruit的Circuit Playground Express開發板內建了紅外線發射器和接收器,使得它能夠與電視或其他紅外線裝置進行通訊。
無線電通訊則使用無線電波,這是一種電磁輻射,類別似於可見光,但具有更長的波長。無線電波不需要直接視線,可以繞過障礙物,傳輸距離也更遠。無線電通訊透過調變無線電波的某個屬性(如振幅、相位或頻率)來編碼資料。micro:bit和ESP8266/32開發板都使用無線電通訊,但方式不同。micro:bit的網路功能簡單易懂,適合教育用途;而ESP8266/32開發板則具有TCP/IP堆積疊,可以透過IEEE 802.11標準(即WiFi)進行通訊,非常適合用於物聯網專案。
紅外線通訊協定與Morse Code
紅外線訊號透過調變38 kHz的紅外光來表示數位上的0和1。要使訊號具有意義,需要使用特定的通訊協定。製造商們定義了多種紅外線通訊協定,這些協定通常透過訊號變化之間的持續時間來表示資料。
Morse Code是一種經典的通訊編碼方式,它透過不同長度的訊號來表示字元。例如,字母“A”被編碼為“.-”(dit dah)。我們可以利用Morse Code來演示如何在兩個Circuit Playground Express開發板之間傳送和接收紅外線訊息。
Morse Code 編碼範例
import array
import pulseio
import board
# Morse Code 查表
MORSE_CODE_LOOKUP = {
"A": ".-",
"B": "-...",
"C": "-.-.",
"D": "-..",
"E": ".",
"F": "..-.",
"G": "--.",
"H": "....",
"I": "..",
"J": ".
---
",
"K": "-.-",
"L": ".-..",
"M": "--",
"N": "-.",
"O": "
---
",
"P": ".--.",
"Q": "--.-",
"R": ".-.",
"S": "...",
"T": "-",
"U": "..-",
"V": "...-",
"W": ".--",
"X": "-..-",
"Y": "-.--",
"Z": "--..",
"1": ".
---
-",
"2": "..
---
",
"3": "...--",
"4": "....-",
"5": ".....",
"6": "-....",
"7": "--...",
"8": "
---
..",
"9": "
---
-.",
"0": "
---
--",
}
def encode_message(msg):
words = msg.split(' ')
message_buffer = []
for word in words:
message_buffer.extend([8000, 8000]) # 表示新的單字
for character in word:
message_buffer.extend([4000]) # 表示新的字母
for val in MORSE_CODE_LOOKUP[character.upper()]:
if val == '-':
message_buffer.extend([2000]) # 表示dah
else:
message_buffer.extend([1000]) # 表示dit
return message_buffer
#### 內容解密:
此程式碼片段定義了一個函式 `encode_message`,用於將輸入的文字訊息轉換成Morse Code,並根據特定的時間間隔來表示不同的字元和單字。
1. `MORSE_CODE_LOOKUP` 字典用於查詢每個字母或數字的Morse Code表示。
2. `encode_message` 函式將輸入的訊息分割成單字和字母,並根據Morse Code規則將其轉換成對應的時間間隔序列。
3. 時間間隔的單位是微秒,其中 `1000` 微秒錶示 “dit”,`2000` 微秒錶示 “dah”,`4000` 微秒錶示字母之間的間隔,而兩個 `8000` 微秒的間隔表示單字之間的分隔。
### 網路通訊的未來與MicroPython
隨著物聯網技術的發展,裝置之間的通訊變得越來越重要。MicroPython作為一種輕量級的Python實作,為嵌入式系統提供了強大的網路功能。無論是紅外線還是無線電通訊,MicroPython都能提供簡潔易用的API,使得開發者能夠快速實作裝置之間的通訊。
#### 使用Plantuml圖表來說明紅外線通訊流程
```plantuml
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 使用Plantuml圖表來說明紅外線通訊流程
rectangle "紅外線訊號" as node1
rectangle "解碼訊號" as node2
rectangle "處理資料" as node3
node1 --> node2
node2 --> node3
@enduml
此圖示說明瞭紅外線通訊的基本流程:
傳送裝置發出紅外線訊號,接收裝置接收到訊號後進行解碼,提取出資料,最後根據資料執行對應的動作。
紅外線通訊技術實作與解析
紅外線通訊技術是一種常見的無線通訊方式,廣泛應用於各種裝置之間的資料傳輸。本文將探討如何使用 Circuit Playground Express 開發板實作紅外線通訊,並解析相關程式碼。
傳送端實作
傳送端的核心功能是將訊息轉換為摩斯密碼,並透過紅外線發射器傳送。以下是關鍵程式碼:
import array
import pulseio
import board
MORSE_CODE_LOOKUP = {
'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.',
'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.
---
',
# ... 其他字母與數字的摩斯密碼對應
}
def encode_message(message):
message_buffer = []
words = message.split()
for word in words:
for char in word.upper():
if char in MORSE_CODE_LOOKUP:
for symbol in MORSE_CODE_LOOKUP[char]:
if symbol == '.':
message_buffer.extend([1000]) # 表示 dit
else:
message_buffer.extend([2000]) # 表示 dah
message_buffer.extend([4000]) # 字元間隔
message_buffer.extend([8000]) # 詞間隔
message_buffer.extend([8000, 8000]) # 訊息結束標記
return array.array('H', message_buffer)
ir_led = pulseio.PWMOut(board.REMOTEOUT, frequency=38000, duty_cycle=2**15)
ir_out = pulseio.PulseOut(ir_led)
message = encode_message("HELLO WORLD")
ir_out.send(message)
內容解密:
- MORSE_CODE_LOOKUP:定義了字母與數字的摩斯密碼對應表。
- encode_message 函式:將輸入的訊息轉換為摩斯密碼,並產生對應的時序陣列。
- 將訊息分割成單字和字元。
- 根據摩斯密碼規則,將每個字元轉換為對應的 dit 和 dah 序列。
- 使用不同的時間間隔來區分字元和詞。
- pulseio.PWMOut:設定紅外線發射器的 PWM 輸出,頻率為 38 kHz。
- pulseio.PulseOut:使用 PWMOut 物件建立 PulseOut 物件,用於傳送紅外線訊號。
接收端實作
接收端的主要任務是接收紅外線訊號,並將其解碼為原始訊息。以下是關鍵程式碼:
import array
import pulseio
import board
import time
MORSE_CODE_LOOKUP = {
'.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D', '.': 'E',
# ... 其他摩斯密碼對應的字母與數字
}
VALID_VALUES = (1000, 2000, 4000, 8000)
def normalise(raw):
for val in raw:
rounded_val = round(val/1000) * 1000
if rounded_val in VALID_VALUES:
yield rounded_val
def decode_message(normalised):
words = []
characters = []
tokens = []
for val in normalised:
if val == 8000:
# 新的詞
if tokens:
characters.append(get_character(tokens))
if characters:
words.append(''.join(characters))
tokens = []
characters = []
elif val == 4000:
# 新的字元
if tokens:
characters.append(get_character(tokens))
tokens = []
elif val == 2000:
tokens.append('-') # dah
elif val == 1000:
tokens.append('.') # dit
return ' '.join(words).strip()
ir_in = pulseio.PulseIn(board.REMOTEIN, maxlen=512, idle_state=False)
while True:
while len(ir_in) == 0:
time.sleep(1)
ir_in.pause()
raw = [ir_in[i] for i in range(len(ir_in))]
normalised = normalise(raw)
msg = decode_message(normalised)
if msg:
print(msg)
ir_in.clear()
ir_in.resume()
內容解密:
- normalise 函式:將接收到的原始訊號值正規化,使其符合預期的時間間隔(1000、2000、4000、8000 微秒)。
- decode_message 函式:將正規化的訊號解碼為原始訊息。
- 根據不同的時間間隔,區分 dit、dah、字元間隔和詞間隔。
- 將摩斯密碼序列轉換回字母或數字。
- pulseio.PulseIn:用於接收紅外線訊號,儲存訊號的時序資料。
微位元無線電模組詳解與應使用案例項
微位元(micro:bit)的無線電模組提供了一種簡便的方式來實作裝置間的無線通訊,支援廣播和接收訊息,並可根據位址和群組進行訊息過濾。無線電模組的資料傳輸速率預設為1 MB每秒,並可透過API進行多項引陣列態,如頻道、發射功率、位址和群組等,以滿足不同的應用需求。
無線電模組的基本操作
使用無線電模組前,需先將其開啟(radio.on()),否則無法傳送或接收訊息。當不需要使用無線電功能時,應將其關閉(radio.off())以節省能源。傳送和接收訊息可以透過字串或位元組(bytes)進行,提供了很大的靈活性。
引陣列態
無線電模組的引陣列態可透過radio.config(**kwargs)函式實作,主要引數包括:
length:定義訊息的最大長度(預設32位元組,最大251位元組)。queue:指定訊息佇列中可儲存的訊息數量(預設3)。channel:設定無線電頻道(預設7,可設定範圍0-100)。power:調整發射訊號的強度(預設6)。address:設定一個32位元的位址用於過濾接收的訊息包(預設0x75626974)。group:與位址結合使用的8位元值,用於進一步過濾訊息(預設0)。data_rate:設定資料傳輸速率(預設1 MB)。
若無線電模組進入異常狀態,可使用radio.reset()還原至預設設定。
簡單的傳送與接收範例
以下是一個簡單的範例,展示如何組態無線電模組、傳送和接收訊息:
from microbit import *
import radio
# 設定無線電頻道為42
radio.config(channel=42)
# 開啟無線電
radio.on()
while True:
sleep(20)
# 若按鈕A被按下,傳送訊息"Hello"
if button_a.was_pressed():
radio.send("Hello")
# 接收訊息
msg = radio.receive()
if msg:
# 在顯示器上滾動顯示接收到的訊息
display.scroll(msg, 80, wait=False)
這個範例展示了一個簡單的事件驅動程式,監測按鈕A的按下事件來傳送訊息,並在每次迴圈迭代中檢查是否有新訊息到達。
進階應用:對等網狀網路
微位元無線電模組的一個重要應用是建立對等網狀網路(peer-to-peer mesh network)。在這個網路中,每個裝置都可以傳送和接收訊息,並將收到的訊息重新廣播給其他裝置,從而實作訊息在整個網路中的傳播。
例項:室內廣播系統
假設在房屋的不同房間中放置多個微位元裝置,並為每個裝置分配一個名稱(如“廚房”、“浴室”等)。每個裝置都有一個預設的訊息列表,可以透過按鈕A選擇不同的訊息,按鈕B傳送選定的訊息。裝置收到訊息後,會在顯示器上滾動顯示訊息內容和傳送者名稱,並將訊息重新廣播。
為了避免無限迴圈的廣播,需要維護一個簡易的訊息快取,記錄最近收到的訊息及其時間戳。收到重複訊息時,若該訊息存在於快取中,則忽略該訊息;否則,將其加入快取並重新廣播。
程式碼範例
import radio
from microbit import *
# 組態無線電引數
radio.config(length=64)
# 開啟無線電
radio.on()
# 裝置名稱
device_name = "客廳"
# 預設訊息列表
messages = [
"電視可用。",
"需要火爐用的木柴。",
"火爐需要清潔。",
"火爐燒得很旺!",
"有零食可用。",
"是",
"否",
]
# 簡易的事件處理迴圈
while True:
# 省略具體實作...
pass
這個範例展示瞭如何利用微位元無線電模組建立一個簡單的對等網狀網路,實作多個裝置之間的無線通訊和協同工作。
#### 內容解密:
- 微位元無線電模組 提供了一種方便的方式來實作裝置間的無線通訊。
- 引陣列態 可透過
radio.config(**kwargs)函式實作,用於調整無線電的工作模式。 - 簡易範例 展示了基本的傳送和接收功能。
- 對等網狀網路 的應用展示了微位元裝置之間的協同工作能力。
- 室內廣播系統 的例項說明瞭如何利用微位元建立實際應用系統。