部品 · 読了まで16分

LoRa Arduinoガイド:SX1278 Ra-02とESP32で長距離無線通信

LoRaをArduinoで使うためのガイドです。SX1278 Ra-02の配線、SFと帯域幅の設定、送受信コード、ESP32とPicoでの使い方、3.3 Vの注意点、通信距離テスト、LoRaとLoRaWANの違いを解説します。

LoRa Arduinoのプロジェクトは、インターネットやSIMカードを使わず、わずかな電力で2枚のボード間の数kmにわたってデータを送る最も実用的な方法です。LoRa(Long Range)はSemtechが開発した無線変調方式です。SX1278を搭載した433 MHzのRa-02などの安価なモジュールで、市街地では1〜3 km、開けた場所では最大10 kmまで届きます。その代わり、速度は毎秒数百バイトから数キロビット程度です。そのため音声や動画には向きませんが、温度、湿度、水位、ドアの状態、GPS位置などの小さな測定データを遠くへ送るのに最適です。

このガイドでは、LoRaが遠くまで届く仕組み、通信距離を決めるSF・BW・CRの設定、地域に適した周波数、Ra-02とArduino Uno・ESP32・Raspberry Pi Picoの配線、LoRaライブラリを使った送受信コード、RSSIとSNRの読み取り、実際の通信距離テストを順に解説します。最後に、LoRaとLoRaWANの違い、The Things Network(TTN)、電池で数か月動く畑のセンサープロジェクトを紹介します。

LoRaとは?遠くまで届く仕組み

LoRaはチャープスペクトラム拡散(CSS)という技術を使います。各シンボルは、帯域内を周波数が一定のペースで上昇する「チャープ」として送信されます。情報はチャープが始まる周波数に埋め込まれています。受信機が入力信号に既知のチャープ波形を掛けて足し合わせると、ノイズは打ち消され、信号は蓄積されます。これにより、LoRaはノイズフロアより20 dB低い信号まで復号できます。一般的な433 MHz ASKモジュールでは信号がノイズより明らかに強い必要がありますが、LoRaはかすかな信号も読み取れます。これが、同じ出力でより遠くまで届く秘密です。

代償は時間です。チャープが長いほど受信機が集めるエネルギーが増えて通信距離は伸びますが、同じデータを送る速度は低下します。LoRaでは通信距離、速度、電池寿命が常に結び付いています。20バイトの測定データの送信には、最速の設定で約57ミリ秒、最も遠くまで届く設定で1.3秒かかります。以下の表で、LoRaとArduinoで使われるほかの無線方式を比較します。

項目LoRa(SX1278)nRF24L01433 MHz ASKWi-Fi(ESP32)
一般的な通信距離市街地で1〜3 km、開けた場所で最大10 km50〜100 m(PA+LNA付きで約1 km)20〜100 m50〜100 m(ルーターまで)
データ速度0.3〜5.5 kbit/s(125 kHz)250 kbit/s〜2 Mbit/s1〜10 kbit/sMbit/s程度
送信時の電流40〜120 mA(出力による)11〜12 mA10〜40 mA120〜240 mA
スリープ時の電流1 µA未満約1 µAなし(電源オフ)10 µA(ディープスリープ)
双方向通信可能可能不可(送信機と受信機が別)可能
インフラ不要不要不要ルーターとインターネット

LoRaモジュール:Ra-02、RFM95、E32と一体型ボード

市販のLoRaモジュールの多くは、SemtechのSX127xシリーズのチップを使っています。SX1276の対応範囲は137〜1020 MHz、SX1278は137〜525 MHzです。そのため、433 MHzモジュールにはSX1278、868/915 MHzモジュールにはSX1276が使われています。モジュールには、SPIで通信する無線回路のみのものと、独自のプロセッサを搭載し、UART経由でシリアルポートのように使えるものの2種類があります。

モジュールチップ周波数インターフェース補足
Ai-Thinker Ra-02SX1278433 MHzSPI最も安価で広く使われるタイプ。IPEXアンテナコネクター
Ai-Thinker Ra-01SX1278433 MHzSPIスプリングアンテナ付きのRa-02派生モデル
HopeRF RFM95WSX1276868 / 915 MHzSPILoRaWANやTTNでよく使われるモデル
Ebyte E32 / E220SX1278 / LLCC68433 / 868 MHzUART独自のプロセッサを搭載。ライブラリなしでシリアルポートのように動作
TTGO LoRa32, Heltec LoRa 32ESP32 + SX1276/78433 / 868 / 915 MHzボード上に搭載ESP32、LoRa、OLEDを1枚のボードに搭載
Ra-02の仕様値
チップSemtech SX1278
周波数範囲410〜525 MHz(通常は433 MHz)
最大出力+18 dBm(約63 mW)
受信感度最低-141 dBm(最も狭い帯域幅の場合)
電源1.8〜3.7 V、通常は3.3 V
電流送信時約40〜120 mA、受信待機時約12 mA、スリープ時1 µA未満
インターフェースSPI(最大10 MHz)+ DIO0割り込みピン
アンテナIPEX(U.FL)コネクター。433 MHzのアンテナが必要
SX1278は3.3 Vのチップで、ピンは5 Vトレラントではありません。Ra-02をArduino Unoの5Vピンや5 VのSPI信号線に直接つなぐと、修復不能な故障を起こします。電源は必ず3.3 Vにし、UnoではSPI信号線にレベル変換モジュールが必要です(配線の節で解説します)。

