ESP32(Arduino)で SigFox をはじめるまで

今さら?かもしれませんが、今回Sigfoxを試してみました。Sigfoxは数キロメートル離れた基地局へ直接データを送信できるサービスです。一度に送れるデータ数は16byteで、一日に〜140回しか送れませんが、センサーデータなどであれば十分ですよね。なにより、このSigfoxサービスは値段が安い!1デバイスあたりの年間費は1000円程度です。今回は、ESP32とSigfoxのブレイクアウトボード BRKLSM100A を使ってSigfox通信してみました。

SigFoxの具体的な設定方法や、技術的な質問にはお答えできませんのでご了承ください。お仕事依頼の場合は こちらからお問い合わせ ください。

SigFoxとは

SigFoxは、低消費電力の広域ネットワーク(LPWAN: Low Power Wide Area Network)技術の一つで、主にIoTデバイス向けに設計されています。LPWANは0G回線とも呼ばれてます。Sigfoxサービスを展開するのはフランスの会社ですが、日本では京セラさんが代理店として窓口に立ってくれています。なにか分からないことがあれば、京セラさんが丁寧にご回答してくれます。

というか、情報がすくなすぎて、京セラさんがいなかったら利用できないレベルで躓きました(笑)

以下、Sigfoxの特徴をまとめておきます。

低消費電力

デバイスのバッテリー寿命が数年に渡ることが可能です。通信頻度が低く、消費電力が非常に少ない設計になっています。Sigfoxデバイスを制御するには、UARTのATコマンドになります。ArduinoやESP32、またはPICなどでも制御できるはずです。低消費電力のPICであれば、Sigfoxデバイスと組み合わせて太陽電池やリチウム電池で長期間運用も実現可能かもしれませんね。

広範囲カバー

SigfoxデバイスからSigfox基地局(Sigfoxゲートウェイ)まで、数キロメートルから数十キロメートルにわたる広範囲の通信が可能です。都市部では数キロメートル、農村部では数十キロメートルの通信距離をカバーします。Sigfox GW(ゲートウェイ)は自前で用意する必要はありません。下記URLにSigfox通信できるエリアが示されています。日本の首都圏で広く展開されています。山間部などや一部地方ではつながらない感じでしょうか。

世界中の多くの国で利用可能で、国境を越えた通信が容易に行えます。Sigfoxのネットワークオペレーターがインフラを提供します。

低データレート

1回の通信で最大12バイトのペイロードを送信できます。例えば 0123456789AB で12バイトですね。0、1のbitを16進数表現させてしまえば、かなりの情報量を送れますね。一日の送信回数に制限があり、通常は140回までです。

低コスト

BRKLSM100A のようなBreakout Board Devkit(開発キット)の場合、1年間の無償回線を利用できるようです。以下のURLから、Devkit情報の入力、及びユーザーアカウント情報をご入力してDevkit登録を行ってください。

それに気づかず、私の場合は先に回線を買ってしまいました😅 後から連絡しても無償回線を提供いただけなかったので注意です。

下記ページをよく読んでから、回線契約しましょう。

Sigfox回線を購入する際には、プランが色々あります。送信回数制限によって値段が違っています。

最大送信回数年間費(1/device)
2¥671
70¥814
140¥1221

私の場合は、70回制限の年間814円/deviceプランを選びました。もう少しお金を出せば、位置情報も追加できるようです。盗難防止や以上検知の意味では、リアルタイムな位置情報が分かったほうが良いのかもしれません。

利用ケース

項目内容
スマートメーターガス、水道、電力メーターのリモートモニタリング。
資産追跡コンテナ、車両、ペットなどの位置追跡。
環境モニタリング気象センサーや環境データの収集。
セキュリティ防犯センサーやアラームシステム。

技術的な詳細

通信方式としては、アップリンク(デバイスからクラウド)とダウンリンク(クラウドからデバイス)の通信が可能です。ただし、ダウンリンクは制限があり、主にアップリンク通信が主体です。

周波数帯は、868MHz(ヨーロッパ)および902MHz(北米)など、地域によって異なる周波数帯を使用します。日本において免許不要の920MHz帯を利用します。Sigfoxデバイスが届いたら、ATコマンドを使ってRC (region configuration) をその国に合わせて設定しないとデータ通信できませんので注意が必要です。後ほど具体的なプログラミングで解説します。

Sigfoxは超狭帯域(UNB: Ultra Narrow Band)を使用して通信を行います。

メリットとデメリット

ここまでのまとめとして、メリットとデメリットを挙げておきます。

メリットは以下の通りです。

  • 長距離通信が可能で、インフラのコストが低い。
  • デバイスの運用コストが低い。
  • 簡単なインテグレーションとスケーラビリティ。

デメリットは以下の通りです。

  • データレートが低く、大量のデータ送信には不向き。
  • 通信のリアルタイム性が低い。
  • 利用可能エリアが限られている場合がある。

