![見出し画像](https://assets.st-note.com/production/uploads/images/145590726/rectangle_large_type_2_af9862ad81bf48cf561ba3a16415e944.png?width=1200)
自動システムを作ってみる(コード編)
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.");
}
}