周波数は433 MHzと868/915 MHzのどちらを選ぶ?

LoRaは免許不要のISM帯で動作しますが、周波数帯は国によって異なり、それぞれ出力とデューティ比に制限があります。ヨーロッパでLoRaに使われるのは433.05〜434.79 MHzと863〜870 MHzの2つの帯域で、北米では902〜928 MHzです。LoRaWANネットワークとTTNはヨーロッパで868 MHz、米国で915 MHzを使います。一方、安価なRa-02モジュールを使う趣味の1対1通信では433 MHzがよく使われます。アンテナとチップは特定の周波数に合わせて調整されているため、購入前に使用地域の条件を確認してください。868 MHzのモジュールは433 MHzでは動作しません。

地域LoRaの周波数LoRaWANプラン
ヨーロッパ、英国、トルコ433 MHzと863〜870 MHzEU868(EU433はまれ)
米国、カナダ、メキシコ902〜928 MHzUS915
ブラジル、アルゼンチン、オーストラリア915〜928 MHzAU915
インド865〜867 MHzIN865
日本、東南アジア920〜923 MHzAS923
中国470〜510 MHz(および433 MHz)CN470
ヨーロッパの規則では、433 MHz帯の許容出力は一般に10 mW(10 dBm)、868 MHzのサブバンドでは多くの場合25 mWで、デューティ比は1%です。つまり、1秒送信した機器は、その後99秒間送信を止める必要があります。Ra-02の最大出力18 dBmはこの制限を超えるため、サンプルコードではsetTxPower(10)を使っています。正確な制限は、使用する国の電波規制当局で確認してください。

SF・BW・CR:通信距離を決める3つの設定

LoRaの通信距離と速度は3つのパラメータで決まります。拡散率(SF)は、各シンボルを構成する「チップ」の数を決めます。SF7からSF12まで、1段階上げるごとにシンボル時間が2倍になり、約2.5 dB弱い信号まで復号できるようになりますが、電波を送信している時間もほぼ2倍になります。以下の表は帯域幅125 kHz、符号化率4/5、20バイトのパケットで計算しています。最後の列はデューティ比1%を守るために必要な、パケット間の最短待機時間です。

SFビットレート20バイトのパケット送信時間おおよその感度復号可能な最低SNRデューティ比1%での待機時間
SF75.5 kbit/s57 ms-123 dBm-7.5 dB6 s
SF83.1 kbit/s103 ms-126 dBm-10 dB10 s
SF91.8 kbit/s185 ms-129 dBm-12.5 dB18 s
SF10977 bit/s371 ms-132 dBm-15 dB37 s
SF11537 bit/s741 ms-134 dBm-17.5 dB73 s
SF12293 bit/s1319 ms-137 dBm-20 dB131 s

帯域幅(BW)は信号が占める周波数範囲の広さです。標準は125 kHzで、250 kHzと500 kHzでは速度がそれぞれ2倍と4倍になりますが、感度は3 dBと6 dB低下します。62.5 kHz以下にすると通信距離が伸びる一方、安価な水晶の周波数ドリフトの影響を受けやすくなります。符号化率(CR)は誤り訂正のために加える冗長データの割合です。4/5では4ビットごとに訂正用の1ビット、4/8では4ビットを加えます。ノイズの多い環境で役立ちますが、パケットは長くなります。ビットレートの式はRb = SF × (BW / 2^SF) × 4 / (4 + CR)です。SF9、125 kHz、4/5では9 × 125000 / 512 × 0.8 ≈ 1758 bit/sとなります。

最初はSF9、125 kHz、4/5がバランスのよい設定です。通信距離が足りなければSFを1段階ずつ上げ、速度が必要なら下げます。周波数、SF、BW、CR、同期ワードは送信側と受信側で完全に一致させる必要があります。1つでも違うと、受信側はパケットをまったく受信できません。既定の同期ワードは0x12で、多くのプライベートネットワークが使っています。LoRaWANネットワークは0x34を使います。サンプルのように0xF3など独自の値を選ぶと、近くの趣味用機器やLoRaWANからのパケットをハードウェアで除外しやすくなります。

Ra-02の配線:Arduino Uno、ESP32、Pico

Ra-02には4本のSPI信号線(SCK、MISO、MOSI、NSS)のほかに、リセットピンと割り込みピン(DIO0)が必要です。DIO0は送信完了時や新しいパケットの受信時にHIGHになり、LoRaライブラリはこれを割り込みに使います。このガイドのコードでは、モジュールのDIO1〜DIO5ピンは未接続のままで構いません。SPIに初めて触れる場合は、先にSPIとは?の記事を読んでみてください。

