From 97623c6a7362839a5a1c0dd17502bf2bc71cd86c Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 12:39:04 -0600 Subject: [PATCH 01/19] Added smart plug code --- src/main/config.h | 15 ++++- src/main/main.ino | 163 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 166 insertions(+), 12 deletions(-) diff --git a/src/main/config.h b/src/main/config.h index 0f1a68a..2fe17a1 100644 --- a/src/main/config.h +++ b/src/main/config.h @@ -35,8 +35,19 @@ bool SHOW_CUSTOM_TEXT = true; // Set to true to show bool SHOW_IP_INFO = true; // Set to true to show IP information constexpr char STARTUP_TEXT[] = "HI"; // Startup custom text constexpr char CUSTOM_TEXT[] = ""; // OLED custom text "_____________________" -bool INTERUPT_WITH_BITMAP = true; // Periodically show bitmap -constexpr int INTERUPT_BITMAP_TIME = 300000; // Check WiFi time (ms) +bool INTERRUPT_WITH_BITMAP = true; // Periodically show bitmap +constexpr int INTERRUPT_BITMAP_TIME = 300000; // Check WiFi time (ms) + +// SMART PLUG CONFIGURATION +const char *intakePlugAlias = "plug_intake"; // Kasa plug alias (Intake) +const char *exhaustPlugAlias = "plug_exhaust"; // Kasa plug aliases (Exhaust) +constexpr int SMARTPLUG_UPDATE_TIME = 60000; // Update smart plugs time (ms) +constexpr float DESIRED_TEMP = 75.0; // Desired temperature in F +constexpr float DESIRED_HUMIDITY = 50.0; // Desired humidity in percentage +constexpr float DESIRED_CO2 = 800.0; // Desired CO2 level (ppm) +constexpr float TEMP_HYSTERESIS = 1.0; // Temperature hysteresis to prevent rapid switching +constexpr float HUMIDITY_HYSTERESIS = 5.0; // Humidity hysteresis to prevent rapid switching +constexpr float CO2_HYSTERESIS = 100.0; // CO2 hysteresis to prevent rapid switching // SERIAL CONFIGURATION constexpr int BAUD_RATE = 115200; // Baud rate diff --git a/src/main/main.ino b/src/main/main.ino index f7450ca..c336df4 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -2,7 +2,9 @@ * File: ./main.ino */ -// Dependencies +// ============================================================================ +// DEPENDENCIES ----------------------------------------------------------- +// ============================================================================ #include "WiFi.h" #include "ESPAsyncWebServer.h" #include "DHTesp.h" @@ -10,9 +12,10 @@ #include #include #include - -#include "config.h" // Include config header file -#include "bitmap.h" // Include bitmap header file +#include "KasaSmartPlug.h" // KASA TP-link smart plug library: https://github.com/kj831ca/KasaSmartPlug +#include "config.h" // Include config header file +#include "bitmap.h" // Include bitmap header file +// ============================================================================ // ============================================================================ // GLOBAL INSTANCES ----------------------------------------------------------- @@ -20,6 +23,9 @@ DHTesp dht; // DHT Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) AsyncWebServer server(SERVER_PORT); // Define server on port +KASAUtil kasaUtil; // Kasa utility object +KASASmartPlug *intakePlug = NULL; // Smart plug pointers (Intake) +KASASmartPlug *exhaustPlug = NULL; // Smart plug pointers (Exhaust) // ============================================================================ // ============================================================================ @@ -75,6 +81,89 @@ float celsiusToFahrenheit(float celsius) { return fahrenheit; } +// ------------------------------------- +// KASA TP-Link Smart Plug Functions +// ------------------------------------- +// Function to initialize smart plugs +void initSmartPlugs() { + int found = kasaUtil.ScanDevices(); + Serial.printf("Found %d Kasa devices\n", found); + + display.clearDisplay(); + display.setCursor(0, 0); + display.print("KASA devices found: "); + display.println(found); + display.display(); + delay(500); + + // Loop through found devices and match aliases + for (int i = 0; i < found; i++) { + KASASmartPlug *plug = kasaUtil.GetSmartPlugByIndex(i); + if (plug == NULL) continue; + + Serial.printf("Found Plug: %s (IP: %s, State: %d)\n", plug->alias, plug->ip_address, plug->state); + + display.clearDisplay(); + display.setCursor(0, 0); + display.print("KASA Smart Plugs"); + display.setCursor(0, 16); + display.print("Alias: "); + display.println(plug->alias); + display.print("IP : "); + display.println(plug->ip_address); + display.print("State : "); + display.println(plug->state); + display.display(); + delay(1000); + + // Match plugs by their aliases + if (strcmp(plug->alias, intakePlugAlias) == 0) { + intakePlug = plug; + Serial.println("Intake plug initialized."); + } else if (strcmp(plug->alias, exhaustPlugAlias) == 0) { + exhaustPlug = plug; + Serial.println("Exhaust plug initialized."); + } + } + + // Check if plugs were found + if (intakePlug == NULL) { + Serial.println("Error: Intake plug not found!"); + + display.clearDisplay(); + display.setCursor(0, 0); + display.print("ERROR: Intake plug not found"); + display.display(); + delay(1000); + } + if (exhaustPlug == NULL) { + Serial.println("Error: Exhaust plug not found!"); + + display.clearDisplay(); + display.setCursor(0, 0); + display.print("ERROR: Exhaust plug not found"); + display.display(); + delay(1000); + } +} + +// Function to turn a plug on or off +void setPlugState(const char *alias, bool state) { + KASASmartPlug *plug = kasaUtil.GetSmartPlug(alias); + if (plug == NULL) { + Serial.printf("Error: Could not find plug with alias '%s'\n", alias); + return; + } + + if (state) { + Serial.printf("Turning ON plug: %s\n", alias); + plug->SetRelayState(1); // Turn on + } else { + Serial.printf("Turning OFF plug: %s\n", alias); + plug->SetRelayState(0); // Turn off + } +} + // ------------------------------------- // WIFI Functions // ------------------------------------- @@ -265,11 +354,12 @@ void updateOLED(float co2, float temperature, float temperatureF, float humidity // SETUP ---------------------------------------------------------------------- // ============================================================================ void setup() { - pinMode(CO2_PIN, INPUT); // Set co2 pin mode + pinMode(CO2_PIN, INPUT); // Set co2 pin mode dht.setup(DHT_PIN, DHTesp::DHT_MODEL_t::DHT22); // Initialize DHT sensor - Serial.begin(BAUD_RATE); // Initialize Serial for debugging - initOLED(); // Initialize OLED - connectToWiFi(); // Connect to Wi-Fi + Serial.begin(BAUD_RATE); // Initialize Serial for debugging + initOLED(); // Initialize OLED + connectToWiFi(); // Connect to Wi-Fi + initSmartPlugs() // Initialize Smart Plugs // Define the root endpoint server.on(SERVER_PATH, HTTP_GET, [](AsyncWebServerRequest* request) { @@ -309,8 +399,10 @@ void loop() { static unsigned long lastUpdateTime = 0; static unsigned long lastWiFiCheck = 0; static unsigned long lastBitmapCheck = 0; + static unsigned long lastPlugCheck = 0; unsigned long currentTime = millis(); + // Update OLED display if (currentTime - lastUpdateTime >= SCREEN_UPDATE_TIME) { lastUpdateTime = currentTime; @@ -331,6 +423,57 @@ void loop() { updateOLED(co2, temperature, temperatureF, humidity); } +/* + * Temperature Too High -> Turn on the exhaust fan, consider additional cooling (e.g., A/C). + * Temperature Too Low -> Turn off the exhaust fan, possibly add a heater. + * Humidity Too High -> Turn on the exhaust fan to vent humid air, or use a dehumidifier. + * Humidity Too Low -> Turn off the exhaust fan, reduce intake, and add a humidifier if needed. + * CO2 Too High -> Turn on the exhaust fan to vent excess CO2. + * CO2 Too Low -> Turn off the exhaust fan to retain CO2, or add a CO2 source. +*/ + + // Update Smart plugs + if (currentTime - lastPlugCheck >= SMARTPLUG_UPDATE_TIME) { + lastPlugCheck = currentTime; + + // Get sensor values + float co2 = readCO2(); + float temperature = readTemperature(); + float temperatureF = celsiusToFahrenheit(temperature); + float humidity = readHumidity(); + + // Temperature control logic + if (temperatureF > DESIRED_TEMP + TEMP_HYSTERESIS) { // Temp too high + Serial.println("Temperature too high! Turning on intake and exhaust fans..."); + setPlugState(exhaustPlug, true); // Turn on exhaust fan + setPlugState(intakePlug, true); // Turn on intake fan + } else if (temperatureF < DESIRED_TEMP - TEMP_HYSTERESIS) { // Temp too low + Serial.println("Temperature too low! Turning off intake and exhaust fans..."); + setPlugState(exhaustPlug, false); // Turn off exhaust fan + setPlugState(intakePlug, false); // Turn off intake fan + } else { + // If temperature is within the target range, ensure both fans are off + setPlugState(exhaustPlug, false); // Turn off exhaust fan + setPlugState(intakePlug, false); // Turn off intake fan + } + + // Humidity control logic + if (humidity > DESIRED_HUMIDITY + HUMIDITY_HYSTERESIS) { // Humidity too high + Serial.println("Humidity too high! Turning on exhaust fan..."); + setPlugState(exhaustPlug, true); // Turn on exhaust fan + } else if (humidity < DESIRED_HUMIDITY - HUMIDITY_HYSTERESIS) { // Humidity too low + Serial.println("Humidity too low! Turning off intake and exhaust fans..."); + setPlugState(intakePlug, false); // Turn off intake fan + setPlugState(exhaustPlug, false); // Turn off exhaust fan + // Optionally, activate a humidifier if available + } else { + // If humidity is within the target range, ensure both fans are off + setPlugState(exhaustPlug, false); // Turn off exhaust fan + setPlugState(intakePlug, false); // Turn off intake fan + } + //TODO: Add CO2 levels + } + // Periodically check Wi-Fi status if (currentTime - lastWiFiCheck >= WIFI_CHECK_INTERVAL) { lastWiFiCheck = currentTime; @@ -349,8 +492,8 @@ void loop() { } // Periodically show bitmap - if (INTERUPT_WITH_BITMAP) { - if (currentTime - lastBitmapCheck >= INTERUPT_BITMAP_TIME) { + if (INTERRUPT_WITH_BITMAP) { + if (currentTime - lastBitmapCheck >= INTERRUPT_BITMAP_TIME) { lastBitmapCheck = currentTime; showBitmap(); } From 171c56b161d470e671ea8b350ef4127236bb140e Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 12:45:52 -0600 Subject: [PATCH 02/19] Added smart plug to readme --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index 4d9c656..f11e5d9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -29,6 +29,7 @@ Here is a list of parts used in this project | 10K Ω Resistor | $0.25 | 0/1 | 10K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR67DJHM) | Most DHT22 sensor modules have a built-in resistor | | Wire/Breadboard | $1 | 0/1 | Jumper wire or breadboard | [Amazon](https://www.amazon.com/DEYUE-breadboard-Set-Prototype-Board/dp/B07LFD4LT6) | Optional depending on setup | | Breakout Board | $4 | 0/1 | ESP32 Breakout Board GPIO | [Amazon](https://www.amazon.com/dp/B0BNQ8V65G) | Optional depending on setup | +| Kasa Smart Plug | $7.50 | 2 | TP-Link Kasa Smart Plug HS103 | [Amazon](https://www.amazon.com/dp/B07RCNB2L3) | Intake and exhaust fans | > *Lower prices can be found if you shop around* From b9d475514305cf96d46b0d75dc33cdef3fbcf0e9 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 13:55:59 -0600 Subject: [PATCH 03/19] Increased version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 857572f..d3845ad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v4.0.0 +v5.0.0 From 9338af756232d34f3635e558bc6708b8cba8c2c8 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:00:58 -0600 Subject: [PATCH 04/19] Added total to readme --- docs/README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index f11e5d9..57ef0d8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,17 +19,18 @@ Here is a list of parts used in this project > *Amazon links are non-affiliate* -| NAME | PRICE | COUNT | DESCRIPTION | LINK | NOTE | -|-----------------|-------|-------|-----------------------------------|--------|----------------------------------------------------| -| ESP32 | $5 | 1 | Microcontroller | [Amazon](https://www.amazon.com/ESP-WROOM-31-Development-Microcontroller-Integrated-Compatible/dp/B08D5ZD528) | [USB-C ESP32 Amazon](https://www.amazon.com/dp/B0CR5Y2JVD) | -| DHT22 | $7 | 1 | Temp/Humidity Sensor | [Amazon](https://www.amazon.com/gp/product/B0795F19W6) | | -| MQ-135 | $3 | 1 | CO2 Sensor | [Amazon](https://www.amazon.com/Ximimark-Quality-Hazardous-Detection-Arduino/dp/B07L73VTTY) | | -| OLED Display | $3 | 1 | 0.96" OLED Display 128x64 SSD1306 | [Amazon](https://www.amazon.com/Hosyond-Display-Self-Luminous-Compatible-Raspberry/dp/B09C5K91H7) | | -| 1K Ω Resistor | $0.25 | 1 | 1K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR66ZN6B) | MQ-135 analog pin | -| 10K Ω Resistor | $0.25 | 0/1 | 10K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR67DJHM) | Most DHT22 sensor modules have a built-in resistor | -| Wire/Breadboard | $1 | 0/1 | Jumper wire or breadboard | [Amazon](https://www.amazon.com/DEYUE-breadboard-Set-Prototype-Board/dp/B07LFD4LT6) | Optional depending on setup | -| Breakout Board | $4 | 0/1 | ESP32 Breakout Board GPIO | [Amazon](https://www.amazon.com/dp/B0BNQ8V65G) | Optional depending on setup | -| Kasa Smart Plug | $7.50 | 2 | TP-Link Kasa Smart Plug HS103 | [Amazon](https://www.amazon.com/dp/B07RCNB2L3) | Intake and exhaust fans | +| NAME | PRICE | COUNT | DESCRIPTION | LINK | NOTE | +|-----------------|---------|-------|-----------------------------------|--------|----------------------------------------------------| +| ESP32 | $5 | 1 | Microcontroller | [Amazon](https://www.amazon.com/ESP-WROOM-31-Development-Microcontroller-Integrated-Compatible/dp/B08D5ZD528) | [USB-C ESP32 Amazon](https://www.amazon.com/dp/B0CR5Y2JVD) | +| DHT22 | $3 | 1 | Temp/Humidity Sensor | [Amazon](https://www.amazon.com/dp/B0CPHQC9SF) | | +| MQ-135 | $3 | 1 | CO2 Sensor | [Amazon](https://www.amazon.com/Ximimark-Quality-Hazardous-Detection-Arduino/dp/B07L73VTTY) | | +| OLED Display | $3 | 1 | 0.96" OLED Display 128x64 SSD1306 | [Amazon](https://www.amazon.com/Hosyond-Display-Self-Luminous-Compatible-Raspberry/dp/B09C5K91H7) | | +| 1K Ω Resistor | $0.25 | 1 | 1K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR66ZN6B) | MQ-135 analog pin | +| 10K Ω Resistor | $0.25 | 0/1 | 10K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR67DJHM) | Most DHT22 sensor modules have a built-in resistor | +| Wire/Breadboard | $1 | 0/1 | Jumper wire or breadboard | [Amazon](https://www.amazon.com/DEYUE-breadboard-Set-Prototype-Board/dp/B07LFD4LT6) | Optional depending on setup | +| Breakout Board | $4 | 0/1 | ESP32 Breakout Board GPIO | [Amazon](https://www.amazon.com/dp/B0BNQ8V65G) | Optional depending on setup | +| Kasa Smart Plug | $7.50 | 2 | TP-Link Kasa Smart Plug HS103 | [Amazon](https://www.amazon.com/dp/B07RCNB2L3) | Intake and exhaust fans | +| **TOTAL** | ~$34.25 | | | | | > *Lower prices can be found if you shop around* From 9f907a10236360dec838c72c12f774d338caa273 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:08:18 -0600 Subject: [PATCH 05/19] Updated readme --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 57ef0d8..4ec836d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -25,11 +25,11 @@ Here is a list of parts used in this project | DHT22 | $3 | 1 | Temp/Humidity Sensor | [Amazon](https://www.amazon.com/dp/B0CPHQC9SF) | | | MQ-135 | $3 | 1 | CO2 Sensor | [Amazon](https://www.amazon.com/Ximimark-Quality-Hazardous-Detection-Arduino/dp/B07L73VTTY) | | | OLED Display | $3 | 1 | 0.96" OLED Display 128x64 SSD1306 | [Amazon](https://www.amazon.com/Hosyond-Display-Self-Luminous-Compatible-Raspberry/dp/B09C5K91H7) | | +| Kasa Smart Plug | $7.50 | 2 | TP-Link Kasa Smart Plug HS103 | [Amazon](https://www.amazon.com/dp/B07RCNB2L3) | Intake and exhaust fans smart plugs | | 1K Ω Resistor | $0.25 | 1 | 1K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR66ZN6B) | MQ-135 analog pin | | 10K Ω Resistor | $0.25 | 0/1 | 10K Ohm Resistor | [Amazon](https://www.amazon.com/California-JOS-Carbon-Resistor-Tolerance/dp/B0BR67DJHM) | Most DHT22 sensor modules have a built-in resistor | | Wire/Breadboard | $1 | 0/1 | Jumper wire or breadboard | [Amazon](https://www.amazon.com/DEYUE-breadboard-Set-Prototype-Board/dp/B07LFD4LT6) | Optional depending on setup | | Breakout Board | $4 | 0/1 | ESP32 Breakout Board GPIO | [Amazon](https://www.amazon.com/dp/B0BNQ8V65G) | Optional depending on setup | -| Kasa Smart Plug | $7.50 | 2 | TP-Link Kasa Smart Plug HS103 | [Amazon](https://www.amazon.com/dp/B07RCNB2L3) | Intake and exhaust fans | | **TOTAL** | ~$34.25 | | | | | > *Lower prices can be found if you shop around* From 7a632a6f79ee74f6074628985f83a4012ec1b5e6 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:19:58 -0600 Subject: [PATCH 06/19] Added F() to println --- src/main/main.ino | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/main.ino b/src/main/main.ino index c336df4..5830768 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -170,6 +170,9 @@ void setPlugState(const char *alias, bool state) { // Function to connect to Wi-Fi void connectToWiFi() { Serial.println(F("Setting up Wi-Fi...")); + + WiFi.mode(WIFI_STA); // Station mode only + if (!WiFi.setHostname(WIFI_HOSTNAME)) { Serial.printf("Error: Failed to set Wi-Fi hostname: %s\n", WIFI_HOSTNAME); } @@ -417,7 +420,7 @@ void loop() { Serial.printf("Temperature: %.2f F\n", temperatureF); Serial.printf("Humidity : %.2f %%\n", humidity); Serial.printf("CO2 : %.2f ppm\n", co2); - Serial.println("Updating display..."); + Serial.println(F("Updating display...")); // Update OLED display with latest sensor data updateOLED(co2, temperature, temperatureF, humidity); @@ -444,11 +447,11 @@ void loop() { // Temperature control logic if (temperatureF > DESIRED_TEMP + TEMP_HYSTERESIS) { // Temp too high - Serial.println("Temperature too high! Turning on intake and exhaust fans..."); + Serial.println(F("Temperature too high! Turning on intake and exhaust fans...")); setPlugState(exhaustPlug, true); // Turn on exhaust fan setPlugState(intakePlug, true); // Turn on intake fan } else if (temperatureF < DESIRED_TEMP - TEMP_HYSTERESIS) { // Temp too low - Serial.println("Temperature too low! Turning off intake and exhaust fans..."); + Serial.println(F("Temperature too low! Turning off intake and exhaust fans...")); setPlugState(exhaustPlug, false); // Turn off exhaust fan setPlugState(intakePlug, false); // Turn off intake fan } else { @@ -459,10 +462,10 @@ void loop() { // Humidity control logic if (humidity > DESIRED_HUMIDITY + HUMIDITY_HYSTERESIS) { // Humidity too high - Serial.println("Humidity too high! Turning on exhaust fan..."); + Serial.println(F("Humidity too high! Turning on exhaust fan...")); setPlugState(exhaustPlug, true); // Turn on exhaust fan } else if (humidity < DESIRED_HUMIDITY - HUMIDITY_HYSTERESIS) { // Humidity too low - Serial.println("Humidity too low! Turning off intake and exhaust fans..."); + Serial.println(F("Humidity too low! Turning off intake and exhaust fans...")); setPlugState(intakePlug, false); // Turn off intake fan setPlugState(exhaustPlug, false); // Turn off exhaust fan // Optionally, activate a humidifier if available From ef82d852ba373ca8b38efdedc319fd949bd2856e Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:32:43 -0600 Subject: [PATCH 07/19] Added toc and libraries section to readme --- docs/README.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 4ec836d..fb88d4e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,26 @@ -# ESP32 Plant Monitoring / Watering System +# ESP32 Plant Monitoring System + + +- [ESP32 Plant Monitoring System](#esp32-plant-monitoring-system) + - [Overview](#overview) + - [Shopping List](#shopping-list) + - [Setup](#setup) + - [Circuit Schematic](#circuit-schematic) + - [ESP32 Pinout](#esp32-pinout) + - [30 Pin](#30-pin) + - [38 Pin](#38-pin) + - [Configuration](#configuration) + - [WiFI Configuration](#wifi-configuration) + - [Other Configuration](#other-configuration) + - [Libraries](#libraries) + - [External Libraries](#external-libraries) + - [Uploading](#uploading) + - [3D Print](#3d-print) + - [DHT22 Case](#dht22-case) + - [MQ-135 Case](#mq-135-case) + - [TODO](#todo) + - [Links](#links) + ![ESP32 Plant Monitoring Project Image](/static/img/project.png) @@ -86,6 +108,19 @@ Here is a list of WiFi variables that **must** be defined and their descriptions Other variables in the code can be changed to suite your needs +### Libraries + +You will need to install additional libraries. + +In Arduino IDE, go to library manager and search and install the +required libraries listed in the `DEPENDENCIES` section in [`main.ino`](/src/main/main.ino) + +#### External Libraries + +- [KasaSmartPlug Github](https://github.com/kj831ca/KasaSmartPlug) + +--- + ### Uploading I use Arduino IDE to upload the code to the board. I had to install additional drivers ***[(Download)](https://www.silabs.com/documents/public/software/CP210x_Universal_Windows_Driver.zip)*** to get connected to my board. From 0c8f0bef20904bf8d4421a76cca636518c7cca58 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:33:40 -0600 Subject: [PATCH 08/19] Added toc --- docs/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index fb88d4e..a151af3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,14 @@ # ESP32 Plant Monitoring System +![ESP32 Plant Monitoring Project Image](/static/img/project.png) + +--- + +## Table of Contents + - [ESP32 Plant Monitoring System](#esp32-plant-monitoring-system) + - [Table of Contents](#table-of-contents) - [Overview](#overview) - [Shopping List](#shopping-list) - [Setup](#setup) @@ -22,8 +29,6 @@ - [Links](#links) -![ESP32 Plant Monitoring Project Image](/static/img/project.png) - --- ## Overview From d355cf667554e85a1e1ba7a7d139a972a2f6796b Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:35:17 -0600 Subject: [PATCH 09/19] Added image section --- docs/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/README.md b/docs/README.md index a151af3..1eb9c0c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,7 @@ - [Libraries](#libraries) - [External Libraries](#external-libraries) - [Uploading](#uploading) + - [Images](#images) - [3D Print](#3d-print) - [DHT22 Case](#dht22-case) - [MQ-135 Case](#mq-135-case) @@ -134,6 +135,13 @@ I installed the ESP32 boards and selected ESP32dev board. --- +## Images + + +![ESP32 Plant Monitoring Project Image](/static/img/project.png) + +--- + ## 3D Print ![ESP32 Plant Monitoring Housing Image](/static/img/3d-housing.png) From 13be0409170a76d9f294aa0bd0ab1d019dad383a Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:36:10 -0600 Subject: [PATCH 10/19] Added link --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index 1eb9c0c..e41b9b3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -184,5 +184,6 @@ The 3D model files are located under the [3D-models](/3D-models) directory. * https://www.thingiverse.com/thing:4521313 * https://www.thingiverse.com/thing:2893581 * https://javl.github.io/image2cpp +* https://github.com/kj831ca/KasaSmartPlug --- From 5b74fc5b47c3fd07c97f413d04aa767d718b37f0 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:36:57 -0600 Subject: [PATCH 11/19] Added link --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index e41b9b3..9f74715 100644 --- a/docs/README.md +++ b/docs/README.md @@ -140,6 +140,9 @@ I installed the ESP32 boards and selected ESP32dev board. ![ESP32 Plant Monitoring Project Image](/static/img/project.png) +> [!TIP] +> gggg + --- ## 3D Print From f49dc7130eaa1578b459709f9b48e3ddb51468df Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:40:19 -0600 Subject: [PATCH 12/19] Added link --- docs/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9f74715..3480fb5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -138,10 +138,11 @@ I installed the ESP32 boards and selected ESP32dev board. ## Images -![ESP32 Plant Monitoring Project Image](/static/img/project.png) -> [!TIP] -> gggg +| | | +|--------------------------------------|--------------------------------------| +| ![ESP32 Plant Monitoring Project Image](/static/img/project.png) | ![ESP32 Plant Monitoring Project Image](/static/img/project.png) | +| ![ESP32 Plant Monitoring Project Image](/static/img/project.png) | ![ESP32 Plant Monitoring Project Image](/static/img/project.png) | --- From 098df69d69cfaf03f196436bd9cc09931ecb0991 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:42:05 -0600 Subject: [PATCH 13/19] Added tip and note --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index 3480fb5..c16fc87 100644 --- a/docs/README.md +++ b/docs/README.md @@ -60,6 +60,7 @@ Here is a list of parts used in this project | Breakout Board | $4 | 0/1 | ESP32 Breakout Board GPIO | [Amazon](https://www.amazon.com/dp/B0BNQ8V65G) | Optional depending on setup | | **TOTAL** | ~$34.25 | | | | | +> [!TIP] > *Lower prices can be found if you shop around* --- @@ -81,6 +82,7 @@ Once you have all the required parts in hand, you can start wiring | 21 | OLED SCL | SCL | 3.3 | 3.3V | GND | | 22 | OLED SDA | SDA | 3.3 | 3.3V | GND | +> [!NOTE] > *Feel free to change the pins used on the ESP32, just note, if you change the pins, you will need to update the values in the code.* ### ESP32 Pinout From cf54390b5180f501fd5675a302c01d7c1b1b60b3 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 14:42:32 -0600 Subject: [PATCH 14/19] Added tip and note --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index c16fc87..1ad678b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,6 +45,7 @@ This is designed to be used to monitor the environment when growing plants Here is a list of parts used in this project +> [!NOTE] > *Amazon links are non-affiliate* | NAME | PRICE | COUNT | DESCRIPTION | LINK | NOTE | From a4a069a449ba86d48c15aed5ec925513555501e8 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 22:00:49 -0600 Subject: [PATCH 15/19] Fixed missing ; --- src/main/main.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/main.ino b/src/main/main.ino index 5830768..372db39 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -362,7 +362,7 @@ void setup() { Serial.begin(BAUD_RATE); // Initialize Serial for debugging initOLED(); // Initialize OLED connectToWiFi(); // Connect to Wi-Fi - initSmartPlugs() // Initialize Smart Plugs + initSmartPlugs(); // Initialize Smart Plugs // Define the root endpoint server.on(SERVER_PATH, HTTP_GET, [](AsyncWebServerRequest* request) { From a328d8353f0b708e78b59d7471b39c1c765026da Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 22:30:04 -0600 Subject: [PATCH 16/19] Fixed kasa object type errors --- src/main/.theia/launch.json | 19 +++++++++++++++++++ src/main/main.ino | 18 ++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 src/main/.theia/launch.json diff --git a/src/main/.theia/launch.json b/src/main/.theia/launch.json new file mode 100644 index 0000000..1c48c5b --- /dev/null +++ b/src/main/.theia/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [ + + { + "cwd": "${workspaceFolder}", + "executable": "./bin/executable.elf", + "name": "Debug with JLink", + "request": "launch", + "type": "cortex-debug", + "device": "", + "runToEntryPoint": "main", + "showDevDebugOutput": "none", + "servertype": "jlink" + } + ] +} diff --git a/src/main/main.ino b/src/main/main.ino index 372db39..b50d6a0 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -148,18 +148,20 @@ void initSmartPlugs() { } // Function to turn a plug on or off -void setPlugState(const char *alias, bool state) { - KASASmartPlug *plug = kasaUtil.GetSmartPlug(alias); +void setPlugState(KASASmartPlug* plug, bool state) { + // Setting variable for printing. otherwise dont need this + KASASmartPlug *plugAlias = kasaUtil.GetSmartPlug(plug->alias); + if (plug == NULL) { - Serial.printf("Error: Could not find plug with alias '%s'\n", alias); + //Serial.printf("Error: Could not find plug with alias '%s'\n", plugAlias); return; } if (state) { - Serial.printf("Turning ON plug: %s\n", alias); + //Serial.printf("Turning ON plug: %s\n", plugAlias); plug->SetRelayState(1); // Turn on } else { - Serial.printf("Turning OFF plug: %s\n", alias); + //Serial.printf("Turning OFF plug: %s\n", plugAlias); plug->SetRelayState(0); // Turn off } } @@ -290,13 +292,13 @@ void showIPInfo() { if (SHOW_IP_INFO) { display.clearDisplay(); display.setCursor(0, 16); - display.print("SSID: "); + display.print("SSID: "); display.println(WIFI_SSID); display.setCursor(0, 26); - display.print("Hostname: "); + display.print("Host: "); display.println(WiFi.getHostname()); display.setCursor(0, 36); - display.print("IP: "); + display.print("IP: "); display.println(WiFi.localIP().toString().c_str()); // Custom Text From 3090541c406d03c34a8cbec45eecdb5ba5100915 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 22:38:47 -0600 Subject: [PATCH 17/19] Added TODO --- src/main/main.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/main.ino b/src/main/main.ino index b50d6a0..c9583c2 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -150,6 +150,7 @@ void initSmartPlugs() { // Function to turn a plug on or off void setPlugState(KASASmartPlug* plug, bool state) { // Setting variable for printing. otherwise dont need this + //TODO: Figure out how to turn this into a string KASASmartPlug *plugAlias = kasaUtil.GetSmartPlug(plug->alias); if (plug == NULL) { @@ -166,6 +167,8 @@ void setPlugState(KASASmartPlug* plug, bool state) { } } +//TODO: Function to get plug state + // ------------------------------------- // WIFI Functions // ------------------------------------- From 4402d344c172382bf0d18549233f820810de4117 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 23:00:12 -0600 Subject: [PATCH 18/19] Disabled humidity. will need to get a humidifier for this one --- src/main/main.ino | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/main.ino b/src/main/main.ino index c9583c2..7994d22 100644 --- a/src/main/main.ino +++ b/src/main/main.ino @@ -460,25 +460,25 @@ void loop() { setPlugState(exhaustPlug, false); // Turn off exhaust fan setPlugState(intakePlug, false); // Turn off intake fan } else { - // If temperature is within the target range, ensure both fans are off + // If temperature is within the target range, turn off fans to save energy setPlugState(exhaustPlug, false); // Turn off exhaust fan setPlugState(intakePlug, false); // Turn off intake fan } - // Humidity control logic - if (humidity > DESIRED_HUMIDITY + HUMIDITY_HYSTERESIS) { // Humidity too high - Serial.println(F("Humidity too high! Turning on exhaust fan...")); - setPlugState(exhaustPlug, true); // Turn on exhaust fan - } else if (humidity < DESIRED_HUMIDITY - HUMIDITY_HYSTERESIS) { // Humidity too low - Serial.println(F("Humidity too low! Turning off intake and exhaust fans...")); - setPlugState(intakePlug, false); // Turn off intake fan - setPlugState(exhaustPlug, false); // Turn off exhaust fan - // Optionally, activate a humidifier if available - } else { - // If humidity is within the target range, ensure both fans are off - setPlugState(exhaustPlug, false); // Turn off exhaust fan - setPlugState(intakePlug, false); // Turn off intake fan - } +// // Humidity control logic +// if (humidity > DESIRED_HUMIDITY + HUMIDITY_HYSTERESIS) { // Humidity too high +// Serial.println(F("Humidity too high! Turning on exhaust fan...")); +// setPlugState(exhaustPlug, true); // Turn on exhaust fan +// } else if (humidity < DESIRED_HUMIDITY - HUMIDITY_HYSTERESIS) { // Humidity too low +// Serial.println(F("Humidity too low! Turning off intake and exhaust fans...")); +// setPlugState(intakePlug, false); // Turn off intake fan +// setPlugState(exhaustPlug, false); // Turn off exhaust fan +// // Optionally, activate a humidifier if available +// } else { +// // If humidity is within the target range, turn off fans to save energy +// setPlugState(exhaustPlug, false); // Turn off exhaust fan +// setPlugState(intakePlug, false); // Turn off intake fan +// } //TODO: Add CO2 levels } From 1462c01a0f0d2f7ed67c7325e916c295b09c4ff1 Mon Sep 17 00:00:00 2001 From: ConnerWill Date: Thu, 23 Jan 2025 23:07:04 -0600 Subject: [PATCH 19/19] Tuned settings --- src/main/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/config.h b/src/main/config.h index 2fe17a1..7e2d55f 100644 --- a/src/main/config.h +++ b/src/main/config.h @@ -33,7 +33,7 @@ bool SHOW_STARTUP = true; // Set to true to show bool SHOW_BITMAP = true; // Set to true to show the bitmap bool SHOW_CUSTOM_TEXT = true; // Set to true to show custom text bool SHOW_IP_INFO = true; // Set to true to show IP information -constexpr char STARTUP_TEXT[] = "HI"; // Startup custom text +constexpr char STARTUP_TEXT[] = ":)"; // Startup custom text constexpr char CUSTOM_TEXT[] = ""; // OLED custom text "_____________________" bool INTERRUPT_WITH_BITMAP = true; // Periodically show bitmap constexpr int INTERRUPT_BITMAP_TIME = 300000; // Check WiFi time (ms) @@ -41,7 +41,7 @@ constexpr int INTERRUPT_BITMAP_TIME = 300000; // Check WiFi time (ms) // SMART PLUG CONFIGURATION const char *intakePlugAlias = "plug_intake"; // Kasa plug alias (Intake) const char *exhaustPlugAlias = "plug_exhaust"; // Kasa plug aliases (Exhaust) -constexpr int SMARTPLUG_UPDATE_TIME = 60000; // Update smart plugs time (ms) +constexpr int SMARTPLUG_UPDATE_TIME = 30000; // Update smart plugs time (ms) constexpr float DESIRED_TEMP = 75.0; // Desired temperature in F constexpr float DESIRED_HUMIDITY = 50.0; // Desired humidity in percentage constexpr float DESIRED_CO2 = 800.0; // Desired CO2 level (ppm)