プライベート LoRa 通信は、通信距離が従来の通信方式と比較して長い、LPWA(Low Power Wide Area「低消費電力広域通信」)規格の一つです。
実習では、ラズパイPicoWに接続したLoRa通信モジュール(E220-900T22S(JP))を親機と子機として2セット用意し、テキストデータを親子機器間で送受信しながら、現在時刻と電波強度(RSSI)を子機のOLEDディスプレイに表示します。
送受信の確認方法について
親機と子機の送信手順を次のように行います。
- 子機から親機に64バイトのテキストデータ(0123456789abcd・・・)を送信します。
- 親機は受信したデータが正しいかどうかを判定し、正しい場合はLEDを点灯させます。その後、内部で動作している時計の情報(現在時刻)と、電波強度(RSSI)を子機の送信します。
- 子機は受信した経過時間と電波強度(RSSI)の内容に応じて、LEDを点灯させます。受信したデータはOLED(有機ELディスプレイ)に表示した後、親機に先ほどそうした64バイトのテキストデータと異なったデータ(abcd・・・0123456789)を送信します。
- 親機は受信したデータが正しいかどうかを判定し、正しい場合はLEDを消灯させます。その後、内部で動作している時計の情報(現在時刻)と、電波強度(RSSI)を子機の送信します。
- 子機は受信した経過時間と電波強度(RSSI)の内容に応じて、LEDを消灯させます。受信したデータはOLED(有機ELディスプレイ)に表示した後、親機に最初に送信した64バイトのテキストデータと異なったデータ(0123456789abcd・・・)を送信します。
- 1~5を繰返します。
実験準備
実験に必要な環境や部品を準備します。
機器
「ラズパイPicoWを始めよう。」記事で書きました、MicroPythonファームウェアをインストールしたラズパイPicoWと、統合開発環境ThonnyをインストールしたRaspi4Bを準備します。
親機、子機の2セットが必要です。
使う部品
LoRaモジュールなど実験に使う部品を準備します。
部 品 名 | 規 格 | 数 量 | 取扱い店(参考) |
LoRa通信モジュール評価ボード | E220-900T22S(JP)-EV1 | 2 | 秋月電子通商 |
LoRa用アンテナ | TX915-JKS-20 | 2 | 秋月電子通商 |
有機ELディスプレイ(OLED) 白色 (子機のみ使用) | SSD1306 | 1 | 秋月電子通商 |
ブレッドボード | BB-102 | 2 | 秋月電子通商 |
ジャンパーワイヤ | 14種類×10本 | 1 | 秋月電子通商 |
配線
準備した機器と部品を、配線リストと配線図を参考にして接続します。
配線リスト
次の配線を行います。
▶️親機の配線
From | To |
ラズパイPicoW(GND) | LoRa通信モジュール(GND) |
ラズパイPicoW(3V3) | LoRa通信モジュール(VCC) |
ラズパイPicoW(GP27) | LoRa通信モジュール(M1) |
ラズパイPicoW(GP26) | LoRa通信モジュール(M0) |
ラズパイPicoW(GP18) | LoRa通信モジュール(AUX) |
ラズパイPicoW(GP17) | LoRa通信モジュール(TXD) |
ラズパイPicoW(GP16) | LoRa通信モジュール(RXD) |
▶️子機の配線
親機の配線に、新たに有機ELディスプレイ(OLED) を追加して配線をします。
From | To |
ラズパイPicoW(GND) | 有機ELディスプレイ(GND) |
ラズパイPicoW(3V3) | 有機ELディスプレイ(VCC) |
ラズパイPicoW(GP21) | 有機ELディスプレイ(SCL) |
ラズパイPicoW(GP20) | 有機ELディスプレイ(SDA) |
ラズパイPicoW(GP28) | ラズパイPicoW(GND) |
配線図
データ送受信プログラムの実行
テキストデータを親子機器間で送受信しながら、現在時刻と電波強度(RSSI)が、継続的に子機のOLEDディスプレイに表示されることを確認します。
Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。
▶️親機のコード
#LoRaモジュール 親機 (Raspberry Pi Pico W)
##################################################
#
# モジュールの読み込み
#
##################################################
from machine import Pin
from machine import UART
import utime
import struct
##################################################
#
# グローバル変数
#
##################################################
#RSSIバイト (1:有効、0:無効)
GLBL_RSSI_BYTE = 1
##################################################
#
# モジュール自アドレス選択(下位アドレス)
#
##################################################
#1:0x00,0x00 0:0x00.0x01
LOW_ADRS_SEL = Pin(28, Pin.IN, Pin.PULL_UP)
##################################################
#
# Pico W上のLED
#
##################################################
led = Pin("LED", Pin.OUT)
##################################################
#
# モジュールのピン
#
##################################################
AUX = 18
M0 = 26
M1 = 27
TXD = 17 #(UART0 RX)
RXD = 16 #(UART0 TX)
#AUXピン
LR_AUX = Pin(AUX,Pin.IN)
#M0ピン
LR_M0 = Pin(M0,Pin.OUT)
#M1ピン
LR_M1 = Pin(M1,Pin.OUT)
##################################################
#
# モジュールの初期設定
#
##################################################
def lora_initst():
######設定レジスタパラメータを設定######
#Config/DeepSleepモード(mode 3)に設定
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
LR_M0.value(1)
LR_M1.value(1)
#UART設定
urt = UART(0, 9600, tx=Pin(RXD), rx=Pin(TXD))
urt.init(9600, bits=8, parity=None, stop=1)
#設定レジスタにパラメータを設定
#書込コマンド(0xC0)、スタートアドレス(0x00)、書込数(0x08)
CMD = [0xC0, 0x00, 0x08]
#レジスタ-00(ADR_H):自デバイスの上位アドレス(0x00)
ADR_H = 0x00
CMD.append(ADR_H)
#自アドレス選択(下位アドレス)
if LOW_ADRS_SEL.value() == 1:
#レジスタ-01(ADR_L):デバイスの下位アドレス(0x00)
ADR_L = 0x00
CMD.append(ADR_L)
else:
#レジスタ-01(ADR_L):デバイスの下位アドレス(0x01) 送信先アドレス
ADR_L = 0x01
CMD.append(ADR_L)
#レジスタ-02(REG0):ボーレート(9600)、帯域幅設定(BW:125)、拡散率設定(SF:9)
REG0 = 0x70
CMD.append(REG0)
#レジスタ-03(REG1):ペイロード長(64byte)、RSSI環境ノイズ(無効)、未使用、送信出力(13dBm)
REG1 = 0x81
CMD.append(REG1)
#レジスタ-04(REG2):自周波数チャンネル(0)
REG2 = 0x00
CMD.append(REG2)
#レジスタ-05(REG3):RSSIバイト(有効)、 送信方法(通常 Fixed-block)、未使用、
#低電圧動作(無効)、WORサイクル(3000ms)
REG3 = 0xC5
CMD.append(REG3)
#レジスタ-06:暗号化キー上位バイト(0)
ENCRYPT_H = 0x00
CMD.append(ENCRYPT_H)
#レジスタ-07:暗号化キー下位バイト(0)
ENCRYPT_L = 0x00
CMD.append(ENCRYPT_L)
#パラメータ設定値確認
#print("パラメータの設定値")
#設定値表示
#disp = ""
#for prm in CMD:
#disp = disp + str(hex(prm)) + "/"
#print(hex(prm))
#print(disp)
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#書込
for val in CMD:
dat = struct.pack("B", val)
urt.write(bytes(dat))
#utime.sleep(0.002)
utime.sleep_ms(1000)
######設定レジスタパラメータを読出######
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#Config/DeepSleepモード(mode 3)に設定
LR_M0.value(1)
LR_M1.value(1)
utime.sleep_ms(200)
#読出コマンド(0xC1)、スタートアドレス(0x00)、読出数(0x08)
CMD = [0xC1, 0x00, 0x08]
rspns = bytes()
#モジュールにコマンドを書込
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#書込
for val in CMD:
dat = struct.pack("B", val)
urt.write(bytes(dat))
#utime.sleep(0.002)
utime.sleep_ms(1000)
#パタメータを読込
while urt.any() != 0 :
rspns = urt.read(urt.any())
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
LR_M0.value(0)
LR_M1.value(0)
return urt
##################################################
#
# 送信
#
##################################################
def lora_transmission(urt,txdt):
#送信先上位アドレス(0x00)
TX_ADR_H = 0x00
#送信先アドレス選択(下位アドレス)
if LOW_ADRS_SEL.value() == 1:
#送信先下位アドレス(0x01)
TX_ADR_L = 0x01
else:
#送信先下位アドレス(0x00)
TX_ADR_L = 0x00
#送信先チャンネル(0x01)
CHNL= 0x01
#送信データにアドレスとチャンネルを設定
payload = bytes([TX_ADR_H, TX_ADR_L, CHNL])
#テストデータを設定
payload = payload + txdt.encode("utf-8")
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#送信
for dat in payload:
bdat = struct.pack("B", dat)
urt.write(bytes(bdat))
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
return
##################################################
#
# 受信
#
##################################################
def lora_receive(urt):
#print("受信中...")
payload = bytes()
#データ受信待ち
while LR_AUX.value() != 0:
utime.sleep_ms(1)
#受信開始待ち時間
utime.sleep_ms(3)
#RSSI初期化
rssi = 0
#受信開始待ち
while True:
if urt.any() != 0:
#受信データ読込
payload = payload + urt.read()
elif urt.any() == 0 and len(payload) != 0:
if GLBL_RSSI_BYTE ==1:
#受信データ(RSSIバイト削除)
rcv_dara = payload[:-1]
#RSSIバイト有効
rssi = int(payload[-1]) - 256
#print("RSSI: {0} dBm".format(rssi))
break
else:
#受信データ
rcv_dara = payload
#RSSIバイト無効
#print("受信完了(RSSIバイト無効)")
#print(payload)
break
rcv_dara = rcv_dara.decode("utf-8")
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
return rcv_dara, rssi
##################################################
#
# メイン
#
##################################################
#LED消灯
led.value(0)
#モジュールの初期設定
urt = lora_initst()
utime.sleep_ms(2000)
while True:
#ローカル時刻設定
lcl_tm= utime.localtime()
tm = ("%2d:%02d:%02d" % (lcl_tm[3:6]))
#時刻表示
#print("受信 "+ tm)
#受信
rcv_data, rssi = lora_receive(urt)
#print(rcv_data)
#送信データ
txdt = tm + str(rssi)
if rcv_data == "012345678abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
#LED消灯
led.value(1)
lora_transmission(urt,txdt + "0")
if rcv_data == "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678":
#LED点灯
led.value(0)
lora_transmission(urt,txdt + "1")
▶️子機のコード
事前に有機ELディスプレイ SSD1306(OLED)用のモジュール「ssd1306」をこちらからダウンロードして、ラズパイPicoWの「libフォルダ」に保存してください。
#LoRaモジュール 子機 (Raspberry Pi Pico W)
##################################################
#
# モジュールの読み込み
#
##################################################
from machine import Pin
import utime
#LoRaモジュール通信用
from machine import UART
import struct
#有機ELディスプレイ SSD1306(OLED)用
from machine import I2C
from ssd1306 import SSD1306_I2C
##################################################
#
# グローバル変数
#
##################################################
#RSSIバイト (1:有効、0:無効)
GLBL_RSSI_BYTE = 0
##################################################
#
# モジュール自アドレス選択(下位アドレス)
#
##################################################
#1:0x00,0x00 0:0x00.0x01
LOW_ADRS_SEL = Pin(28, Pin.IN, Pin.PULL_UP)
##################################################
#
# Pico W上のLED
#
##################################################
led = Pin('LED', Pin.OUT)
##################################################
#
# 有機ELディスプレイ SSD1306(OLED)設定
#
##################################################
#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0, scl=Pin(21), sda=Pin(20), freq=400000)
#OLEDを利用するため、オブジェクト(oled)を作成
oled = SSD1306_I2C(128, 64, i2c)
##################################################
#
# モジュールのピン
#
##################################################
AUX = 18
M0 = 26
M1 = 27
TXD = 17 #(UART0 RX)
RXD = 16 #(UART0 TX)
#AUXピン
LR_AUX = Pin(AUX,Pin.IN)
#M0ピン
LR_M0 = Pin(M0,Pin.OUT)
#M1ピン
LR_M1 = Pin(M1,Pin.OUT)
##################################################
#
# モジュールの初期設定
#
##################################################
def lora_initst():
######設定レジスタパラメータを設定######
#Config/DeepSleepモード(mode 3)に設定
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
LR_M0.value(1)
LR_M1.value(1)
#UART設定
urt = UART(0, 9600, tx=Pin(RXD), rx=Pin(TXD))
urt.init(9600, bits=8, parity=None, stop=1)
#設定レジスタにパラメータを設定
#書込コマンド(0xC0)、スタートアドレス(0x00)、書込数(0x08)
CMD = [0xC0, 0x00, 0x08]
#レジスタ-00(ADR_H):自デバイスの上位アドレス(0x00)
ADR_H = 0x00
CMD.append(ADR_H)
#自アドレス選択(下位アドレス)
if LOW_ADRS_SEL.value() == 1:
#レジスタ-01(ADR_L):デバイスの下位アドレス(0x00)
ADR_L = 0x00
CMD.append(ADR_L)
else:
#レジスタ-01(ADR_L):デバイスの下位アドレス(0x01) 送信先アドレス
ADR_L = 0x01
CMD.append(ADR_L)
#レジスタ-02(REG0):ボーレート(9600)、帯域幅設定(BW:125)、拡散率設定(SF:9)
REG0 = 0x70
CMD.append(REG0)
#レジスタ-03(REG1):ペイロード長(64byte)、RSSI環境ノイズ(無効)、未使用、送信出力(13dBm)
REG1 = 0x81
CMD.append(REG1)
#レジスタ-04(REG2):自周波数チャンネル(1)
REG2 = 0x01
CMD.append(REG2)
#レジスタ-05(REG3):RSSIバイト(有効)、 送信方法(通常 Fixed-block)、未使用、
#低電圧動作(無効)、WORサイクル(3000ms)
REG3 = 0x45
CMD.append(REG3)
#レジスタ-06:暗号化キー上位バイト(0)
ENCRYPT_H = 0x00
CMD.append(ENCRYPT_H)
#レジスタ-07:暗号化キー下位バイト(0)
ENCRYPT_L = 0x00
CMD.append(ENCRYPT_L)
#パラメータ設定値確認
#print("パラメータの設定値")
#設定値表示
#disp = ""
#for prm in CMD:
#disp = disp + str(hex(prm)) + "/"
#print(hex(prm))
#print(disp)
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#書込
for val in CMD:
dat = struct.pack("B", val)
urt.write(bytes(dat))
#utime.sleep(0.002)
utime.sleep_ms(1000)
######設定レジスタパラメータを読出######
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#Config/DeepSleepモード(mode 3)に設定
LR_M0.value(1)
LR_M1.value(1)
utime.sleep_ms(200)
#読出コマンド(0xC1)、スタートアドレス(0x00)、読出数(0x08)
CMD = [0xC1, 0x00, 0x08]
rspns = bytes()
#モジュールにコマンドを書込
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#書込
for val in CMD:
dat = struct.pack("B", val)
urt.write(bytes(dat))
utime.sleep_ms(1000)
#パタメータを読込
while urt.any() != 0 :
rspns = urt.read(urt.any())
#読込値表示
#disp = ""
#for prm in rspns:
#disp = disp + str(hex(prm)) + "/"
#print(hex(prm))
#print(disp)
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#通常送受信モード(mode 0)に設定
LR_M0.value(0)
LR_M1.value(0)
return urt
##################################################
#
# 送信
# (Pico W UART0 TX → 子機LoRa → 親機LoRa)
#
##################################################
def lora_transmission(urt,txdt):
#送信先上位アドレス(0x00)
TX_ADR_H = 0x00
#送信先アドレス選択(下位アドレス)
if LOW_ADRS_SEL.value() == 1:
#送信先下位アドレス(0x01)
TX_ADR_L = 0x01
else:
#送信先下位アドレス(0x00)
TX_ADR_L = 0x00
#送信先チャンネル(0x00)
CHNL= 0x00
#送信データにアドレスとチャンネルを設定
payload = bytes([TX_ADR_H, TX_ADR_L, CHNL])
#テストデータを設定
payload = payload + txdt.encode("utf-8")
#print("payload: {0}".format(payload))
#受信バッファクリア
utime.sleep_ms(200)
while urt.any() != 0 :
urt.read()
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
#送信
for dat in payload:
bdat = struct.pack("B", dat)
urt.write(bytes(bdat))
#print(bdat)
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
return
##################################################
#
# 受信
# (親機LoRa → 子機LoRa → Pico W UART0 TX)
#
##################################################
def lora_receive(urt):
#print("受信中...")
payload = bytes()
#データ受信待ち
while LR_AUX.value() != 0:
utime.sleep_ms(1)
#受信開始待ち時間
utime.sleep_ms(3)
#RSSI初期化
rssi = 0
#受信開始待ち
while True:
if urt.any() != 0:
#受信データ読込
payload = payload + urt.read()
#print("MSG" + str(payload))
elif urt.any() == 0 and len(payload) != 0:
if GLBL_RSSI_BYTE ==1:
#受信データ(RSSIバイト削除)
rcv_data = payload[:-1]
#RSSIバイト有効
rssi = int(payload[-1]) - 256
print("RSSI: {0} dBm".format(rssi))
break
else:
#受信データ
rcv_data = payload
#RSSIバイト無効
#print("受信完了(RSSIバイト無効)")
#print(payload)
break
#print(rcv_data)
rcv_data = rcv_data.decode("utf-8")
#モジュールのアイドル状態確認
while LR_AUX.value() == 0:
utime.sleep_ms(1)
return rcv_data, rssi
##################################################
#
# メイン
#
##################################################
#LED消灯
led.value(0)
#SSD1306(OLED)消去
oled.fill(0)
oled.show()
#モジュールの初期設定
urt = lora_initst()
#送信
lora_transmission(urt,"012345678abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
while True:
#受信
rcv_data, rssi = lora_receive(urt)
#print(rcv_data)
#時刻
tm = rcv_data[:8]
#RSSI
rssi = rcv_data[8:-1]
#応答フラグ
resflg =rcv_data[-1]
#SSD1306(OLED)表示
oled.fill(0)
oled.write_text(tm, x=0, y=10, size=2)
oled.write_text(rssi + "dBm", x=0, y=40, size=2)
oled.show()
utime.sleep_ms(2000)
#応答フラグ判定
if resflg == "1":
#LED点灯
led.value(1)
lora_transmission(urt,"012345678abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
if resflg == "0":
#LED消灯
led.value(0)
lora_transmission(urt,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678")
#utime.sleep_ms(2000)
親機のThonnyの「F5」キーを押して、データ送受信プログラムを実行し、数秒後、子機のThonnyの「F5」キーを押して、データ送受信プログラムを実行します。
親機、子機のLEDが数秒間隔で点滅し、子機のOLEDディスプレイに時刻と電波強度(RSSI)が継続的に表示されます。
確認後、Thonnyの「Ctrl + c」キーを押すと、処理が中断します。
Raspi4Bを接続せずに電池等で起動する場合を考え、親子機ともファイル名「main.py」で保存しました。
親機にRaspi4Bを接続せずに、電池等で起動させた場合は、現在時刻ではなく、「0:00:00」から始まる時刻を表示します。
LoRa通信モジュールの使い方
親子機、子機の2セットのLoRa通信モジュール(E220-900T22S(JP))を使って、テキストデータを送受信しながら、現在時刻と電波強度(RSSI)が、継続的に子機のOLEDディスプレイに表示されることを確認しました。
LoRa通信モジュール(以下 モジュール)を使ってプライベート LoRa 通信を行うための基本的な 使い方を簡単に見ていきます。
モジュールのデータシート、MicroPython用にライブラリについては、株式会社クレアリンクテクノロジー(DRAGON TORCH)のダウンロード・サポートよりダウンロードしてください。
モジュールの初期設定
モジュールの動作は、9バイトで構成される設定レジスタ(レジスタアドレス 0x00~0x08)を操作することで制御されます。
モジュールとラズパイPicoWはUART通信によりデータの送受信が行われ、設定レジスタへの書込み、読出しは、次のコマンドにより行われます。
- レジスタ書込みコマンド:0xC1、レジスタ開始アドレス、書込み数
- レジスタ読出しコマンド:0xC0、レジスタ開始アドレス、読出し数
設定レジスタにはモジュールのデバイスアドレス、データの伝送速度(ボーレート)、データの長さ(ペイロード長)、送信出力、周波数チャンネル、電波強度 (RSSI)通知の有無等を設定します。
▶️設定レジスタへの書込みコマンド
コマンド | 開始アドレス | 書込み数 | 備 考 |
0xC0 | 0x00 | 0x08 |
▶️設定レジスタへの書込み内容
レジスタ アドレス | 項 目 | 設 定 値 | |
親 機 | 子 機 | ||
0x00 | アドレスの上位バイト | 0x00 | 0x00 |
0x01 | アドレスの下位バイト | 0x00 | 0x01 |
0x02 | ・ボーレート:9600bps ・帯域幅設定(BW):125 ・拡散率設定(SF):9 | 0x70 | 0x70 |
0x03 | ・ペイロード長:64byte ・RSSI環境ノイズ:無功 ・送信出力:13dBm | 0x81 | 0x81 |
0x04 | 自身の周波数チャンネル | 0x00 | 0x01 |
0x05 | ・RSSIバイト:親機=有効、子機=無効 ・送信方法:通常(Fixed-block) ・低電圧動作:無功 ・WORサイクル:3000ms | 0xC5 | 0x45 |
0x06 | 暗号化キー上位バイト | 0x00 | 0x00 |
0x07 | 暗号化キー下位バイト | 0x00 | 0x00 |
▶️設定レジスタからの読出しコマンド
コマンド | 開始アドレス | 書込み数 | 備 考 |
0xC1 | 0x00 | 0x08 |
設定レジスタへの書込み、設定レジスタからの読出しは、Config/DeepSleepモード(モジュールのM0、M1ピンをHigh)に設定し、UART通信で行います。
モジュールが何らか処理を行っている場合は、書込み、読出しはできませんので、モジュールのAUXピンをモニターし処理を行っていないことや、受信用バッファのデータ有無を確認する必要があります。
書込み、読出し後は、通常の送受信モードにするため、M0、M1ピンをLowに設定します。
送信
送信は送信先のアドレス(2バイト)、周波数チャンネル(1バイト)を実際のデータに付加して行いますので、実際のデータは設定したペイロード長(64バイト)から3バイト引いた61バイトになります。
▶️親機から子機への送信
子機の上位アドレス | 子機の下位アドレス | 子機の周波数チャンネル |
0x00 | 0x01 | 0x01 |
▶️子機から親機への送信
親機の上位アドレス | 親機の下位アドレス | 親機の周波数チャンネル |
0x00 | 0x00 | 0x00 |
送信は、通常の送受信モード(モジュールのM0、M1ピンをLow)に設定し、UART通信で行います。
モジュールが何らか処理を行っている場合は、送信はできませんので、モジュールのAUXピンをモニターし処理を行っていないことや、受信用バッファのデータ有無を確認する必要があります。
受信
受信は受信したアドレス(2バイト)、周波数チャンネル(1バイト)が、自身のアドレス、周波数チャンネルと一致した場合に処理されます。
親機はRSSIバイトが有効になっていますので、モジュールは受信データの最後にRSSIバイトを付与して、ラズパイPicoWにデータを送ります。
ラズパイPicoWは最後のバイトを抽出して、電波強度(RSSI)を計算します。
子機はRSSIバイトが無効になっていますので、電波強度(RSSI)の計算は必要ありません。
受信は、通常の送受信モード(モジュールのM0、M1ピンをLow)に設定し、UART通信で行います。
モジュールが何らか処理を行っていいる場合は、受信はできませんので、モジュールのAUXピンをモニターし処理を行っていないことを確認する必要があります。
まとめ
親機、子機の2セットのLoRa通信モジュール(E220-900T22S(JP))を使って、テキストデータを送受信しながら、現在時刻と電波強度(RSSI)が、継続的に子機のOLEDディスプレイに表示されることを確認しました。
LoRa通信モジュール(E220-900T22S(JP))で通信を行うための基礎的な設定と送信、受信の方法を学びました。
住宅地や農地で利用した場合の、通信距離や通信精度を確認することが今後の課題です。