Ra-02のピンArduino UnoESP32Raspberry Pi Pico
3.3V外部3.3 Vレギュレーター3V33V3 (OUT)
GNDGNDGNDGND
SCKD13(レベル変換経由)GPIO 18GP18
MISOD12(直接接続)GPIO 19GP16
MOSID11(レベル変換経由)GPIO 23GP19
NSSD10(レベル変換経由)GPIO 5GP17
RESETD9(レベル変換経由)GPIO 14GP20
DIO0D2(直接接続、割り込みピン)GPIO 26GP21
Unoでは2つの問題があります。1つ目は電圧です。UnoのSCK、MOSI、NSS、RESETの出力は5 Vなので、レベル変換IC(74HC4050など)か、各信号線に2.2 kΩ + 3.3 kΩの分圧回路を入れて3.3 Vに下げる必要があります。MISOとDIO0はモジュールからUnoに向かう信号なので、直接接続できます。2つ目は電流です。Unoの3.3Vピンが供給できるのは約50 mAですが、Ra-02は送信時に100 mAを超える電流を消費することがあります。AMS1117などの別の3.3 Vレギュレーターからモジュールに給電してください。ESP32、Pico、3.3 VのArduino Pro Miniでは、これらの問題はありません。

アンテナは配線と同じくらい重要です。Ra-02のIPEXコネクターに、433 MHz用に調整されたアンテナを取り付けます。自作も簡単です。波長は300 / 433 = 0.693メートルなので、まっすぐな17.3 cmの線で1/4波長アンテナになります(868 MHzでは8.6 cm、915 MHzでは8.2 cm)。アンテナは垂直に立て、金属の箱には入れず、両側のアンテナを同じ向き(両方とも垂直)にしてください。互いに直角になると、信号の大部分を失います。

ステップごとの解説:LoRaライブラリで送信機を作る

  1. Arduino IDEのライブラリマネージャを開き、LoRaと入力して、Sandeep MistryのLoRaライブラリをインストールします。
  2. 表のとおりにモジュールを配線し、アンテナを取り付けずに送信することは絶対に避けてください。
  3. 送信側のボードに以下のコードを書き込みます。ESP32かUnoかを判別し、それに合わせてピンを選びます。
  4. シリアルモニタを115200ボーで開くと、5秒ごとに「Gonderildi / sent」の行が表示されます。
  5. LoRa.begin()が失敗した場合は、配線、3.3 V電源、NSSピンとRESETピンを確認してください。
C++ (Arduino IDE)
1#include <SPI.h>
2#include <LoRa.h>
3
4#if defined(ESP32)
5const int PIN_SS = 5, PIN_RST = 14, PIN_DIO0 = 26;   // ESP32 (VSPI: SCK 18, MISO 19, MOSI 23)
6#else
7const int PIN_SS = 10, PIN_RST = 9, PIN_DIO0 = 2;    // Uno (SCK 13, MISO 12, MOSI 11) + seviye dönüştürücü / level shifter
8#endif
9
10const long FREKANS = 433E6;      // Ra-02: 433 MHz; RFM95 için 868E6 / 868E6 for an RFM95
11unsigned long sayac = 0;
12
13void setup() {
14  Serial.begin(115200);
15  LoRa.setPins(PIN_SS, PIN_RST, PIN_DIO0);
16  if (!LoRa.begin(FREKANS)) {               // SX1278 bulunamadı / SX1278 not found
17    Serial.println("LoRa baslatilamadi / LoRa init failed");
18    while (true) delay(1000);
19  }
20  LoRa.setSpreadingFactor(9);               // SF9: menzil ile hız dengesi / range vs speed balance
21  LoRa.setSignalBandwidth(125E3);           // 125 kHz bant genişliği / bandwidth
22  LoRa.setCodingRate4(5);                   // hata düzeltme 4/5 / error coding 4/5
23  LoRa.setSyncWord(0xF3);                   // iki tarafta aynı olmalı / must match on both sides
24  LoRa.enableCrc();                         // bozuk paketi ele / drop corrupted packets
25  LoRa.setTxPower(10);                      // 10 dBm (433 MHz bandında yasal sınır) / legal limit on 433 MHz
26  Serial.println("Verici hazir / sender ready");
27}
28
29void loop() {
30  LoRa.beginPacket();
31  LoRa.print("BG #");
32  LoRa.print(sayac);                        // paket numarası / packet number
33  LoRa.endPacket();                         // gönderim bitene kadar bekler / blocks until sent
34  Serial.print("Gonderildi / sent #");
35  Serial.println(sayac);
36  sayac++;
37  delay(5000);                              // havada kalma süresine göre bekle / wait according to airtime
38}
39
関数働き
LoRa.setPins(ss, reset, dio0)NSS、RESET、DIO0ピンを指定します。begin()の前に呼び出します
LoRa.begin(433E6)モジュールを起動し、周波数をHzで設定します。チップが見つからない場合は0を返します
setSpreadingFactor(6–12)SFの設定。既定値は7
setSignalBandwidth(125E3)帯域幅。既定値は125 kHz
setCodingRate4(5–8)符号化率4/5〜4/8。既定値は4/5
setSyncWord(0xF3)同期ワード。既定値は0x12(LoRaWANは0x34)
enableCrc()パケットにCRCを追加します。ライブラリでは既定で無効です
setTxPower(2–20)dBm単位の出力。既定値は17
beginPacket() / print() / endPacket()パケットを準備し、データを書き込み、送信します

