3.3Vで稼働するCO2センサー "S-300L-3V" を Wio LTE で動かして SORACOM Harvest Data に蓄積する


サンタさん来訪に備え、室内のCO2濃度を快適にしておきたいと思っている 松下(ニックネーム: Max) です。

多すぎる二酸化炭素は脳の敵 と言われており、オフィスのIoTネタでもよく話題になるCO2の計測。センサーは探すとあるのですが、いかんせん5V駆動のものばかりで、 Wio LTE のような 3.3V マイコンで動かすには...

  • 3.3V -> 5V DCDC 昇圧回路を挟む
  • 3.3V で駆動するセンサーを探す

という選択肢となります。ちなみに、動作電圧3.3Vか5Vというのはプロトコルのようなものです。3.3V/5Vの両方に対応しているセンサーもありますし、電圧を「変換」することで動きます。

作るのは好きですが、目的を見失うので3.3Vで動くCO2センサーを探してみると...あるものですね!

S-300L-3V CO₂センサモジュール

1万円となかなかいいお値段ですが、昇圧回路を作って5Vのものを動かすくらいなら、既製品を使えばお金はかかるかもしれませんが、時間※が節約できるので、今回はこれを使ってみようと思います。

※時間 = 昇圧回路を作るだけじゃなくて、その回路が正常に動いているかチェックしたり、、、面倒なのはお金で解決したい派です。

S-300L にピンヘッダをはんだ付け

本当は Grove コネクタがついてくれていれば最強だったのですが、残念。
仕方ないのでピンヘッダをハンダで取り付けます。まあ、このくらいは作業するか。

下手なのはわかってます。突っ込まないで。

ブレッドボードで検証

S-300Lのピンヘッダは直接ブレッドボードに挿せます(2.54mmピッチ)。これは便利。
あとは Groveのジャンパーピン変換ケーブルを使って Wio LTE の UART と接続します。
ケーブルと S-300L の接続は以下の通り。

Grove S-300L
GND
VCC
Rx
Tx

こんな感じになります。

コード

この時点ではまだセンサーとマイコン(Wio LTE)間の接続を確認してみます。
S-300L から UART で出力されるデータフォーマットは公開されていますので、それを見ながら以下のようにします。

  • S-300L <=> Wio LTE のスピードは 38400 bps
  • 3秒毎に計測されるので UART バッファ内を待つ
  • 区切り文字に LF (0x0A = \n)
measurement_co2.ino
#include <WioLTEforArduino.h>
WioLTE Wio;

uint16_t CO2ppm() {
  while (!SerialUART.available()); /* wait max 3 seconds by spec (TODO: Timeout) */
  String buf = SerialUART.readStringUntil('\n'); /* separete char by spec */
  int pos = buf.lastIndexOf(" ppm"); /* Avoiding garbage in buffer */
  String v = buf.substring(pos - 6, pos);
  return v.toInt();
}

void setup() {
  delay(200);
  Wio.Init();
  SerialUSB.begin(115200);
  Wio.PowerSupplyGrove(true);
  delay(500);
  SerialUART.begin(38400);
  SerialUSB.println("Ready");
}

void loop() {
  uint16_t ppm = CO2ppm();
  SerialUSB.println(ppm);
  delay(5000);
}

ppm が表示され始めたら成功です。
誰もいない部屋なら800 ~ 1000 くらいの間だと思います。