これらの特徴により、Sigfoxは低消費電力で長距離通信が必要なIoTアプリケーションに適しています。

ESP32からSigfoxでデータ送信するまで

ここでは主に躓いた部分を取り上げつつ、ESP32からSigfoxでデータ送信するまでのざっくりとした流れを解説いたします。詳細な設定方法は、京セラさんのブログページをご参考ください。

ゴール(SigfoxクラウドでCallback登録してSlackへWebhookさせる)

下記のようなイメージでシステム構築してみました。

ESP32とSigfoxデバイス BRKLSM100A はUART、つまりシリアル通信で繋ぎます。ATコマンドでデータ送信をSigfoxデバイスへ命令します。データ送信に成功すると、Sigfoxクラウドのバックエンド画面で受信データを確認できます。受信データはSlackはじめ、アプリケーションへ送信できます。この仕組みをSigfoxクラウドではCallbackと呼んでいます。SlackのWebhook URLをCallbackに登録すれば、デバイスからデータ送信されたタイミングで、Slackに通知させることができます。SigfoxクラウドのCallback送信の仕組みは、単なるHTTPリクエストです。Content typeを設定できるので、json形式でPOSTさせることも可能です。

ESP32とSigfoxデバイスの配線

シリアル通信に使うTXとRXの配線に注意してください。

ESP32LSM100A
3V3VCC
GNDGND
16 (RX)TX
17 (TX)RX
4RST

Sigfoxクラウドの設定

デバイスの数だけ回線を契約したら、Sigfoxクラウドでデバイス登録をします。DEVICE TYPEを作成してからDEVICEを追加するようにします。手順は京セラさんのブログに詳しく掲載されてますので、そちらをご参考ください。

PACについて

パッケージは捨てないで!
パッケージは捨てないで!

デバイスが届いたら、パッケージに記載されているDevice IDとPACナンバーを使ってSigfoxクラウドにデバイス登録します。PACはワンタイムパスワードのようなものです。一度登録するとそのPACナンバーは無効になります。同じデバイスを再度登録する場合は、問い合わせてPACナンバーを再発行してもらう必要があります。

PACはSigfoxクラウド側で必要になるだけで、デバイス自体に設定したりするものではありません。

デバイスがActivateになるタイミング

デバイスがActivateになるタイミングは、はじめてSigfoxクラウドへ送信成功したときです。その時点でToken stateがOKになり、契約中の回線(Contracts)が紐づけられて利用開始となります。ここら辺のタイミングは、ライフサイクルとして下記ブログで詳しく解説されています。

注意として、アクティベート後に登録したデバイスを削除してしまうと紐づけられた回線契約も無効になってしまいます。回線費が無駄金になってしまいますので、デバイス削除は基本しないようにしましょう。デバイス自体は使えますが、PACの再発行と新たな回線契約が必要になります。

SigFoxデバイスの設定①(通信方法)

BRKLSM100A デバイスは、初期設定ではLoRa通信になってます。また、RCZをRC1からRC3に変更する必要があります。そのため、データを送信する前にATコマンドで設定を変更しておきます。

SigfoxデバイスにUARTで AT+MODE=0 を送信します。

  • 0: SigFox
  • 1: LoRa

デバイスを購入したmarutsuさんや、京セラさんの案内では AT+MODE=1 を送信するように書かれてますが、←コレ間違ってると思います!

▼ こちら本家のユーザーマニュアルの19ページをご確認いただければ分かります。

pdf
LoRa & Sigfox Mode Change. After a MCU reset.
<mode>: [ 0: SigFox, 1: LoRa ]

と記載されてます。

1ではなく0がSigfox通信の設定になるはずです。つまり AT+MODE=0 がSigFox通信のです。実機でも確認しましたが、その通りになりますので注意してください。

SigFoxデバイスの設定②(Region Configuration)

さらにRC (region configuration)の設定の必要がありますが、こちらも案内通りだとうまく設定できませんでした。案内では AT$TM=3C,0 となってますが、実際にコマンド送信してみると ERROR 0x50 のエラーが返ってきてしまい、設定変更できません。

そこで ユーザーマニュアル を読み直し、AT$RC=3C でコマンド送信したところ、RC3に切り替わりました。SigFoxへのデータ送信もはじめて成功しました!ここまでかなり大変でしたが、ようやく送信に成功してとても嬉しいです。Arduino界隈でSigFoxを試されている方の情報が少ないところをみると、はじめの段階で躓いて諦めてしまった方々が多いのではないでしょうか?だとしたら、とても残念ですね😢

ソースコード

先に記述した通り、ESP32とSigfoxデバイスを配線後、SigFoxクラウドへデータ送信に成功したソースコードです。

cpp
#include <Arduino.h>
#include <HardwareSerial.h>

// ESP32 LSM100A
// 16 → TX
// 17 → RX