受信機:パケット、RSSI、SNRの読み取り

受信コードはループのたびにLoRa.parsePacket()で新しいパケットが届いたかを確認します。届いていればパケットのサイズが返り、LoRa.read()で内容を1バイトずつ読み取ります。また、パケット番号の抜けを数えて損失率を計算します。これは、この後で行う通信距離テストの基本になります。

C++ (Arduino IDE)
1#include <SPI.h>
2#include <LoRa.h>
3
4#if defined(ESP32)
5const int PIN_SS = 5, PIN_RST = 14, PIN_DIO0 = 26;
6#else
7const int PIN_SS = 10, PIN_RST = 9, PIN_DIO0 = 2;
8#endif
9
10long sonNo = -1;                 // son alınan paket numarası / last packet number
11unsigned long alinan = 0, kayip = 0;
12
13void setup() {
14  Serial.begin(115200);
15  LoRa.setPins(PIN_SS, PIN_RST, PIN_DIO0);
16  if (!LoRa.begin(433E6)) {
17    Serial.println("LoRa baslatilamadi / LoRa init failed");
18    while (true) delay(1000);
19  }
20  LoRa.setSpreadingFactor(9);    // verici ile aynı ayarlar / same settings as the sender
21  LoRa.setSignalBandwidth(125E3);
22  LoRa.setCodingRate4(5);
23  LoRa.setSyncWord(0xF3);
24  LoRa.enableCrc();
25  Serial.println("Alici hazir / receiver ready");
26}
27
28void loop() {
29  int boyut = LoRa.parsePacket();           // paket geldi mi? / did a packet arrive?
30  if (boyut == 0) return;
31
32  String mesaj = "";
33  while (LoRa.available()) mesaj += (char)LoRa.read();
34
35  int diyez = mesaj.indexOf('#');           // "BG #123" içinden numara / number from "BG #123"
36  long no = (diyez >= 0) ? mesaj.substring(diyez + 1).toInt() : -1;
37  if (sonNo >= 0 && no > sonNo + 1) kayip += no - sonNo - 1;   // atlanan numaralar kayıp / skipped numbers are lost
38  if (no >= 0) sonNo = no;
39  alinan++;
40
41  Serial.print(mesaj);
42  Serial.print("  RSSI: ");
43  Serial.print(LoRa.packetRssi());          // dBm, -120'ye yaklaştıkça zayıf / weaker towards -120
44  Serial.print(" dBm  SNR: ");
45  Serial.print(LoRa.packetSnr(), 1);        // dB, eksi değerler de çözülebilir / negative values still decode
46  Serial.print(" dB  kayip / lost: ");
47  Serial.print(100.0 * kayip / (alinan + kayip), 1);
48  Serial.println(" %");
49}
50

RSSI(受信信号強度指標)は受信信号の強さを示す、単位dBmの負の数です。-40 dBmは非常に強く、-120 dBmは非常に弱い信号です。SNR(信号対雑音比)は、信号がノイズよりどれだけ強いかを表します。LoRaの特徴は、SNRが負でも動作することです。SF9では-12.5 dBまでパケットを復号できます。通信距離の限界に近いかを判断するときは、RSSIよりもSNRに注目してください。ノイズの多い市街地では、RSSIが-100 dBmでもSNRはすでに限界に達していることがあります。

指標値意味
RSSI-30〜-70 dBm非常に強い。モジュール同士が近い
RSSI-70〜-110 dBm良好で安定した通信
RSSI-110〜-125 dBm弱い。SFを上げることを検討
SNR+5 dB以上余裕あり。SFを下げて速度を上げられる可能性あり
SNR0〜-10 dBLoRaの通常の動作範囲
SNRSFの限界付近(SF9では-12 dB)途切れる直前。SFを上げるかアンテナを改善

ESP32でLoRaを使う:Wi-Fiへのブリッジ

ESP32開発ボード
ESP32:3.3 VのピンをRa-02にレベル変換なしで接続でき、同時にLoRaのデータをWi-Fi経由でインターネットへ転送できます。

ESP32はLoRaを最も簡単に使えるボードです。ピンはもともと3.3 Vで、3V3ピンはモジュールに必要な電流を供給でき、VSPIバス(GPIO 18、19、23)をそのまま使えます。上記の送受信コードは、変更せずにESP32でコンパイルできます。#if defined(ESP32)の行でNSS = 5、RESET = 14、DIO0 = 26が選ばれます。DIO0をGPIO 2ではなくGPIO 26につなぐのは、GPIO 2がチップの起動方法に影響するストラッピングピンだからです。ESP32の真価はブリッジとしての働きにあります。畑のセンサーからLoRaで届いたデータを、Wi-Fi経由でWebページ、MQTTサーバー、Telegramへ転送できます。TTGO LoRa32やHeltec LoRa 32などのボードには、ESP32、LoRaチップ、OLEDディスプレイが1枚に搭載されています。ピン番号は異なるため、ボードの回路図を確認してください。

