### 5.11 Web制御スマートファーム #### 5.11.1 ESP32ボードをネットワークに接続する ESP32ボードはWi-Fi(**2.4G**)とBluetooth(4.2)を搭載しており、Wi-Fiに簡単に接続したり、ネットワーク上の他のデバイスと通信したりできます。 準備するもの: - **2.4 GHz** Wi-Fi(モバイルホットスポットまたはルーターでも可) - Wi-Fi名とパスワード - 同じWi-Fiに接続できる電話/IPAD/コンピューター **Arduino IDEには、Wi-Fi設定とESP32 Wi-Fiネットワーク監視をサポートするライブラリファイル が用意されています。** A. **基地局モード**(STAまたはWi-Fiクライアント側モード):このモードでは、ESP32はWi-Fiホットスポット(AP)に接続します。 B. **APモード**(Soft-APまたはWi-Fiホットスポットモード):このモードでは、他のWi-FiデバイスがESP32に接続します。 C. **AP-STAモード**:このモードでは、ESP32はWi-Fiホットスポットであると同時に、別のWi-Fiホットスポットに接続するWi-Fiデバイスでもあります。 D. これらのモードは、WPA、WPA2、WEPなどの複数の安全モードと互換性があります。 E. アクティブスキャンとパッシブスキャンを含むWi-Fiホットスポットのスキャンが可能です。 F. IEEE802.11 Wi-Fiパケットを監視するためのプロミスキャスモードをサポートしています。 **Wi-Fiの詳細については、以下を参照してください。** https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html ESPRESSIF公式サイト:https://www.espressif.com.cn/en/home Arduino IDEで**5.11.0Connect-the-ESP32-to-the-Network**コードを開きます。 ```c #include const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; void setup() { Serial.begin(9600); //Initialize Wifi WiFi.begin(ssid, password); //Scan for wifi. If connection fails, stay in connecting, and execute "while" loop while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } //Connected. Print the IP address Serial.println("Connected to WiFi"); Serial.println(WiFi.localIP()); } void loop() { } ``` コード内の`your_SSID`をWi-Fiの名前に、`your_PASSWORD`をWi-Fiのパスワードに変更します。 ```c const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; ``` **ESP32 Dev Module**ボードと**COM**ポートを選択し、コードをアップロードします。 ![5458448](../media/5458448.png) **テスト結果:** コードをアップロードすると、ボードはWi-Fiネットワークに接続し、シリアルモニターにIPアドレスを表示します。 ![image-20250417153507142](../media/image-20250417153507142.png) #### 5.11.2 ウェブサイトのセットアップ - HELLOWORLD Wi-Fiに接続している限り、ESP32のWebサーバーライブラリはウェブページを提供できます。以下のサンプルコードでは、「Hello, World!」を表示する簡単なウェブサイトをセットアップします。 Arduino IDEで**5.11.1WiFi-HTML-HELLOWORLD**コードを開きます。 ```c #include #include const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; WebServer server(80); //Set the server port to 80. Enter the website by IP address rather than the port number. //Initialize the website void handleRoot() { //Used to send HTTP to the client-side for response, sending 200 means success. server.send(200, "text/html", "

Hello, World!

"); } void setup() { Serial.begin(9600); //Initialize wifi WiFi.begin(ssid, password); //Scan for wifi. If connection fails, stay in connecting, and execute "while" loop while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } //Connected. Print the IP address Serial.println("Connected to WiFi"); Serial.println(WiFi.localIP()); server.on("/", handleRoot); //Start server server.begin(); Serial.println("Web server started"); } void loop() { server.handleClient(); } ``` コード内の`your_SSID`をWi-Fiの名前に、`your_PASSWORD`をWi-Fiのパスワードに変更します。その後、コードをアップロードします。 ```c const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; ``` **ESP32 Dev Module**ボードと**COM**ポートを選択し、コードをアップロードします。 ![5458448](../media/5458448.png) **テスト結果:** このサンプルコードでは、ESP32のWebServerライブラリを使用してWebサーバーを構築します。handleRoot()関数はルートパスでの処理を要求し、クライアント側に「Hello, World!」のHTML応答を送信します。次に、setup()はルートを設定し、server.begin()はWebサーバーを開始します。 シリアルモニターをクリックしてIPアドレスを表示します。 ![image-20250417155849702](../media/image-20250417155849702.png) **注:PC、携帯電話、ESP32ボードが同じネットワークに接続されている場合、PCと携帯電話で同時にこのウェブサイトにアクセスできます。** PCブラウザまたは電話ブラウザでIPにアクセスします。 ![image-20250417155955349](../media/image-20250417155955349.png) 注:2.4 GHz Wi-Fiが必要です。5Gではありません。IPアドレスにアクセスするPCまたは携帯電話は、ESP32ボードと同じWi-Fiに接続されている必要があります。 ![image-20250417160135272](../media/image-20250417160135272.png) #### 5.11.3 Web制御スマートファーム ![flo11](../media/flo11.png) Arduino IDEで**5.11.2WiFi-HTML-Smart-Farm**コードを開きます。 ```c #include #include #include #include #include #include // Pin Definitions #define DHT11PIN 17 // 温度および湿度センサーピン #define LEDPIN 27 // LEDピン #define SERVOPIN 26 // サーボピン #define FANPIN1 19 // ファン IN+ ピン #define FANPIN2 18 // ファン IN- ピン #define STEAMPIN 35 // 蒸気センサーピン #define LIGHTPIN 34 // フォトレジスターピン #define SOILHUMIDITYPIN 32 // 土壌湿度センサーピン #define WATERLEVELPIN 33 // 水位センサーピン #define RELAYPIN 25 // リレーピン // センサーとコンポーネントの初期化 dht11 DHT11; LiquidCrystal_I2C lcd(0x27, 16, 2); Servo myservo; // サーボを制御するためのサーボオブジェクト // WiFi認証情報 const char *SSID = "your_SSID"; const char *PASS = "your_PASSWORD"; // WebServerオブジェクトの作成 WebServer server(80); // 状態を制御するための変数 static int A = 0; static int B = 0; static int C = 0; // HTML Webページコンテンツ const char index_html[] PROGMEM = R"rawliteral( TEST HTML ESP32
)rawliteral"; // センサーデータをHTML形式にマージする関数 String Merge_Data(void) { String dataBuffer; String Humidity; String Temperature; String Steam; String Light; String SoilHumidity; String WaterLevel; // DHT11センサーの読み取り int chk = DHT11.read(DHT11PIN); // 他のセンサーの読み取り Steam = String(analogRead(STEAMPIN) / 4095.0 * 100); Light = String(analogRead(LIGHTPIN)); int shvalue = analogRead(SOILHUMIDITYPIN) / 4095.0 * 100 * 2.3; shvalue = shvalue > 100 ? 100 : shvalue; SoilHumidity = String(shvalue); int wlvalue = analogRead(WATERLEVELPIN) / 4095.0 * 100 * 2.5; wlvalue = wlvalue > 100 ? 100 : wlvalue; WaterLevel = String(wlvalue); Temperature = String(DHT11.temperature); Humidity = String(DHT11.humidity); // HTMLコンテンツの構築 dataBuffer += "

