「センサーデータを数キロ先まで飛ばしたい」「Wi-FiもBluetoothも届かない屋外でIoTをやりたい」——そんな悩みを抱えている方に、LoRa(ローラ)という技術がまさにドンピシャです。

LoRaは「Long Range(長距離)」の名前の通り、見通し距離で最大数キロメートルの無線通信が可能な規格です。消費電力も極めて低く、畑・山林・河川・駐車場など、インフラが整っていない屋外環境のIoTにうってつけなんです。

今回は、ArduinoとLoRaモジュール「SX1278(RA-02)」を使って、送信機→受信機のシンプルな長距離無線通信を実装する方法を、回路図・コード・応用例まで丸ごと解説します!

LoRaとは?Wi-Fi・Bluetoothとどう違う?

LoRa IoT outdoor sensor
LoRa IoT outdoor sensor / Photo by Bmonster Lab via Pexels

まず、ざっくりと位置づけを整理しておきましょう。

規格 通信距離 消費電力 通信速度 主な用途
Wi-Fi 〜100m 速い 動画・データ転送
Bluetooth 〜50m 低〜中 スマホ連携
LoRa 〜数km 極低 遅い 屋外センサー・農業IoT

LoRaは通信速度こそ遅いですが、温湿度・土壌水分・CO2濃度など、数十バイト程度のセンサーデータを定期送信するだけなら十分すぎるスペックです。農業IoT・スマートシティ・物流管理など、世界中で活用されています。

必要なものと配線(回路図)

用意するもの

  • Arduino UNO(または Nano)× 2台(送信機・受信機用)
  • LoRaモジュール SX1278(RA-02) × 2個
  • ジャンパワイヤ・ブレッドボード
  • (応用)DHT11温湿度センサー × 1個

⚠️ SX1278は3.3V動作です。Arduino UNO(5V)と直結すると壊れる可能性があります。必ずレベルシフター(3.3V←→5Vの変換モジュール)を使うか、3.3V出力対応のArduino(Arduino Nano Every等)を使いましょう。もしくは後述のように3.3Vピンから給電し、SPIラインにレベルシフターを挟む構成が安全です。

SX1278(RA-02)とArduino UNOの配線

SX1278はSPI通信で動きます。ピン対応表はこちらです。

SX1278(RA-02) Arduino UNO
VCC 3.3V(⚠️ 5Vは不可)
GND GND
SCK D13(SPI CLK)
MISO D12(SPI MISO)
MOSI D11(SPI MOSI)
NSS(CS) D10
RESET D9
DIO0 D2

📡 アンテナも忘れずに!RA-02モジュールにはアンテナ端子(U.FL)があります。アンテナなしで送信するとモジュールが壊れる場合があるので、必ず適切なアンテナ(433MHz対応)を取り付けてください。

ライブラリのインストール

Arduino IDEを開いて、「RadioHead」ライブラリをインストールします。

  1. Arduino IDE → スケッチ → ライブラリをインクルード → ライブラリを管理
  2. 検索欄に「RadioHead」と入力
  3. 「RadioHead by Mike McCauley」をインストール

RadioHeadはLoRa(SX1278)を含む多数の無線モジュールをサポートする定番ライブラリです。安定していて情報も豊富なので、初心者にもおすすめですよ。

コード①:送信機(センサーデータを飛ばす)

まずは送信側のArduinoのコードです。シンプルなメッセージを一定間隔で送信します。


#include <SPI.h>
#include <RH_RF95.h>  // RadioHeadのLoRaドライバ

// ピン設定(配線と一致させること)
#define RFM95_CS   10  // NSS(チップセレクト)
#define RFM95_RST   9  // RESET
#define RFM95_INT   2  // DIO0(割り込み)

// 周波数:日本では920MHz帯が推奨(RA-02は433MHz帯モデルも多い)
// 購入したモジュールの対応周波数に合わせること!
#define RF95_FREQ 433.0

RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup() {
  Serial.begin(9600);
  pinMode(RFM95_RST, OUTPUT);

  // モジュールをリセット
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  // LoRa初期化チェック
  if (!rf95.init()) {
    Serial.println("LoRa初期化失敗!配線を確認してください");
    while (1);  // 止める
  }

  // 周波数を設定
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("周波数設定失敗");
    while (1);
  }

  // 送信出力パワーを設定(5〜23 dBm)
  rf95.setTxPower(13, false);
  Serial.println("LoRa送信機 起動完了!");
}

void loop() {
  // 送信するメッセージを作成
  String message = "温度:25.3 湿度:62.1";
  uint8_t buf[message.length() + 1];
  message.getBytes(buf, sizeof(buf));

  Serial.print("送信中: ");
  Serial.println(message);

  // データを送信
  rf95.send(buf, sizeof(buf));
  rf95.waitPacketSent();  // 送信完了まで待機

  Serial.println("送信完了!");
  delay(3000);  // 3秒ごとに送信
}

ポイントをまとめるとこんな感じです。

  • rf95.init():モジュールの初期化。失敗したらシリアルモニタにエラーが出ます
  • setFrequency():433MHz帯モジュールなら433.0、920MHz帯なら920.0を設定
  • setTxPower():送信電力。大きいほど遠くまで届くが電池消耗も増える
  • rf95.send() → waitPacketSent():送信→完了待ち、のセットで使います

コード②:受信機(データを受け取る)


次に受信側のArduinoです。送信機から飛んできたデータをシリアルモニタに表示します。


#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS   10
#define RFM95_RST   9
#define RFM95_INT   2
#define RF95_FREQ 433.0

RH_RF95 rf95(RFM95_CS, RFM95_INT);

void setup() {
  Serial.begin(9600);
  pinMode(RFM95_RST, OUTPUT);

  // モジュールリセット
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  if (!rf95.init()) {
    Serial.println("LoRa初期化失敗!");
    while (1);
  }

  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("周波数設定失敗");
    while (1);
  }

  Serial.println("LoRa受信機 待機中...");
}

void loop() {
  // データが届いているか確認(ノンブロッキング)
  if (rf95.available()) {
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];  // 受信バッファ
    uint8_t len = sizeof(buf);

    if (rf95.recv(buf, &len)) {
      // 受信したデータを文字列に変換して表示
      Serial.print("受信データ: ");
      Serial.println((char*)buf);

      // RSSI(受信信号強度)を表示。数値が高いほど信号が強い
      Serial.print("RSSI(信号強度): ");
      Serial.println(rf95.lastRssi(), DEC);

    } else {
      Serial.println("受信失敗(データ破損の可能性)");
    }
  }
}

受信側のポイントはこちらです。

  • rf95.available():受信データが来ているかをチェック(来ていなければスルーしてループを続ける)
  • rf95.recv():バッファにデータを格納
  • rf95.lastRssi():受信信号強度(dBm)。デバッグや通信品質確認に役立ちます

シリアルモニタで動作確認しよう

送信機・受信機それぞれをPCに接続し、2つのArduino IDEシリアルモニタを開きます(ボーレートは9600)。

送受信が正常に動いていれば、受信側のシリアルモニタにこんな出力が出るはずです。


LoRa受信機 待機中...
受信データ: 温度:25.3 湿度:62.1
RSSI(信号強度): -42
受信データ: 温度:25.3 湿度:62.1
RSSI(信号強度): -43

RSSIが-100dBm以下になってくると信号が弱い・ギリギリという状態です。距離を縮める・アンテナを変えるなど対策を検討しましょう。

農業IoTへの応用例:畑の温湿度を遠隔モニタリング

