見出し画像

自動システムを作ってみる(コード編)


5秒おきにリレーをオンオフするコード

 #include  <WiFi.h> #include  <Wire.h> #include  <Adafruit_SHT31.h> #include  <Adafruit_I2CDevice.h>  // 確認のため再度インクルード

const char* ssid = "YOUR_SSID"; // Wi-Fi SSID
const char* password = "YOUR_PASSWORD"; // Wi-Fi パスワード

Adafruit_SHT31 sht31 = Adafruit_SHT31();

const int relayPin = 25; // リレー制御用のピン番号(GPIO 25を使用)

unsigned long previousMillis = 0;
const long interval = 5000;  // 5秒間隔
bool relayState = LOW;

void setup() {
  Serial.begin(115200);

  pinMode(relayPin, OUTPUT); // リレーピンを出力モードに設定
  digitalWrite(relayPin, relayState); // 初期状態でリレーをオフに設定

  // Initialize sensor
  if (!sht31.begin(0x44)) {
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }

  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    relayState = !relayState;  // リレーの状態を切り替える
    digitalWrite(relayPin, relayState);
    Serial.println(relayState ? "Relay ON" : "Relay OFF");
    
    float temp = sht31.readTemperature();
    float hum = sht31.readHumidity();

    Serial.print("Temperature: ");
    Serial.print(temp);
    Serial.println(" *C");
    
    Serial.print("Humidity: ");
    Serial.print(hum);
    Serial.println(" %");
  }
}


完成版コード

Wi-Fiに接続し、湿度・温度センサー(Adafruit SHT31)からデータを取得し、リレーを制御するESP32ベースの自動散水システム

 #include  <WiFi.h> #include  <Wire.h> #include  <Adafruit_SHT31.h> #include  <Adafruit_I2CDevice.h>  // 確認のため再度インクルード


const char* ssid = "YOUR_SSID"; // Wi-Fi SSID
const char* password = "YOUR_PASSWORD"; // Wi-Fi パスワード

Adafruit_SHT31 sht31 = Adafruit_SHT31();

WiFiServer server(80);

const int relayPin = 25; // リレー制御用のピン番号(GPIO 25を使用)
bool relayState = LOW;
bool autoWatering = false;
unsigned long relayOnTime = 0;
unsigned long autoOffTime = 0;
const unsigned long maxRelayOnDuration = 300000; // 5分 (300,000ミリ秒)