Raspberry Pi PicoでLoRaを使う(MicroPython)

PicoではRa-02をSPI0バス(GP16 MISO、GP18 SCK、GP19 MOSI、GP17 NSS)に接続します。公式のmicropython-libリポジトリにはSX127xチップ向けのLoRaドライバがあり、Thonnyのパッケージマネージャかmpremote mip install lora-sync lora-sx127xでインストールできます。ドライバには設定を辞書形式で渡します。SF、帯域幅、同期ワードがArduino側と一致していれば、Picoは上記のArduino送信機からのパケットを問題なく読み取れます。ドライバはSNRをチップのレジスタに格納された値、つまりdB値の4倍で返すため、コードでは4で割っています。Ra-02のアンテナはチップのPA_BOOST出力につながっているので、tx_antの設定は必ず「PA_BOOST」にしてください。そうしないと、送信が非常に弱くなります。

MicroPython
1from machine import Pin, SPI
2from lora import SX1278          # mip: lora-sync + lora-sx127x paketleri / packages
3import time
4
5lora_cfg = {
6    "freq_khz": 433000,          # Ra-02: 433 MHz
7    "sf": 9,                     # Arduino tarafıyla aynı / same as the Arduino side
8    "bw": "125",                 # kHz
9    "coding_rate": 5,            # 4/5
10    "preamble_len": 8,
11    "syncword": 0xF3,
12    "tx_ant": "PA_BOOST",        # Ra-02 anteni PA_BOOST çıkışında / Ra-02 antenna is on PA_BOOST
13    "output_power": 10,          # dBm
14}
15
16spi = SPI(0, baudrate=2_000_000, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
17modem = SX1278(spi=spi, cs=Pin(17), dio0=Pin(21), reset=Pin(20), lora_cfg=lora_cfg)
18
19while True:
20    paket = modem.recv(timeout_ms=10000)       # 10 sn dinle / listen for 10 s
21    if paket and paket.valid_crc:
22        # snr kayıtta 4 katı tutulur / snr is stored as 4x in the register
23        print(bytes(paket), "RSSI:", paket.rssi, "dBm  SNR:", paket.snr / 4, "dB")
24    elif paket:
25        print("CRC hatali paket / bad CRC")
26    else:
27        print("Paket yok / no packet")
28    time.sleep_ms(10)
29

通信距離テスト:LoRaは何kmまで届く?

実際の通信距離を知るには、テストするしかありません。自宅の窓辺や屋根に送信機を置き、受信機をノートパソコン、またはモバイルバッテリーで動かすESP32 + OLEDに接続します。離れながらRSSI、SNR、損失率を記録してください。損失率が10%を超えるか、SNRがSFの限界に近づくと、実用的な通信距離の限界です。違いの原因が分かるように、1回のテストで変えるのはSF、アンテナ、高さなどのうち1つだけにします。2地点間の直線距離は、スマホの地図アプリで測れます。

環境一般的な通信距離(Ra-02、SF9〜SF12、簡単なアンテナ)決め手となる要因
屋内、建物内数フロア、100〜500 mコンクリートの壁と金属
建物が密集した市街地1〜3 km建物、見通しがないこと
郊外、村3〜6 km木と低い建物
開けた田園、畑5〜10 kmアンテナの地上高
見通しのよい丘の頂上同士15 km以上地球の曲率とアンテナ利得
  • アンテナを高くする:通信距離を伸ばすうえで、アンテナの高さほど効果的なものはありません。高さを1メートルから5メートルにすると、見通し距離は何倍にも伸びます。
  • 適切なアンテナを使う:モジュールに付属する小さなスプリングアンテナは手軽ですが、効率はよくありません。17.3 cmの1/4波長ワイヤーアンテナや屋外用ホイップアンテナにすると、はっきりした差が出ます。
  • SFを上げる:SF9からSF12にすると約8 dBの改善が得られ、開けた場所では距離がおおむね2倍以上になります。
  • 帯域幅を狭くする:125 kHzから62.5 kHzに下げると3 dB改善しますが、2つのモジュールの水晶の周波数ドリフトが問題になることがあります。
  • フレネルゾーンを空ける:見通しがよく見えても、2本のアンテナ間にある楕円形の領域に木や建物が入ると信号が弱まります。アンテナを少し高くすると解消できます。
  • 電源にも注意する:送信時の急な電流増加で、余裕のない3.3 Vラインの電圧が下がり、モジュールがリセットされることがあります。電源に100 µFのコンデンサを追加してください。

LoRaとLoRaWANの違い:TTNとは?

この2つの用語はよく混同されます。LoRaは無線変調方式、つまり物理層だけを指します。2つのモジュールが直接パケットを送り合い、どの機器が何を誰に送るかは自分で決めます。このガイドの例はすべて1対1のLoRa通信です。LoRaWANはLoRaの上に構築されたネットワークプロトコルです。機器(エンドノード)は近くのゲートウェイにパケットを送り、ゲートウェイはインターネット経由でネットワークサーバーに渡し、そこからアプリケーションにデータが届きます。LoRaWANは機器の識別、AES-128暗号化、周波数とSFの自動調整(ADR)、デューティ比の規則を自動で処理します。

項目LoRa(1対1通信)LoRaWAN
層無線のみ(物理層)無線 + ネットワークプロトコル(MAC)
インフラモジュール2つで十分ゲートウェイとネットワークサーバーが必要
暗号化なし。自分で追加AES-128、必須
ArduinoライブラリLoRa(Sandeep Mistry)MCCI LoRaWAN LMIC, RadioLib
ヨーロッパでの周波数433 MHzか868 MHzを自由に選択EU868のチャネルプラン
適した用途自宅の庭、2つの建物間、リモコン市全体のセンサーネットワーク、多数の機器

The Things Network(TTN)は、ボランティアが設置したゲートウェイで構成される、無料のコミュニティ型LoRaWANネットワークです。近くにTTNゲートウェイがあれば、自分でゲートウェイを作らなくても、機器を登録してインターネット上でデータを読めます。無料利用にはフェアユースポリシーがあり、1台あたりの合計送信時間は1日約30秒、ダウンリンクメッセージは1日最大10件です。TTNはヨーロッパでEU868、米国でUS915を使うため、433 MHzのRa-02は適していません。TTNには使用地域に合ったRFM95か、LoRaWAN対応の完成済みモジュールを用意してください。近くにゲートウェイがなければ、1対1のLoRa通信のほうがはるかに簡単です。

プロジェクト:電池で動く畑と庭のセンサー

土壌水分センサー
土壌水分センサー:畑のLoRaノードがこのセンサーで測定し、10分ごとに自宅へパケットを送ります。

LoRaの代表的な用途は、電源やWi-Fiのない畑や、庭の奥にある温室からデータを取得することです。以下のESP32コードは土壌水分を測り、「T1,42,37」(ノードID、パケット番号、水分率)の形式で小さなパケットを送信します。その後、LoRaモジュールとESP32の両方をスリープさせ、10分後に再び起動します。センサーには測定中だけGPIO 25から給電するため、スリープ中は電流を消費せず、抵抗式センサーでは電極の腐食も抑えられます。センサーのキャリブレーションは土壌水分センサーの記事、ディープスリープの詳細はESP32のディープスリープの記事で解説しています。自宅の受信機には上記の受信コードを使い、カンマで値を分割できます。

C++ (Arduino IDE)
1#include <SPI.h>
2#include <LoRa.h>
3
4const int PIN_SS = 5, PIN_RST = 14, PIN_DIO0 = 26;
5const int NEM_PIN = 34;                      // toprak nem sensörü AO (yalnız giriş pini) / soil sensor AO (input-only pin)
6const int SENSOR_GUC = 25;                   // sensörü yalnız ölçerken besle / power the sensor only while measuring
7const int KURU = 3000, ISLAK = 1200;         // kendi sensörünle kalibre et / calibrate with your sensor
8const uint64_t UYKU_US = 10ULL * 60 * 1000000;   // 10 dakika / 10 minutes
9
10RTC_DATA_ATTR uint32_t paketNo = 0;          // derin uykuda korunur / kept during deep sleep
11
12void setup() {
13  pinMode(SENSOR_GUC, OUTPUT);
14  digitalWrite(SENSOR_GUC, HIGH);
15  delay(200);                                // sensör otursun / let the sensor settle
16  int ham = analogRead(NEM_PIN);
17  digitalWrite(SENSOR_GUC, LOW);
18  int nem = constrain(map(ham, KURU, ISLAK, 0, 100), 0, 100);   // % nem / % moisture
19
20  LoRa.setPins(PIN_SS, PIN_RST, PIN_DIO0);
21  if (LoRa.begin(433E6)) {
22    LoRa.setSpreadingFactor(10);             // uzak tarla için daha yüksek SF / higher SF for a distant field
23    LoRa.setSignalBandwidth(125E3);
24    LoRa.setSyncWord(0xF3);
25    LoRa.enableCrc();
26    LoRa.setTxPower(10);
27    LoRa.beginPacket();
28    LoRa.print("T1,");                       // düğüm kimliği / node id
29    LoRa.print(paketNo++);
30    LoRa.print(",");
31    LoRa.print(nem);                         // ör. "T1,42,37" / e.g. "T1,42,37"
32    LoRa.endPacket();
33    LoRa.sleep();                            // SX1278 uykuda 1 uA altı / under 1 uA asleep
34  }
35  esp_sleep_enable_timer_wakeup(UYKU_US);
36  esp_deep_sleep_start();                    // 10 dk sonra setup() baştan başlar / setup() restarts after 10 min
37}
38
39void loop() {}
40

電池寿命を見積もってみましょう。ノードは10分(600秒)ごとに約0.5秒間起動し、その間の平均消費電流は約100 mAです。スリープ中は、ESP32のモジュール単体とRa-02を合わせて約15 µAを消費します。平均電流は(0.5 × 100)/ 600 + 0.015 ≈ 0.1 mAです。2000 mAhの18650電池なら、理論上は20,000時間、つまり2年以上持ちます。実際には電池の自己放電やレギュレーターの損失で短くなります。注意点として、ESP32 DevKitの完成済みボードはUSBシリアル変換チップやレギュレーターを搭載しているため、スリープ中も数ミリアンペア消費することがあります。スリープ電流が5 mAなら、同じ電池でも17日まで短くなります。長く動かすには、自己消費電流の小さいレギュレーターかモジュール単体を使ってください。電池寿命計算ツールで、自分の値を使って計算できます。

LoRaのプロジェクトアイデア

  • 離れた水タンクの水位:水位センサーで離れたタンクにどれだけ水があるかを測り、自宅に送信します。
  • 郵便受けの通知:庭の門にある郵便受けが開いたことをリードスイッチで検出し、室内のディスプレイに表示します。
  • ミツバチの巣箱のはかり:HX711ロードセルで巣箱の重さを1日に数回送信します。
  • GPSトラッカー:NEO-6M GPSで数km離れた自転車や動物を追跡します。
  • 温室の環境監視:温室の温湿度をLoRaで受信し、しきい値を超えたら自宅で警告を出します。
  • 自作ゲートウェイ:1台のESP32で複数のLoRaセンサーのデータをWi-Fiに転送し、スマホで確認します。

よくある間違いと対処法

症状考えられる原因対処法
「LoRa init failed」(LoRaの初期化に失敗)SPI配線、NSSピン、RESETピンの間違い、または電源なし配線とsetPins()の値を確認し、3.3 Vを測定
送信側は送っているのに受信側で何も受信しない周波数、SF、BW、CR、同期ワードの不一致両側の設定を完全に一致させる
モジュールが熱くなる、またはまったく動かない5 Vで給電した、または5 V信号を入力した3.3 V電源とレベル変換モジュールを使う。モジュールが壊れている可能性あり
送信時にボードがリセットされる3.3 Vラインが急な電流増加に対応できない専用のレギュレーターを使い、電源に100 µFのコンデンサを追加
数メートルしか届かないアンテナがない、または周波数の違うアンテナを使用433 MHzアンテナを取り付ける。アンテナなしの送信はPAを壊すおそれあり
パケットの文字が化けるCRCが無効で、ノイズで破損したパケットを受け入れている両側でenableCrc()を呼び出す
一部のパケットが届かないパケット送信が頻繁すぎて電波が衝突している電波の送信時間に応じてパケット間隔を広げる
最初のテストは、2つのモジュールを同じ机に置き、低出力(setTxPower(2))で行ってください。距離が非常に短いと、高出力によって受信機の入力が飽和し、パケット損失が起こることがあります。机上で動作したら、距離を伸ばしていきます。

LoRaモジュールは、Arduinoプロジェクトを家の外の畑や庭、隣の建物へ広げる最も安価な方法です。適切な周波数とSF、よいアンテナを使えば、数km先で電池で数か月動くセンサーを作れます。短い距離で高速にデータを送るなら、nRF24L01やESP-NOWのほうが適しているかもしれません。BlueGraysアプリには、2台のArduino間の一方向・双方向通信、スマート水やり、ESP32のディープスリープのプロジェクトが、ステップごとの回路図とコード付きで用意されています。これらにLoRaを追加して発展させられます。

よくある質問

LoRaモジュールはどのくらい遠くまで届きますか?

Ra-02のようなSX1278モジュールに簡単なアンテナを付けた場合、通常は市街地で1〜3 km、開けた場所で5〜10 km届きます。アンテナを高く設置し、見通しがよければ15 km以上も可能です。通信距離は主にアンテナの高さ、品質、SFの設定で決まります。

LoRaとLoRaWANの違いは何ですか?

LoRaは無線変調方式だけを指し、2つのモジュールが直接パケットを送り合います。LoRaWANはLoRa上に構築されたネットワークプロトコルです。機器がゲートウェイに送信し、データはインターネット経由でネットワークサーバーに届きます。暗号化や機器管理はプロトコルが処理します。自宅の庭にはLoRa、市全体のネットワークにはLoRaWANが向いています。

LoRaの周波数は433、868、915 MHzのどれを使えばよいですか?

使用する地域によります。ヨーロッパは433 MHzと863〜870 MHz(LoRaWANではEU868)、北米は902〜928 MHz(US915)を使い、ほかの地域にはAU915やAS923などのプランがあります。使用する帯域に合ったモジュールとアンテナを購入し、地域の出力とデューティ比の制限を守ってください。

LoRaモジュールを5 VのArduinoにつなげますか?

直接はつなげません。SX1278は3.3 Vのチップで、5 Vの信号を加えると壊れます。Arduino Unoで使うには、SCK、MOSI、NSS、RESETの信号線にレベル変換モジュールを入れ、別の3.3 Vレギュレーターから給電してください。ESP32とRaspberry Pi Picoは3.3 Vで動作するため、直接接続できます。

LoRaで音声や画像を送れますか?

実用上はできません。LoRaのデータ速度は帯域幅125 kHzで約0.3〜5.5キロビット毎秒で、デューティ比の規則によって送信頻度も制限されます。小さな写真でも数分かかります。LoRaはセンサーの測定値、位置、状態メッセージなどの小さなデータ向けに設計されています。

拡散率(SF)とは何ですか?どの値を使えばよいですか?

SFはLoRaの各シンボルを送信する時間を決めます。SF7からSF12まで、1段階上げるごとに通信距離が伸びますが、データ速度は半分になり、電池消費も増えます。最初はSF9がバランスのよい設定です。距離が足りなければSFを上げ、近距離で速度が必要ならSF7まで下げます。送信側と受信側は同じSFを使う必要があります。

全プロジェクトを見る
2台のArduinoで一方向通信
#57中級
プレミアム

2台のArduinoで一方向通信

2台のArduinoを1本のワイヤーで通信させます。一方のボタンを押すともう一方のLEDが点灯し、もう一度押すと消灯します。送信側のボードがボタンの押下を短いメッセージで伝え、受信側のボードはそのメッセージを受け取るとLEDの点灯と消灯を切り替えます。機器同士が情報を伝える仕組みを、最もシンプルな形で確かめられます。

4.4(37)
50
2台のArduinoで双方向通信
#58中級
プレミアム

2台のArduinoで双方向通信

2台のArduinoをケーブルでつないで通信します。片方のボタンを押すともう片方のライトが点灯し、もう一度押すと消灯します。両方のボードで同じプログラムを動かすので、どちらからでもメッセージを送受信できます。ボード同士でメッセージをやり取りする仕組みを、シンプルな構成で学べます。

4.5(20)
26
スマート水やりステーション
#83上級
プレミアム

スマート水やりステーション

旅行中も植物が枯れないよう、自動で水やりをするシステムです。土壌水分センサーで土の湿り具合を測定し、乾燥するとArduinoが給水ポンプを数秒間動かして、青いライトを点灯させます。水分が適切なときは緑のライトが点灯します。土がひどく乾燥すると、赤いライトが点滅し、ブザーが鳴って知らせます。

5.0(42)
57
ESP32のディープスリープで節電(OLED + RTC RAMカウンター)
#135上級
プレミアム

ESP32のディープスリープで節電(OLED + RTC RAMカウンター)

ESP32のディープスリープモードは、CPUとほとんどの周辺機器を停止し、消費電流を約10 µAまで抑えます。電池で動くIoT機器に欠かせない機能です。このプロジェクトでは、タイマー(15秒)、外部ピン(EXT0、ボタンはGPIO 33)、タッチ(T0/GPIO 4)の3種類の復帰方法を使います。RTC_DATA_ATTRを付けた変数はディープスリープ中も保持され、起動回数、タイマーによる復帰回数、ボタンによる復帰回数を継続して記録できます。復帰するたびにSSD1306 OLEDディスプレイに復帰理由と回数を表示します。

4.3(10)
16
ESP32動体検知アラーム(PIR + ブザー + LED + Telegram)
#145上級
プレミアム

ESP32動体検知アラーム(PIR + ブザー + LED + Telegram)

PIRセンサーが動きを検知するとブザーとLEDを作動させ、同時にTelegramで持ち主に即座に通知するスマート防犯アラームです。アラームが繰り返される頻度を抑えるため、30秒のクールダウン(待ち時間)を設けています。この仕組みはPIRの検知が正しいかを確認したり、誤検知をなくしたりするものではありません。家の防犯、ガレージの監視、倉庫や作業部屋などに使えます。ESP32-CAMなら写真付きの通知を追加でき、通常のESP32 DevKit V1ではテキストで通知します。

0.0(0)
9
ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)
#144上級
プレミアム

ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)

ESP32で日時付きの温度・湿度記録システムを作ります!DHT22で1分ごとに温度と湿度を読み取り、DS1307 RTCから取得した日時とともにmicroSDカードへCSV形式で記録します。OLEDには最新の温度を大きな文字で表示し、湿度のパーセント値、日時、総記録数も表示します。SDカードの/temp_log.csvファイルはExcel、Google Sheets、Pythonのpandasで開いて分析できます。温室の監視、家や部屋の温度管理、実験室のデータ収集、食品の保管環境や養蜂箱の監視に適しています。

4.7(7)
12
BluetoothでスマートフォンからLEDを操作
#34初級
プレミアム

BluetoothでスマートフォンからLEDを操作

スマートフォンで部屋の照明をつけたり消したりするための、小さな練習です。Bluetoothモジュールがスマートフォンから送られた文字をArduinoに伝えます。ある文字で赤いLEDが、別の文字で緑のLEDが点灯し、同じ文字を小文字で送ると消灯します。無線操作の仕組みを、ごくシンプルな形で学べます。

4.8(68)
89