防水温度センサとTimer Cameraを畑に設置する

先日、「Timer Camera」と「ENV IIユニット」をつなぎ、超低電力で温度データを採取できることを確認しました(記事は こちら)。
1時間に1回の頻度で温度データをWebサーバに送信する場合、外付けバッテリーなしで約2.5ヶ月も稼働できる見込みです。

また、防水タイプの温度センサ(DS18B20)を入手し、これを「M5StickC」のGROVEポートにつないで動作することを確認しました(記事は こちら)。
この温度センサは「1-wire」というバス規格のもので、ひとつの信号線に複数の温度センサをつなぐことができます。

今回は、これらを組み合わせ、「防水温度センサ」+「Timer Camera」を実際に畑に設置してみようと思います。

温度センサは4つ使います。
畑の端に「ミニ田んぼ」がふたつあるので、ふたつのセンサで、それらの水温を測定します。
また、ひとつのセンサで、その付近の気温も測定することにします。
残りひとつについては、特に目的はありませんが、おまけでつけておきます。

4つのセンサの温度データを、1時間に1回の頻度でWebサーバに送信することにします。
既に、畑にモバイルWi-Fiルータを設置していますので、そのルータにデータ送信します。
前述のように、前回の調査結果では、約2.5ヶ月連続稼働できる見込みとなりましたが、今回設置を予定している場所はモバイルWi-Fiルータからかなり離れているため、Wi-Fi接続に時間がかかる可能性があります。接続に時間がかかるとそれだけ電力消費してしまうため、1ヶ月連続稼働することを目標とします。

Wi-Fiが不安定で接続できないときにずっとリトライを繰り返していると、あっというまに電池がなくなってしまうので、10秒接続できなかったらその回のデータ送信は諦め、そのまま1時間のスタンバイ状態に移行することにします。

4つの温度データは「ambient」に送信します。

「Timer Camera」に書き込むスケッチは以下のとおりです。

#include "battery.h"
#include "bmm8563.h"
#include <WiFi.h>
#include "Ambient.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 13
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress temp2 = { 0x28, 0xAF, 0x02, 0xD8, 0x5F, 0x20, 0x01, 0x43 };
DeviceAddress temp3 = { 0x28, 0xA1, 0xE7, 0x06, 0x5F, 0x20, 0x01, 0x4C };
DeviceAddress temp4 = { 0x28, 0x4F, 0xD8, 0x24, 0x5F, 0x20, 0x01, 0xEA };
DeviceAddress temp5 = { 0x28, 0x2C, 0x24, 0x11, 0x5F, 0x20, 0x01, 0x3E };

WiFiClient client;
Ambient ambient;

const char*  ssid      = "XXXXXXXX";
const char*  password  = "XXXXXXXX";
unsigned int channelId = XXXXX;
const char*  writeKey  = "XXXXXXXX";

unsigned long interval = 3600; // unit:sec

void sleepTimerCam() {
  bat_disable_output(); // disable bat output, will wake up after interval sec, Sleep current is 1~2μA
  // if usb not connect, will not in here;
  esp_sleep_enable_timer_wakeup(interval*1000*1000);
  esp_deep_sleep_start();
}

boolean connect_wifi() {
  int cnt=0;
  Serial.printf("Connecting to %s\n", ssid);
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    cnt++;
    delay(500);
    Serial.print(".");
    if(cnt>=20) return false;
  }
  Serial.printf("\nWiFi connected\n");
  return true;
}

void disconnect_wifi() {
  WiFi.disconnect(true);
  Serial.printf("WiFi disconnected\n");
}

void setup() {
  Serial.begin(115200);
  Serial.println("[Temperature Sensor (DS18B20)]");
  bat_init(); // hold bat output
  bmm8563_init();
  bmm8563_setTimerIRQ(interval); // interval sec later will wake up
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  float val2 = sensors.getTempC(temp2);
  float val3 = sensors.getTempC(temp3);
  float val4 = sensors.getTempC(temp4);
  float val5 = sensors.getTempC(temp5);

  if(!connect_wifi()) sleepTimerCam();

  ambient.begin(channelId, writeKey, &client);
  ambient.set(1, val2);
  ambient.set(2, val3);
  ambient.set(3, val4);
  ambient.set(4, val5);
  ambient.send();
  Serial.printf("[temp2] %.2f, [temp3] %.2f, [temp4] %.2f, [temp5] %.2f\r\n", val2, val3, val4, val5);

  disconnect_wifi();
  
  sleepTimerCam();
}

「DeviceAddress」で定義しているのは、今回使用する4つの温度センサのアドレスです。

温度センサを「Timer Camera」のGROVEポートにつなぐため、「GROVEプロトシールド」を使います。

プロトシールドにピンソケットを取り付け、そこに温度センサの各端子を差し込むようにします。

温度センサにはピンコネクタをつけます。

このように、ピンソケットに各温度センサの端子を差し込みます。

まずは、これを「M5StickC」につなぎ、前回と同じスケッチをつかって、きちんと接続できていることを確認します。

次に、先ほどのスケッチを書き込んだ「Timer Camera」につなぎ、問題なく温度データを送信できることを確認します。

屋外に設置するため、これらを防水ケースに収納します。
使用したのは、タカチの「BCAP091207T」です。今回は「Timer Camera」を純粋にIoTデバイスとして使用しますが、将来的にはカメラとして使うことも考えられるので、カバーが透明なケースを採用しました。


準備ができたので、実際に畑に持っていって設置します。

畑にイレクターパイプを打ち込み、そこに「Timer Camera」が入ったケースを取り付けます。

園芸用支柱を田んぼに差し込み、水温を測るための温度センサを結束バンドで取り付けます。

Wi-Fiルータからは、こんなに離れています。

これで、長期間にわたるデータ採取ができるかどうか、様子を見たいと思います。


なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。