void setup() {
  Serial.begin(115200);

  pinMode(relayPin, OUTPUT); // リレーピンを出力モードに設定
  digitalWrite(relayPin, relayState); // 初期状態でリレーをオフに設定

  // Initialize sensor
  if (!sht31.begin(0x44)) {
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }

  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  
  // 自動散水の停止処理
  if (autoWatering && currentMillis >= autoOffTime) {
    relayState = LOW;
    digitalWrite(relayPin, relayState);
    autoWatering = false;
    Serial.println("スイッチ オフ");
  }

  // 消し忘れ防止のための処理
  if (relayState == HIGH && currentMillis - relayOnTime >= maxRelayOnDuration) {
    relayState = LOW;
    digitalWrite(relayPin, relayState);
    autoWatering = false; // 手動でオンにしても自動でオンにしても同じ扱い
    Serial.println("タイマーによりスイッチオフ");
  }

  WiFiClient client = server.available();
  if (client) {
    Serial.println("New Client.");
    String currentLine = "";
    String request = "";  // HTTPリクエストを保存する変数
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        request += c;
        if (c == '\n') {
          if (currentLine.length() == 0) {
            // リレー制御リクエストのチェック
            if (request.indexOf("GET /on") >= 0) {
              relayState = HIGH;
              digitalWrite(relayPin, relayState); // リレーをオン
              relayOnTime = currentMillis; // オンになった時刻を記録
              autoWatering = false; // 手動でオンにした場合、自動散水モードをオフにする
              Serial.println("スイッチ ON");
            }
            if (request.indexOf("GET /off") >= 0) {
              relayState = LOW;
              digitalWrite(relayPin, relayState); // リレーをオフ
              autoWatering = false; // 手動でオフにした場合、自動散水モードをオフにする
              Serial.println("スイッチ OFF");
            }

            float temp = sht31.readTemperature();
            float hum = sht31.readHumidity();

            // 自動散水機能のチェック
            if (temp > 37.0 && !autoWatering) {
              relayState = HIGH;
              digitalWrite(relayPin, relayState);
              relayOnTime = currentMillis; // オンになった時刻を記録
              autoWatering = true;
              autoOffTime = currentMillis + 180000; // 3分後にリレーをオフにする
              Serial.println("自動散水 ON");
            }

            // Send HTML header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html; charset=utf-8");
            client.println();
            
            // HTML content
            client.println("<html>");
            client.println("<head><meta http-equiv='refresh' content='5'><meta charset='UTF-8'>");
            client.println("<style>");
            client.println("body { font-family: Arial, sans-serif; margin: 20px; }");
            client.println("h1 { color: #333 ; }");
            client.println(".button { padding: 10px 20px; margin: 10px; font-size: 16px; }");
            client.println(".on { background-color: #4CAF50 ; color: white; }");
            client.println(".off { background-color: #f44336 ; color: white; }");
            client.println("</style></head>");
            client.println("<body><h1>自動散水モニター</h1>");
            client.print("<p>気温: ");
            client.print(temp);
            client.println(" *C</p>");
            client.print("<p>湿度: ");
            client.print(hum);
            client.println(" %</p>");
            client.println("<p>Relay State: ");
            client.println(relayState ? "ON" : "OFF");
            client.println("</p>");
            if (autoWatering) {
              client.println("<p>自動散水オン</p>");
            }
            client.println("<button class=\"button on\" onclick=\"relayControl('on')\">Relay ON</button>");
            client.println("<button class=\"button off\" onclick=\"relayControl('off')\">Relay OFF</button>");
            client.println("<script>");
            client.println("function relayControl(state) {");
            client.println("  var xhttp = new XMLHttpRequest();");
            client.println("  xhttp.open('GET', '/' + state, true);");
            client.println("  xhttp.send();");
            client.println("}");
            client.println("</script>");
            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
    Serial.println("Client Disconnected.");
  }
}


コードの主要部分の説明


ライブラリのインクルード

Wi-Fi接続、I2C通信、センサーデータの読み取りに使用するライブラリのインクルード

 #include  <WiFi.h> #include  <Wire.h> #include  <Adafruit_SHT31.h> #include  <Adafruit_I2CDevice.h>


Wi-Fi接続情報

Wi-FiのSSIDとパスワードを設定

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";


グローバル変数の設定

センサー、サーバー、リレー用のピン番号、リレーの状態、自動散水の状態などの変数を設定

Adafruit_SHT31 sht31 = Adafruit_SHT31();
WiFiServer server(80);
const int relayPin = 25;
bool relayState = LOW;
bool autoWatering = false;
unsigned long relayOnTime = 0;
unsigned long autoOffTime = 0;
const unsigned long maxRelayOnDuration = 300000;


セットアップ関数

シリアル通信の開始、リレーピンの設定、センサーの初期化、Wi-Fiへの接続を行う

void setup() {
  Serial.begin(115200);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, relayState);

  if (!sht31.begin(0x44)) {
    Serial.println("Couldn't find SHT31");
    while (1) delay(1);
  }

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}


メインループ

自動散水機能のタイマー処理、手動リレー制御、Wi-Fiクライアントの接続管理、センサーデータの読み取り、そしてHTTPレスポンスの生成と送信を行う

void loop() {
  unsigned long currentMillis = millis();

  if (autoWatering && currentMillis >= autoOffTime) {
    relayState = LOW;
    digitalWrite(relayPin, relayState);
    autoWatering = false;
    Serial.println("スイッチ オフ");
  }

  if (relayState == HIGH && currentMillis - relayOnTime >= maxRelayOnDuration) {
    relayState = LOW;
    digitalWrite(relayPin, relayState);
    autoWatering = false;
    Serial.println("タイマーによりスイッチオフ");
  }

  WiFiClient client = server.available();
  if (client) {
    Serial.println("New Client.");
    String currentLine = "";
    String request = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        request += c;
        if (c == '\n') {
          if (currentLine.length() == 0) {
            if (request.indexOf("GET /on") >= 0) {
              relayState = HIGH;
              digitalWrite(relayPin, relayState);
              relayOnTime = currentMillis;
              autoWatering = false;
              Serial.println("スイッチ ON");
            }
            if (request.indexOf("GET /off") >= 0) {
              relayState = LOW;
              digitalWrite(relayPin, relayState);
              autoWatering = false;
              Serial.println("スイッチ OFF");
            }

            float temp = sht31.readTemperature();
            float hum = sht31.readHumidity();

            if (temp > 37.0 && !autoWatering) {
              relayState = HIGH;
              digitalWrite(relayPin, relayState);
              relayOnTime = currentMillis;
              autoWatering = true;
              autoOffTime = currentMillis + 180000;
              Serial.println("自動散水 ON");
            }

            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html; charset=utf-8");
            client.println();
            client.println("<html>");
            client.println("<head><meta http-equiv='refresh' content='5'><meta charset='UTF-8'>");
            client.println("<style>");
            client.println("body { font-family: Arial, sans-serif; margin: 20px; }");
            client.println("h1 { color: #333 ; }");
            client.println(".button { padding: 10px 20px; margin: 10px; font-size: 16px; }");
            client.println(".on { background-color: #4CAF50 ; color: white; }");
            client.println(".off { background-color: #f44336 ; color: white; }");
            client.println("</style></head>");
            client.println("<body><h1>自動散水モニター</h1>");
            client.print("<p>気温: ");
            client.print(temp);
            client.println(" *C</p>");
            client.print("<p>湿度: ");
            client.print(hum);
            client.println(" %</p>");
            client.println("<p>Relay State: ");
            client.println(relayState ? "ON" : "OFF");
            client.println("</p>");
            if (autoWatering) {
              client.println("<p>自動散水オン</p>");
            }
            client.println("<button class=\"button on\" onclick=\"relayControl('on')\">Relay ON</button>");
            client.println("<button class=\"button off\" onclick=\"relayControl('off')\">Relay OFF</button>");
            client.println("<script>");
            client.println("function relayControl(state) {");
            client.println("  var xhttp = new XMLHttpRequest();");
            client.println("  xhttp.open('GET', '/' + state, true);");
            client.println("  xhttp.send();");
            client.println("}");
            client.println("</script>");
            client.println("</body></html>");

            client.println();
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

この記事が気に入ったらサポートをしてみませんか?