この記事について
前回構築したPrivate LoRa GWに接続するLoRa DeviceをラズパイとLoRaHATで構築します。下図の色付き部分です。
- edge node用ラズパイにLoRaHATを装着しPrivate LoRaデバイス化
- edge node用ラズパイを仮想エッジデバイスと見立てて監視対象の数値をLoRa GWにpub
させます。
デバイス
RaspberryPi
Raspberry Pi: Raspberry Pi 4 Model B Rev 1.2
OS: Raspberry Pi OS Lite 64-bit (Debian GNU/Linux 11 (bullseye))
LoRaHAT
Raspberry Pi 3,4用LoRa HAT(DTH-RPLR)
(こちらとPiZero/Zero2でも可能です:Raspberry Pi Zero用LoRa HAT)
zipのサンプルコードにはconfig_codeとoperation_codeの二つのdirectoryが入っていますのでラズパイの/home/user/にコピーして使います。
型名 DTH-RPLR
RFモジュール LoRa通信モジュール(E220-900T22S(JP))
通信モジュールの仕様はこちら>>
対応ボード Raspberry Pi 3,4
インターフェース UART
モード制御I/O (信号レベルは3.3V TTL)
電源電圧 動作定格 3.3V ~ 5.5V
推奨電圧範囲 3.5V ~ 5.0V
動作温度範囲 -45℃ ~ +85℃
外形寸法 56mm x 65mm
LoRa用アンテナ
ラズパイ LoRa Device
ラズパイ基本環境
GW同様に過去記事の環境から必要に応じて追加/削除します。
wiringpiがよろしくないですが今回はこのまま使います。
#シリアルポート有効化
sudo raspi-config nonint do_serial 2
#ライブラリ追加
pip install pyserial wiringpi
LoRa通信parameters
zipに含まれるE220-900T22S(JP)_シンプルLoRaHAT_利用ガイド_Rev1.pdfに従い以下の設定にします。暗号化はありにします。
own_address
前回Pi GWでは0に設定したので今回のPi LoRa Deviceは1にします
その他のparameter
暗号化キー含めて前回のPi GWと同じにします。
[E220-900JP]
own_address=1
baud_rate=9600
bw=125
sf=9
subpacket_size=200
rssi_ambient_noise_flag=0
transmitting_power=13
own_channel=0
rssi_byte_flag=1
transmission_method_type=2
wor_cycle=3000
encryption_key=1234
ラズパイ LoRa Device
/home/user/operation_code/send.pyを流用してE220デバイス間Private LoRa通信用のsubscriberをプロトタイプしました。
このラズパイ LoRa Deviceの
- 識別子(device_no):1
- 監視対象の値(何でもイイdummy):8888
にします。
import serial
import sys
import argparse
import hexdump
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument("serial_port")
parser.add_argument("-b", "--baud", default="9600")
parser.add_argument("-m", "--model", default="E220-900JP")
parser.add_argument("-p", "--payload_length")
parser.add_argument("-a", "--ascii_text")
parser.add_argument("-f", "--fixed_mode", action="store_true")
parser.add_argument("--target_address")
parser.add_argument("--target_channel")
args = parser.parse_args()
return args
def main(device_no, msg):
args = get_args()
if args.model == "E220-900JP":
if args.fixed_mode:
if (args.target_address != None) and (args.target_channel != None):
t_addr = int(args.target_address)
t_addr_H = t_addr >> 8
t_addr_L = t_addr & 0xFF
t_ch = int(args.target_channel)
payload = bytes([t_addr_H, t_addr_L, t_ch])
print("payload:", payload)
else:
print("INVALID")
return
else:
payload = bytes([])
print("payload:", payload)
if args.payload_length != None:
count = int(args.payload_length) // 256
print("COUNT:", count)
if count > 0:
payload = payload + bytes(range(256))
print("payload:", payload)
for i in range(count - 1):
payload = payload + bytes(range(256))
print("payload:", payload)
payload = payload + bytes(range(int(args.payload_length) % 256))
print("payload:", payload)
else:
payload = payload + bytes(range(int(args.payload_length)))
print("payload:", payload)
elif args.ascii_text == None:
payload = payload + f"{msg}\n{device_no}\n".encode()
else:
std_in = sys.stdin.buffer.read()
print("stdin:", std_in)
payload = payload + std_in
payload = payload + f"{msg}\n{device_no}\n".encode()
print("payload:", payload)
print("serial port:")
print(args.serial_port)
print("payload:")
print(payload)
print("send data hex dump:")
hexdump.hexdump(payload)
with serial.Serial(args.serial_port, int(args.baud), timeout=None) as ser:
while True:
if ser.out_waiting == 0:
break
ser.write(payload)
ser.flush()
print("SENDED")
else:
print("INVALID")
return
if __name__ == "__main__":
# このラズパイDeviceの識別子
device_no = "1"
# dummy message
msg = "8888"
main(device_no, msg)
起動
send.pyでpubする場合も、前回のgateway.py(receive.py)同様にconfig modeでparameterをloadしてからoperation modeに移行してpublisherを起動する必要があります。
E220-900T22S(JP)_シンプルLoRaHAT_利用ガイド_Rev1.pdfに従い以下の順に操作します。
cd ./config_code
python mode3_org.py
python config_cui.py /dev/ttyS0 --apply
cd ../operation_code
python mode0_org.py
while true
do
python send.py /dev/ttyS0 -f --target_address 0 --target_channel 0
sleep 10
done
publihserとGW brokerが両方準備できたので前回構築したgateway.pyを先に起動して待ち受けさせておきます。
user@privateLoRaAP1:~ $ python main.py /dev/ttyS0 --rssi
serial port:
/dev/ttyS0
receive waiting...
payload: b''
Connected
/home/user/operation_code/から10秒毎にsend.pyを実行します。
SENDEDっていうのは私じゃないんで…スルーしますので見なかったことにしてあげてくださいm(__)m
user@privateLoRaSub1:~/operation_code $
while true
do
python send.py /dev/ttyS0 -f --target_address 0 --target_channel 0
sleep 10
done
payload: b'\x00\x00\x00'
serial port:
/dev/ttyS0
payload:
b'\x00\x00\x008888\n1\n'
send data hex dump:
00000000: 00 00 00 38 38 38 38 0A 31 0A ...8888.1.
SENDED
GW brokerで"8888"がsubされているのが確認できます。
.
.
.
topic: privateLoRaAP1/LoRaDev1
count : 8888
{'Timestamp': 1720206874, 'count': 8888}
topic: privateLoRaAP1/LoRaDev1
count : 8888
{'Timestamp': 1720206885, 'count': 8888}
AWS IoT CoreのMQTTクライアントでもdevice_no:1(topic:privateLoRaAP1/LoRaDev1)から"8888"がsub出来ているのが確認できました。
次回
Private LoRa Gateway経由でnodeのデータをAWS IoTにpublish③ E220でESP32 LoRaデバイス構築
次回はESP32版のedge nodeでラズパイPrivate LoRa Deviceを構築します。