PC館

Arduinoで遊んでみる

はじめに

Arduino学習キット

たまにはリアルなモノづくりをやってみようということで、サンタに持ってきてもらった「Arduino学習キット」。いったいどんなものが出来上がるのか?

製作No.01:水槽水温&リビング温湿度監視センサ【】

「まずは簡単なIoTデバイスを」ってことで,ペット達(ハムスター,熱帯魚)が快適な環境で過ごしているかをモニタし,環境変化があればスマホにメールで知らせてくれるセンサ(と監視システム)を作ってみよう。

要求仕様

  1. リビングの温湿度を測定する。
  2. 水槽の水温を測定する。
  3. それぞれの数値を液晶モニタに表示する。
  4. 数値に一定の変化があれば自宅サーバーにデータをアップロードする。
  5. データを受け取った自宅サーバーは,各数値をデータベースに保存する。また,各数値が基準内であるかどうかを判定し,基準外であればスマホにメールを送信する。
  6. 自宅サーバーで,各数値の変化を確認できるようなスクリプトを作成する。

ハード作成

要求仕様を満たすために,以下の構成でセンサ回路を作成する。

部品名備考
ESP-WROOM-02Arduinoとしてプログラムを書き込めるWiFiモジュール。これで制御しつつ,データを無線LANで自宅サーバーに送信する。
AE-HDC1000I2C接続の温湿度センサ
サーミスタ水温計測用。ウチにあった水槽用温度センサを転用。
AE-AQM0802I2C接続の液晶モニタ
電源ACアダプタ(5V)で電源供給し,回路にて3.3Vに降圧して駆動する。

回路図

製作No.01:水槽水温&リビング温湿度監視センサの回路図

ESP-WROOM-02ソースコード

#include <Wire.h>
#include "Adafruit_HDC1000.h"
#include <ESP8266WiFi.h>

//監視データ初期値
  float DefValue1 = 0;    //気温
  float DefValue2 = 0;    //湿度
  float DefValue3 = 0;    //水温
  float Delta1    = 0.4;  //データアップする気温差
  float Delta2    = 2;    //同、湿度差
  float Delta3    = 0.4;  //同、水温差

//WiFiパラメータ
  char WiFiSSID[] = "自宅WiFiのSSID";
  char WiFipass[] = "自宅WiFiのパスワード";
  IPAddress WiFiIP(xxx , xxx , xxx , xxx);    //IPアドレス
  IPAddress WiFiGW(xxx , xxx , xxx , xxx);    //ゲートウェイIPアドレス
  IPAddress WiFiSM(xxx , xxx , xxx , xxx);    //サブネットマスク

//サーバーパラメータ
  const char* Host     = "xxx.xxx.xxx.xxx";   //自宅サーバーのIPアドレス
  const int   httpPort = 80;
  String url      = "/Solar/LivingdataUpload.php?";
  String Data1    = "kion=";
  String Data2    = "&hum=";
  String Data3    = "&suion=";

//サーミスタパラメータ
  float aData = 0;
  float V1    = 3.22;
  float V2    = 0;
  float R1    = 50;
  float R2    = 0;

//HDC1000
  Adafruit_HDC1000 hdc = Adafruit_HDC1000();

//LCD_AQM0802
  int  I2Cadr       = 0x3E;
  byte Contrast     = 32;
  
  void LCD_cmd(byte x) {
    Wire.beginTransmission(I2Cadr);
    Wire.write(0x00);
    Wire.write(x);
    Wire.endTransmission();
  }
  
  void LCD_data(byte x) {
    Wire.beginTransmission(I2Cadr);
    Wire.write(0x40);
    Wire.write(x);
    Wire.endTransmission();
  }
  
  void LCD_puts(const char *s) {
    while(*s) LCD_data(*s++);
  }
  
  // LCD initialize
  void LCD_init() {
    delay(40);
    Wire.begin();
    LCD_cmd(0x38); // function set
    LCD_cmd(0x39); // function set
    LCD_cmd(0x14); // intervalosc
    LCD_cmd(0x70 + (Contrast & 0x0F)); // contrast low
    LCD_cmd(0x5c + (Contrast >> 4));   // contrast high / icon / power
    LCD_cmd(0x6c); // follower control
    delay(300);
    LCD_cmd(0x38); // function set
    LCD_cmd(0x0c); // display on
    LCD_cmd(0x01); // clear display
    delay(2);
  }
  
  void LCD_move(byte pos) {
    LCD_cmd(0x80 | pos);
  }

void setup() {
  Serial.begin(115200);
  if (!hdc.begin()) {
    while (1);        //wait for starting
  }
  LCD_init();
  
  //WiFi接続
  WiFi.mode(WIFI_STA);
  WiFi.begin(WiFiSSID, WiFipass);
  WiFi.config(WiFiIP , WiFiGW , WiFiSM);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
}

void loop() {
  //監視状態
  int Status = 0;   //0:通常  1:変化あり
  
  //気温
  LCD_move(0x0);
  char Line1[9];
  float Value1 = hdc.readTemperature();
  String TEMP1 = String("RT " + String(Value1));
  TEMP1.toCharArray(Line1 , 8);
  LCD_puts(Line1);
  if (abs(Value1 - DefValue1) > Delta1) {
    Status = 1;
    DefValue1 = Value1;
  }
  
  //湿度
  LCD_move(0x40);
  char Line2[9];
  float Value2 = hdc.readHumidity();
  String TEMP2 = String("RH " + String(Value2));
  TEMP2.toCharArray(Line2 , 8);
  LCD_puts(Line2);
  if (abs(Value2 - DefValue2) > Delta2) {
    Status = 1;
    DefValue2 = Value2;
  }
  
  delay(3000);

  //水温
  LCD_move(0x0);
  char Line3[9];
  aData = analogRead(A0);
  V2    = aData/1024;
  R2    = V2/(V1 - V2) * R1;
  float Value3 = 48.954 - 2.1393 * R2;
  String TEMP3 = String("WT " + String(Value3));
  TEMP3.toCharArray(Line3 , 8);
  LCD_puts(Line3);
  if (abs(Value3 - DefValue3) > Delta3) {
    Status = 1;
    DefValue3 = Value3;
  }

  //空白
  LCD_move(0x40);
  char Line4[9] ="        ";
  LCD_puts(Line4);
  
  //状態変化があればデータアップロード
  if (Status == 1) {
    String Param = url + Data1 + String(Value1) + Data2 + String(Value2) + Data3 + String(Value3);
    Serial.println(Param);
    WiFiClient client;
    if (client.connect(Host, httpPort)) {
      client.print(String("GET ") + Param + " HTTP/1.1\r\n" + "Host: " + Host + "\r\n" + "Connection: close\r\n\r\n");
      unsigned long timeout = millis();
      while (client.available() == 0) {
        if (millis() - timeout > 5000) {
          client.stop();
          return;
        }
      }
    }
    Status = 0;
  }
  
  delay(3000);
}