#define MOD_RESET 4
#define MOD_TX 16
#define MOD_RX 17

HardwareSerial Sigfox(2);

void sendCommand(String command, int timeout) {
    Sigfox.print(command);
    Sigfox.print('\r');
    delay(1000);

    String response = "";
    long limit = millis() + timeout;

    while (millis() < limit) {
        while (Sigfox.available()) {
            char c = Sigfox.read();
            response += c;
        }
    }

    Serial.println(response);
}

void setup() {
    Serial.begin(115200);
    Sigfox.begin(9600, SERIAL_8N1, MOD_TX, MOD_RX);
    delay(1000);

    Serial.println("Sigfox Module Ready....");

    // Sigfoxモジュールをリセット
    pinMode(MOD_RESET, OUTPUT); // 4番ピンをリセットピンとして設定
    digitalWrite(MOD_RESET, LOW);
    delay(100);
    digitalWrite(MOD_RESET, HIGH);
    delay(2000); // 数秒待機してSigfoxモジュールが安定するのを待つ

    Serial.println("Start");

    // SigfoxモジュールにATコマンドを送信
//    sendCommand("AT", 3000);

    Serial.println("AT+LINKC? ....");
    sendCommand("AT+LINKC?", 3000);
    // ATコマンド参考: https://www.kccs.co.jp/sigfox/solution/product/device71/pdf/LSM100A_UserManual.pdf

    Serial.println("AT+MODE=0 ....");
    // 通信方法の変更 [0: SigFox, 1: LoRa]
    sendCommand("AT+MODE=0", 3000);

//    Serial.println("AT$TM=3C,0 ....");
//    sendCommand("AT$TM=3C,0", 3000);
    Serial.println("AT$RC=");
    sendCommand("AT$RC=3C", 3000);

    // デバイス情報を取得
    Serial.print("Device ID: ");
    sendCommand("AT$ID", 3000);
//    Serial.print("PAC: ");
//    sendCommand("AT$PAC", 3000);
}

void loop() {
    // サンプルデータを送信
    sendCommand("AT$SF=0123456789AB,1", 5000);
    // 10分待機
    delay(10 * 60 * 1000);
//    delay(10 * 1000);
}

【注意】デバイス起動のタイミング

はじめ、ATコマンドを送信してもAT_ERRORが返ってきてしまい困ったものでした。原因としてはSigFoxデバイス起動のタイミングでした。電源を入れてからESP32起動後、一度SigFoxデバイスをリセットする必要があります。ソースコードを見てもらうと分かりますが、下記のようにしてリセット処理してます。

cpp
    // Sigfoxモジュールをリセット
    pinMode(MOD_RESET, OUTPUT); // 4番ピンをリセットピンとして設定
    digitalWrite(MOD_RESET, LOW);
    delay(100);
    digitalWrite(MOD_RESET, HIGH);
    delay(2000); // 数秒待機してSigfoxモジュールが安定するのを待つ

ESP32の4番ピンとSigFoxデバイスのRSTピンを接続して制御できます。その後、UARTによるATコマンド送信に失敗することがなくなりました。この部分もマニュアルなどに情報がなく、かなり躓く部分だと思われます。

Callback(Slackへの送信)がうまくいかない

SlackのWebhook APIへ送信するHTTPリクエストは下記の通りです。

sh
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/XXXXXXXXXXXX

最初はSigFoxクラウドのCallback設定をjson形式ではなく、x-www-form-urlencodedで設定していたため、400エラーが返ってきてました。

sh
400 - Bad Request - #1
POST https://hooks.slack.com/services/XXXXXXXXXXXX HTTP/1.1
content-length: 22
accept-language: fr
host: hooks.slack.com
content-type: application/x-www-form-urlencoded
accept-encoding: gzip,deflate
accept-charset: UTF-8;q=0.9,*;q=0.7
user-agent: SIGFOX

text=30CE86D1719539412

この問題は content-typeapplication/json を設定すれば解決できます。データ内容などの変数も使えますので、下図のように適宜Bodyに設定します。

正直ここにどり着くまでに、何度もSigFox通信あきらめようと思いました。。ですが、京セラさんの親切な窓口サポートのおかげもあり、なんとかゴールに辿り着きました。

SlackでSigFoxデータ受信
SlackでSigFoxデータ受信

さて、SigFoxの気になる通信距離ですが、窓際でなくても、室内の奥まった場所からでもデータ送信に成功しているのでかなり期待できそうです!

この記事が少しでも参考になれば幸いです。なお、SigFoxの具体的な設定方法や、技術的な質問にはお答えできませんのでご了承ください。お仕事依頼の場合は こちらからお問い合わせ ください。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

ESP32搭載ボード
ESP32の書籍
Arduinoで人気の周辺パーツ
M5Stackのオススメ参考書
M5Stack製品
M5StickCで使えるHat
ESP32ボード