LoRaの真価が発揮されるのが、屋外・遠距離のシナリオです。たとえば農業IoTでの構成イメージはこんな感じです。

  • 🌱 センサーノード(畑側):Arduino + LoRaモジュール + DHT11(温湿度)+ 土壌水分センサー + 太陽光パネル(電池レス運用)
  • 📡 ゲートウェイ(農小屋や建物側):Arduino + LoRaモジュール + Ethernet/Wi-Fiシールド(クラウドへ転送)
  • ☁️ クラウド・スマホ:データを蓄積・グラフ表示・アラート通知

センサーノード側の送信コードをほんの少し修正して、DHT11のデータを乗せてみましょう。


#include <SPI.h>
#include <RH_RF95.h>
#include <DHT.h>  // DHT11ライブラリ(Arduino IDEでインストール)

#define RFM95_CS  10
#define RFM95_RST  9
#define RFM95_INT  2
#define RF95_FREQ 433.0
#define DHTPIN 5      // DHT11のデータピン
#define DHTTYPE DHT11

RH_RF95 rf95(RFM95_CS, RFM95_INT);
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(RFM95_RST, OUTPUT);

  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  if (!rf95.init()) { while (1); }
  if (!rf95.setFrequency(RF95_FREQ)) { while (1); }
  rf95.setTxPower(13, false);
  Serial.println("農業IoTセンサーノード 起動");
}

void loop() {
  float temp = dht.readTemperature();   // 気温(℃)
  float humi = dht.readHumidity();      // 湿度(%)

  // 読み取り失敗チェック
  if (isnan(temp) || isnan(humi)) {
    Serial.println("DHT11読み取りエラー");
    delay(3000);
    return;
  }

  // 送信データを文字列で組み立て
  String payload = "T:" + String(temp, 1) + ",H:" + String(humi, 1);
  uint8_t buf[payload.length() + 1];
  payload.getBytes(buf, sizeof(buf));

  Serial.print("送信: ");
  Serial.println(payload);

  rf95.send(buf, sizeof(buf));
  rf95.waitPacketSent();

  delay(10000);  // 10秒ごとに送信(電池節約)
}

このコードのポイントは送信間隔を長めに取ること(今回は10秒)。電池駆動のセンサーノードでは、送信間隔を30秒〜5分に伸ばすと大幅な省電力化が見込めます。Arduinoのスリープモードと組み合わせると、単三電池数本で数ヶ月運用することも可能です。

LoRa通信のトラブルシューティング


うまく通信できないときは、以下を順番に確認してみてください。

  • VCCは3.3Vになっているか?(5V接続は即故障の原因)
  • アンテナは取り付けているか?(アンテナなし送信はモジュールを傷める)
  • 送信側・受信側の周波数は同じか?(setFrequency()の値を揃える)
  • SPIピン配線に間違いはないか?(MISO・MOSIの取り違えが多い)
  • シリアルモニタに「初期化失敗」と出ていないか?(出ていたら配線が第一容疑者)

まとめ

今回はArduinoとLoRaモジュール(SX1278/RA-02)を使った長距離無線通信の基本を、回路配線・送受信コード・農業IoT応用まで一気に解説しました。

改めてLoRaの魅力をおさらいすると——

  • 📡 数キロ届く長距離通信
  • 🔋 電池で長期間動く超低消費電力
  • 🌾 屋外・農業・インフラ監視などに最適

Wi-FiやBluetoothでは手が届かなかった「遠い場所のIoT」が、LoRaなら驚くほど手軽に実現できます。ぜひ手元で2台のArduinoを使って試してみてください!まずはシリアルモニタに受信データが表示された瞬間、きっとテンション上がりますよ 😊

次のステップとしては、受信データをSDカードに保存したり、クラウドへ転送したりする構成も面白いです。LoRaWAN(LoRaを使った広域ネットワーク規格)への展開も視野に入れると、本格的なIoTシステムへと発展させていけます。一緒にどんどん試していきましょう!

📡 Arduinoをもっと深く学ぼう!

Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。