"; dataBuffer += "

Sensor Data

"; dataBuffer += "Temperature:" + Temperature + "
"; dataBuffer += "Humidity:" + Humidity + "%rh
"; dataBuffer += "WaterLevel:" + WaterLevel + "%
"; dataBuffer += "Steam:" + Steam + "%
"; dataBuffer += "Light:" + Light + "
"; dataBuffer += "SoilHumidity:" + SoilHumidity + "%
"; dataBuffer += "

"; return dataBuffer; } // 受信したHTTPリクエストに基づいてアクションを設定 void Config_Callback() { if (server.hasArg("value")) { String HTTP_Payload = server.arg("value"); Serial.printf("[%lu]%s\r\n", millis(), HTTP_Payload.c_str()); if (HTTP_Payload == "A") { if (A) { digitalWrite(LEDPIN, LOW); A = 0; } else { digitalWrite(LEDPIN, HIGH); A = 1; } } if (HTTP_Payload == "B") { if (B) { digitalWrite(FANPIN1, LOW); digitalWrite(FANPIN2, LOW); B = 0; } else { delay(500); digitalWrite(FANPIN1, HIGH); digitalWrite(FANPIN2, LOW); delay(500); B = 1; } } if (HTTP_Payload == "C") { if (C) { myservo.write(80); delay(500); C = 0; } else { C = 1; myservo.write(180); delay(500); } } if (HTTP_Payload == "D") { digitalWrite(RELAYPIN, HIGH); delay(400); digitalWrite(RELAYPIN, LOW); delay(650); } } server.send(200, "text/plain", "OK"); } // 無効なURLアクセスを処理 void notFound() { server.send(404, "text/plain", "Not found"); } void setup() { Serial.begin(9600); // WiFiに接続 WiFi.begin(SSID, PASS); while (!WiFi.isConnected()) { delay(500); Serial.print("."); } Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // ピンを設定 pinMode(LEDPIN, OUTPUT); pinMode(STEAMPIN, INPUT); pinMode(LIGHTPIN, INPUT); pinMode(SOILHUMIDITYPIN, INPUT); pinMode(WATERLEVELPIN, INPUT); pinMode(RELAYPIN, OUTPUT); pinMode(FANPIN1, OUTPUT); pinMode(FANPIN2, OUTPUT); delay(1000); // サーボをピンに接続 myservo.attach(SERVOPIN); myservo.write(180); // LCDを初期化 lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("IP:"); lcd.setCursor(0, 1); lcd.print(WiFi.localIP()); // サーバールートを設定 server.on("/", HTTP_GET, []() { server.send(200, "text/html", index_html); }); server.on("/dht", HTTP_GET, []() { server.send(200, "text/plain", Merge_Data().c_str()); }); server.on("/set", HTTP_GET, Config_Callback); server.onNotFound(notFound); // サーバーを開始 server.begin(); } void loop() { server.handleClient(); } ``` コード内の `your_SSID` をWi-Fiの名前に、`your_PASSWORD` をWi-Fiのパスワードに変更してください。その後、コードをアップロードします。 ```c const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; ``` **ESP32 Dev Module** ボードと **COM** ポートを選択し、コードをアップロードします。 ![5458448](../media/5458448.png) **テスト結果:** **注: PC、携帯電話、ESP32ボードが同じネットワークに接続されている場合、PCと携帯電話で同時にこのウェブサイトにアクセスできます。** LCD1602からIPアドレスを表示: ![image-20250417161040242](../media/image-2025047161040242.png) 携帯電話またはPCのブラウザにIPアドレスを入力すると、ページ上部にセンサー値が表示され、下のボタンでLED、ファン、給餌室、ウォーターポンプを制御できます。 ![cou117](../media/cou117.png) 注: 2.4 GHz Wi-Fiが必要です。5Gは不可。IPアドレスにアクセスするPCまたは携帯電話は、ESP32ボードと同じWi-Fiに接続されている必要があります。 ![image-20250417160135272](../media/image-20250417160135272.png)