M5Stack COM.X Sigfoxの使い方

お待たせしました。遂にM5Stack公式から、Sigfox通信用拡張モジュール**COM.X Sigfox版**がリリースされました。M5StackにセルラーやLoRa通信等機能を追加するCOM.Xファミリーとしての製品です。スイッチサイエンスから販売されていますので、[こちら](https://www.switch-science.com/catalog/6624/)からご購入下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/25cc0a5a-b635-5ccc-121e-6c0014d8bb16.png)


#COM.X Sigfoxの仕様
COM.X Sigfoxは、SEONG JI（旧Wisol）[SFM11R3](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/module/DS_SFM11R3000_REV05.pdf)を搭載した拡張ボードで、Sigfox ATコマンド（シリアル通信）でSigfox通信を制御することができます。
主な仕様は下記の通りです。

|項目|仕様|
|:---|:---|
|サイズ|54.2 x 54.2 13.2 mm|
|質量|27g|
|付属アンテナ|ANT-916-CW-HWR-SMA|
|対応RC|RC3（日本:ARIB T-108準拠）|
COM.X Sigfoxの[公式ドキュメント](https://docs.m5stack.com/#/en/module/comx_sigfox)には、RC5も記載されていますが、韓国向けのRadio Configurationですので、日本国内ではRC5を使わないようにしてください。

#M5Stack COM.X Sigfoxユースケース
M5StackはArduino IDEやUIFlow、MicroPythonで開発可能であり、COM.Sigfoxの位置づけは、Arduino UNO向けの[Sigfox Shield for Arduino (UnaShield)](https://www.kccs-iot.jp/solution/product/device10/)やArduino ZERO向けの[UnaMKR](https://www.kccs-iot.jp/solution/product/device41/)のM5Stack版となります。
加え、M5Stackは、320 x 240のカラーLCDや3つのボタン、バッテリーベースが付いていますので、センシング情報をディスプレイに表示しながら、定期的ないし異常発生時に、そのデータをSigfoxで送信するというユースケースを簡単に構築することができます。

#COM.X SigfoxはDevkit扱い
COM.X SigfoxはDevkit扱いとなっていますので、1年間の無料回線が付いています。[こちら: *Sigfox Devkit（開発キット）を1年間の無償回線で利用する*](https://qiita.com/ghibi/items/5893923b44f1757294e9)を参考にSigfoxクラウドへデバイス登録してください。2年目以降は、同サイト([Sigfox Buy](https://buy.sigfox.com))から回線購入して、継続利用することも可能です。

#COM.X Sigfoxモジュールの拡張
M5Stack、M5Core2ともに、拡張モジュールに対応していますが、M5Core2では、拡張モジュールを取り付けるため、2mm径の六角レンチが必要となります。
それぞれを取り付けたイメージは下のようになります。

|M5Stack + COM.X Sigfox|M5Core2 + COM.X Sigfox|
|:-----:|:-----:|
|![IMG_5261.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/36fc9252-aff8-661d-52bb-eae162803527.jpeg)|![IMG_5257.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/a1012be1-917f-42d8-d999-845d64bd2c18.jpeg)|

COM.X Sigfoxを拡張した場合、M5Stackは付属のバッテリーモジュールを、そのまま取り付けられますが、M5Core2の場合は、本体にバッテリーが付いているため、バッテリーモジュールを追加する必要がありません。ただ、下の写真のように、背面がむき出しになるので、何らかのベースユニットを用意した方が見た目は綺麗ですね。
![IMG_5136 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/957e6394-9c48-ff3f-7d60-27fc426484dd.jpeg)

#M5Stackの開発準備
ここでは、`M5Stack`及び`M5SCore2`を使ったCOM.X Sigfoxの使用方法について説明します。

1. Arduino IDEのインストール (M5Stack/M5Core2共通)
2. USBシリアルドライバーのインストール (M5Stack/M5Core2共通)
3. ボード定義のインストール(M5Stack/M5Core2)
4. ライブラリのインストール(M5Stack/M5Core2)

##USBシリアルドライバーのインストール (共通)
M5StackをPCと接続するため、USBシリアルドライバーをインストールします。

###Windows の場合
1. [M5Stack の Web サイト](https://m5stack.com/pages/download)からWindows用の CP210X Driverをダウンロードします。
2. ダウンロードした `CP210x_VCP_Windows.zip`を展開します。
3. CP210xVCPInstaller_x64_v6.7.0.0 をダブルクリックしてインストールします。
4. 付属のUSB Type-Cケーブル（Core2には付属されていません）を使用して PC と接続します。[デバイスマネージャ] を開き [ポート (COM と LPT)] で `Silicon LabsCP210x USB to UART Bridge (COMxx)`が表示されることを確認してください。

###macOS の場合
1. [M5Stack の Web サイト](https://m5stack.com/pages/download)からmacOS用の CP210X Driverをダウンロードします。
2. ダウンロードした`CP210x_VCP_MacOS.zip`を展開します。
3. `SiLabsUSBDriverDisk.dmg`をダブルクリックしてマウントします。
4. Finderでマウントされた`Silicon Labs VCP Driver Install Disk`が開かれますので `Silicon Labs VCP Driver.pkg`をダブルクリックしてインストールします。
5. 付属のUSB Type-Cケーブル（Core2には付属されていません）を使用して PC と接続します。
6. [システム環境設定] > [セキュリティとプライバシー] でドライバーのロードを承認します。

##ボード定義のインストール(M5Stack/M5Core2)
M5Stack、M5Core2をArduino IDEで扱うためボード定義をインストールします。

1. Arduino IDEを起動します。
2. メニューから [ファイル] > [環境設定] を選択します。
3. [設定タブ] の [追加のボードマネージャの URL:] へ以下の URL を入力して [保存] をクリックします。 `https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json`
4. Arduino IDEの [ツール] > [ボード] > [ボードマネージャ] を選択します。
5. 一覧の中から`M5Stack by M5Stack official`を選択 (M5Stackで検索すると見つけやすいです）しインストールをクリックします。
6. Arduino IDEの [ツール] > [ボード] メニューから、接続するM5に合わせて、ボードを選択します。
  - 【M5Stackの場合】Arduino IDEの [ツール] > [ボード] > [M5Stack Arduino] > **[M5Stack-Core-ESP32]** を選択します。
  - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/505d2af7-4559-9ec6-bc11-c106b8a00dfb.png)
  - 【M5Core2の場合】Arduino IDEの [ツール] > [ボード] > [M5Stack Arduino] > **[M5Stack-Core2]** を選択します。
  - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/8802a6d4-9c98-31e6-d4aa-53f6b6cbc138.png)

##ライブラリのインストール(M5Stack/M5Core2)
開発において、M5ライブラリを使用できるようにライブラリをインストールします。

1. Arduino IDEを起動します。
2. Arduino IDEの [スケッチ] > [ライブラリをインクルード] > [ライブラリを管理…] を選択します。
3. 使用するM5に合わせ、一覧の中からライブラリをインストールします。
 - 【M5Stackの場合】`M5Stack by M5Stack`を選択。
 - 【M5Core2の場合】`M5Core2 by M5Stack`を選択。

#M5Stackで開発をする
M5Stack、M5Core2で開発する場合、各ライブラリをインクルードします。

- M5Stack用ライブラリをインストールした場合、`#include <M5Stack.h>`がインクルードされます。
- M5Core2用ライブラリをインストールした場合、`#include <M5Core2.h>`がインクルードされます。



#サンプルスケッチ
ボタンクリックに応じ、①UPLINK（上り）メッセージのSigfox送信、②DOWNLINK（下り）要求付メッセージのSigfox送信、③ID/PAC情報の取得を行うサンプルスケッチをM5Stack、M5Core2用に用意しました。
##M5Stack用サンプルスケッチ
```m5stask-sigfox.c
#include <M5Stack.h>
 
void setup() {
  M5.begin(true, false, true);
  Serial2.begin(9600, SERIAL_8N1, 16, 17);
  showTempl();
}

void loop() {
  if (Serial2.available()) {
    displayResults(Serial2.readString());
  }
  M5.update();
 
  if (M5.BtnA.wasReleased()) {
    showTempl();
    M5.Lcd.println("Send Message.");
    Serial2.println("AT$SF=CAFE");
  } else if (M5.BtnB.wasReleased()) {
    showTempl();
    M5.Lcd.println("Send Message with Ack.");
    Serial2.println("AT$SF=C0FFEE,1");    
  } else if (M5.BtnC.wasReleased()) {
    showTempl();
    M5.Lcd.println("Device ID&PAC: ");
    Serial2.println("AT$I=10");
    Serial2.println("AT$I=11");
  }
}

void showTempl()
{
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.println("M5Stack COM.Sigfox");
  
  M5.Lcd.setCursor(30, 220);
  M5.Lcd.print("UP");
  M5.Lcd.setCursor(129, 220);
  M5.Lcd.print("DOWN");
  M5.Lcd.setCursor(238, 220);
  M5.Lcd.print("ID/PAC");  
  
  M5.Lcd.setTextColor(BLUE);
  M5.Lcd.setCursor(0, 35);
}

void displayResults(String ack)
{
  M5.Lcd.println(ack);
  int i = ack.indexOf("RX=");
  if (i >= 0) {
    ack.replace(" ", "");
    String bs = ack.substring(i + 6, i + 11);
    String rs = ack.substring(i + 15);
    signed int rssi = (int16_t)(strtol(rs.c_str(), NULL, 16));
    M5.Lcd.print("BSID: ");
    M5.Lcd.println(bs);
    M5.Lcd.print("RSSI: ");
    M5.Lcd.println(rssi);
  }
}
```

##M5Core2サンプルスケッチ
M5Core2では、①物理ボタンの廃止、②シリアルポートの違いがあり、M5Stack用のスケッチそのままでは動きません。物理ボタンの代わりにタッチポイントによる動作、シリアルポート番号の変更を行っています。

```m5core2-sigfox.c
#include <M5Core2.h>

void setup() {
  M5.begin(true, false, true);
  Serial2.begin(9600, SERIAL_8N1, 13, 14);
  showTempl();
}

void loop() {
  if (Serial2.available()) {
    displayResults(Serial2.readString());
  }

  TouchPoint_t pos = M5.Touch.getPressPoint();
  char btn = btnPressed(pos);
  if (btn != 0) {
    showTempl();
    if (btn == 'A') {
      M5.Lcd.println("Send Message.");
      Serial2.println("AT$SF=CAFE");
    } else if (btn == 'B') {
      M5.Lcd.println("Send Message with Ack.");
      Serial2.println("AT$SF=C0FFEE,1");        
    } else if (btn == 'C') {
      M5.Lcd.println("Device ID&PAC: ");
      Serial2.println("AT$I=10");
      Serial2.println("AT$I=11");    
    }
    delay(1000);
  }
}

char btnPressed(TouchPoint_t pos) 
{
  char btn = 0;
  if (pos.y > 240) {
    if (pos.x < 109) btn = 'A';
    else if(pos.x >= 109 && pos.x <= 218) btn = 'B';
    else if(pos.x > 218) btn = 'C';
  }
  return btn;
}

void showTempl()
{
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.println("M5Stack Core2 COM.Sigfox");
  
  M5.Lcd.setCursor(30, 220);
  M5.Lcd.print("UP");
  M5.Lcd.setCursor(129, 220);
  M5.Lcd.print("DOWN");
  M5.Lcd.setCursor(238, 220);
  M5.Lcd.print("ID/PAC");  
  
  M5.Lcd.setTextColor(BLUE);
  M5.Lcd.setCursor(0, 35);
}

void displayResults(String ack)
{
  M5.Lcd.println(ack);
  int i = ack.indexOf("RX=");
  if (i >= 0) {
    ack.replace(" ", "");
    String bs = ack.substring(i + 6, i + 11);
    String rs = ack.substring(i + 15);
    signed int rssi = (int16_t)(strtol(rs.c_str(), NULL, 16));
    M5.Lcd.print("BSID: ");
    M5.Lcd.println(bs);
    M5.Lcd.print("RSSI: ");
    M5.Lcd.println(rssi);
  }
}
```

#補足: DOWNLINK設定
上記サンプルスケッチで、DOWNLINK（下り要求メッセージ）に対応するためには、SigfoxクラウドのDeviceType設定で、**Downlink data**の設定を行う必要があります。
上記サンプルは、Downlink modeを**DIRECT**、つまり、Sigfoxクラウドから直接下りメッセージ応答を返すようにしています。その際には、下りメッセージをDownlink data in hex項目で設定する必要があり、数の通り、`{tapId}0000{rssi}`とし、受信基地局IDとRSSIをダウンリンクで返す設定としています。
この設定画面へは、Sigfoxクラウドログイン後、上部の[DEVICE TYPE]タブを選択 > 該当のDevice Type Nameを選択 > 右上の[Edit]ボタンクリックとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/14b2af81-7729-08be-38a7-858a92522e66.png)

#番外編（アンテナを変えてみる）
COM.SigfoxのPCBには、u.FL (IPEX)コネクタがあり、通常は、そこから外部のSMAコネクタにケーブルアウトされています。
ですので、下の写真のようにu.FL (IPEX)タイプのアンテナも利用可能です。
![IMG_5276.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/2afa9468-a3ef-56cf-861b-17a1d7e85fe9.jpeg)
SFM11R3の技適取得済みアンテナリストは、[Seongji(Wisol)社のサポートサイト](http://support.seongji.co.kr/certification_sigfox_cerified-2-2/)でダウンロード可能です。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/d6ad10bc-75ba-8124-14d4-f144657c6473.png)](https://twitter.com/ghibi)