※思いっきりテキストで 960 ppm とかコンソールに出力されてくるのは(´Д`)ってな感じ。

SORACOM Harvest Data へ

Wio LTE は LTE Cat.1 モジュールと SIM 、そしてアンテナがあるので Wi-Fi 等が無くても単体でクラウドへデータを送ることができます。
今回は SORACOM の IoT データ収集・蓄積サービス「SORACOM Harvest Data」で以下のように計測したデータを蓄積します。

コード

前回のコードに以下の内容をつけ足しました。

  • setup()
    • セルラーモデム ON
    • セルラーネットワーク(SORACOM) への接続
  • loop()
    • SORACOM Harvest Data への送信
measurement_co2_with_soracom_harvest_data.ino
#include <WioLTEforArduino.h>
WioLTE Wio;

uint16_t CO2ppm() {
  while (!SerialUART.available()); /* wait max 3 seconds by spec (TODO: Timeout) */
  String buf = SerialUART.readStringUntil('\n'); /* separete char by spec */
  int pos = buf.lastIndexOf(" ppm"); /* Avoiding garbage in buffer */
  String v = buf.substring(pos - 6, pos);
  return v.toInt();
}

void setup() {
  delay(200);
  Wio.Init();
  SerialUSB.begin(115200);
  Wio.PowerSupplyGrove(true);
  delay(500);
  SerialUART.begin(38400);
  Wio.PowerSupplyLTE(true);
  delay(500);
  if (!Wio.TurnOnOrReset()) {
    SerialUSB.println("failed TurnOnOrReset()");
    return;
  }
  if (!Wio.Activate("soracom.io", "sora", "sora")) {
    SerialUSB.println("failed Activate()");
    return;
  }
  SerialUSB.println("Ready");
}

void loop() {
  uint16_t ppm = CO2ppm();
  SerialUSB.println(ppm);
  char payload[1024];
  sprintf(payload, "{\"co2_ppm\":%lu}", ppm);
  int status_code;
  if (!Wio.HttpPost("http://uni.soracom.io", payload, &status_code)) {
    SerialUSB.println("failed HttpPost()");
    goto err;
  }
  SerialUSB.print("Status code:");
  SerialUSB.println(status_code);
err:
  SerialUSB.println("Waiting for next loop");
  delay(5000);
}

前回とのdiffはこんな感じで21行加えています。


@@ -16,11 +16,33 @@
   Wio.PowerSupplyGrove(true);
   delay(500);
   SerialUART.begin(38400);
+  Wio.PowerSupplyLTE(true);
+  delay(500);
+  if (!Wio.TurnOnOrReset()) {
+    SerialUSB.println("failed TurnOnOrReset()");
+    return;
+  }
+  if (!Wio.Activate("soracom.io", "sora", "sora")) {
+    SerialUSB.println("failed Activate()");
+    return;
+  }
   SerialUSB.println("Ready");
 }

 void loop() {
   uint16_t ppm = CO2ppm();
   SerialUSB.println(ppm);
+  char payload[1024];
+  sprintf(payload, "{\"co2_ppm\":%lu}", ppm);
+  int status_code;
+  if (!Wio.HttpPost("http://uni.soracom.io", payload, &status_code)) {
+    SerialUSB.println("failed HttpPost()");
+    goto err;
+  }
+  SerialUSB.print("Status code:");
+  SerialUSB.println(status_code);
+err:
+  SerialUSB.println("Waiting for next loop");
   delay(5000);
 }

SORACOM 側の設定

SORACOM Harvest Data を有効にするには SORACOM Harvest Data でデバイスのデータをクラウドで収集・取得・可視化する を参考に進めてください。スクリーンショット付きです。

今回使った機材の費用

ざくっと計算すると、このくらいでした。

  • 初期: 約 21,700円
  • ランニング: 16円/日/SIM

※金額は税抜きです。

初期

役割 機材 金額
マイコン&モデムボード Wio LTE JP Version 9800円
CO2 センサー S-300L-3V 9930円
ブレッドボード どこのやつだったかな? 300~500円くらい
ケーブル Grove ジャンパーピン変換ケーブル (5本入り) 500円くらい
SIM SORACOM 特定地域向け IoT SIM (plan-D) 895円

ランニング (1日分)

役割 機材 金額
データ通信 / 基本料 SORACOM 特定地域向け IoT SIM (plan-D) 10円/日/SIM
データ通信 / 通信料※ SORACOM 特定地域向け IoT SIM (plan-D) 1円/日/SIM
データ収集・蓄積 SORACOM Harvest Data 5円/日/SIM

※ 1回500B、10分に1回で約720KBの通信を想定

まとめ

できる限り既製品を使う事で、思い立ってから1日で完成できたのは大きかった。
(揃うまでに3日くらいかかったけど)

動くことは確認できたので、あとはケースや電源を考えることにします。
とはいえ、ここも作るのが面倒なので 既製品のケースやネジ で何とかしようと思います。

Grove 5V 出力昇圧 DCDC コンバーターがあると嬉しいのだけど!

EoT