プロトコル

[iot][arduino][breeding]Arduinoで水槽の温度管理

安価なマイコン基盤であるArduinoを使って、水槽の温度をクラウドサービスを利用してモニタリングし、さらに一定の温度から外れるとアラートをメールしてくれるシステムを作りました。

購入したのは、以下の機材
Arduino Uno (のクローンの安物、1,000円程度)
Ethernet Shield for Arduino Uno (のクローンの安物、1,500円程度)
温度センサー DS18B20
ブレッドボード
金属皮膜抵抗器
ジャンプワイヤキット

必要な部材

ブレッドボードにセンサーの三芯線とArduinoの5V電源、GRD、デジタル入力からのジャンパ線を刺し、サンプルのスケッチを参考に手直しを加えたら完成。

今のところ、室温と4つの水槽の水温(=5つの温度プローブ)を5分ごとに取得し、これをAT&Tのクラウドリソース、m2xにアップロードし、モニタリングしています(実際のサイト)。設定温度から上下1℃以上変動すると、Herokuに置いたアラートが作動してラボのメンバーにメールが通知されるようになっています。今のところ設置してから二か月以上、安定して動作しています。

スケッチは下記のもの。いろいろ試行錯誤した結果、MSTimer2を利用するのが最も安定しているようです。

#include <MsTimer2.h>
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define TEMPERATURE_PRECISION 12
#define ARDUINO_PLATFORM
#include "M2XStreamClient.h"

// MAC address for your Ethernet shield
byte mac[] = { NICのMACアドレス };
// Set the static IP address to use if the DHCP fails to assign
byte ip[] = { NICのIPアドレス };
byte dns_adress[] = { DNSアドレス };
byte gateway[] = { ゲートウェイアドレス };
byte subnet[] = { サブネットマスク };


char deviceId[] = "m2xのデバイスID"; // Device you want to push to
char m2xKey[] = "m2xのキー"; // Your M2X access key
char streamName1[] = { "temp01"};
char streamName2[] = { "temp02"};
char streamName3[] = { "temp03"};
char streamName4[] = { "temp04"};
char streamName5[] = { "temp05"};

const int temperaturePin = 0;
EthernetClient client;
M2XStreamClient m2xClient(&client, m2xKey);
#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress temp0 = { DS18B20のデバイスアドレス 
例 0x28, 0xFF, 0xB0, 0xA5, 0x8C, 0x16, 0x03, 0x54 };
DeviceAddress temp1 = { };
DeviceAddress temp2 = { };
DeviceAddress temp3 = { };
DeviceAddress temp4 = { };



void setup() {
  sensors.begin();
  sensors.setResolution(TEMPERATURE_PRECISION);
  Serial.begin(9600);
  Ethernet.begin(mac, ip, dns_adress, gateway, subnet);
   //300000ms毎に記録
  MsTimer2::set(300000, timerRecord);
  MsTimer2::start();

  //while (!Serial) {
  //  ; // wait for serial port to connect. Needed for Leonardo only
  //}
}

void timerRecord() {

//  Serial.println("Connected to Ethernet");
//  printEthernetStatus();

  float temp01, temp02, temp03, temp04, temp05;
  sensors.requestTemperatures();

  temp01 = sensors.getTempC(temp0);
  temp02 = sensors.getTempC(temp1);
  temp03 = sensors.getTempC(temp2);
  temp04 = sensors.getTempC(temp3);
  temp05 = sensors.getTempC(temp4);

//  Serial.println(sensors.getTempC(temp0));
//  Serial.println(sensors.getTempC(temp1));
//  Serial.println(sensors.getTempC(temp2));
//  Serial.println(sensors.getTempC(temp3));
//  Serial.println(sensors.getTempC(temp4));

  int response1 = m2xClient.updateStreamValue(deviceId, streamName1, temp01);
  int response2 = m2xClient.updateStreamValue(deviceId, streamName2, temp02);
  int response3 = m2xClient.updateStreamValue(deviceId, streamName3, temp03);
  int response4 = m2xClient.updateStreamValue(deviceId, streamName4, temp04);
  int response5 = m2xClient.updateStreamValue(deviceId, streamName5, temp05);
// Serial.print("M2x client response code: ");
// Serial.println(response);

  delay(10000);
}


void printEthernetStatus() {
  // print local IP
  Serial.print("Local IP: ");
  Serial.println(Ethernet.localIP());

  // print subnet mask
  Serial.print("Subnet Mask: ");
  Serial.println(Ethernet.subnetMask());

  // print gateway IP
  Serial.print("Gateway IP: ");
  Serial.println(Ethernet.gatewayIP());

  // print dns IP
  Serial.print("DNS IP: ");
  Serial.println(Ethernet.dnsServerIP());
}

void loop(){}

2019/10/9 追記:
複数(当方の場合、5つ以上)のDS20B18のコードを延長して接続するとエラー値が頻発してしまうが、これはどうも延長したり複数繋ぐとDS20B18自体が抵抗となってしまい、通常の4K7の抵抗を入れると電圧が高くなりすぎる、あるいは電流が微弱になって読み取れなくなるらしい。その場合、抵抗を低いものに変えるとうまく行く(今回は2K2の抵抗に交換)。この現象はarduinoの個体差や配置する環境によっても異なるらしく、原因がわからずに1年ぐらいトラブルシュートに時間がかかってしまった。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です