227 lines
7.0 KiB
C++
227 lines
7.0 KiB
C++
#include <WiFi.h>
|
|
#include <AsyncTCP.h>
|
|
#include <ESPAsyncWebServer.h>
|
|
#include <Wire.h>
|
|
#include "Adafruit_AHTX0.h"
|
|
|
|
// WiFi Credentials
|
|
const char* ssid = "HickmanWiFi";
|
|
const char* password = "BlackBriar8787@@";
|
|
|
|
// Sensor and Server Instances
|
|
Adafruit_AHTX0 aht;
|
|
AsyncWebServer server(80);
|
|
|
|
// Pins for Relays
|
|
#define FAN_RELAY_PIN 26
|
|
#define HEATER_RELAY_PIN 25 // GPIO 25 for heater relay
|
|
|
|
// Dryer State Variables
|
|
bool dryerOn = false;
|
|
bool fanRelayState = false;
|
|
bool heaterRelayState = false;
|
|
float currentTemperature = 0.0;
|
|
float currentHumidity = 0.0;
|
|
float targetTemperature = 0.0;
|
|
int dryingTime = 0; // Total drying time in minutes
|
|
int remainingTime = 0; // Remaining drying time in minutes
|
|
unsigned long startTime = 0; // Time when the dryer was started (millis)
|
|
|
|
// Historical Data
|
|
const int maxHistory = 180;
|
|
std::vector<float> tempHistory;
|
|
std::vector<float> humidityHistory;
|
|
|
|
// Initialize Relays and Sensor
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
// Connect to WiFi
|
|
WiFi.begin(ssid, password);
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(1000);
|
|
Serial.println("Connecting to WiFi...");
|
|
}
|
|
Serial.println("Connected to WiFi");
|
|
|
|
// AHT10 Sensor Setup
|
|
if (!aht.begin()) {
|
|
Serial.println("Failed to find AHT10 sensor");
|
|
while (1) delay(10);
|
|
}
|
|
Serial.println("AHT10 Found");
|
|
|
|
// Setup Relay Pins
|
|
pinMode(FAN_RELAY_PIN, OUTPUT);
|
|
pinMode(HEATER_RELAY_PIN, OUTPUT);
|
|
digitalWrite(FAN_RELAY_PIN, LOW);
|
|
digitalWrite(HEATER_RELAY_PIN, LOW);
|
|
|
|
// Web Server Endpoints
|
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
|
request->send(200, "text/plain", "Filament Dryer Control");
|
|
});
|
|
|
|
server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request) {
|
|
sensors_event_t humidity, temp;
|
|
aht.getEvent(&humidity, &temp);
|
|
|
|
currentTemperature = temp.temperature;
|
|
currentHumidity = humidity.relative_humidity;
|
|
|
|
// Update remaining drying time
|
|
if (dryerOn) {
|
|
unsigned long elapsedTime = (millis() - startTime) / 60000; // Convert to minutes
|
|
remainingTime = dryingTime > elapsedTime ? dryingTime - elapsedTime : 0;
|
|
|
|
// Automatically turn off dryer when time is up
|
|
if (remainingTime == 0) {
|
|
dryerOn = false;
|
|
heaterRelayState = false;
|
|
fanRelayState = false;
|
|
digitalWrite(HEATER_RELAY_PIN, LOW);
|
|
digitalWrite(FAN_RELAY_PIN, LOW);
|
|
Serial.println("Drying completed. Dryer turned off.");
|
|
}
|
|
} else {
|
|
remainingTime = 0;
|
|
}
|
|
|
|
// Store historical data
|
|
if (tempHistory.size() >= maxHistory) tempHistory.erase(tempHistory.begin());
|
|
if (humidityHistory.size() >= maxHistory) humidityHistory.erase(humidityHistory.begin());
|
|
tempHistory.push_back(currentTemperature);
|
|
humidityHistory.push_back(currentHumidity);
|
|
|
|
String response = "{";
|
|
response += "\"dryerOn\":" + String(dryerOn ? "true" : "false") + ",";
|
|
response += "\"fanRelayState\":" + String(fanRelayState ? "true" : "false") + ",";
|
|
response += "\"heaterRelayState\":" + String(heaterRelayState ? "true" : "false") + ",";
|
|
response += "\"temperature\":" + String(currentTemperature) + ",";
|
|
response += "\"humidity\":" + String(currentHumidity) + ",";
|
|
response += "\"targetTemperature\":" + String(targetTemperature) + ",";
|
|
response += "\"dryingTime\":" + String(dryingTime) + ","; // Total drying time
|
|
response += "\"remainingTime\":" + String(remainingTime) + ","; // Remaining time
|
|
|
|
// Serialize temperature and humidity history
|
|
response += "\"tempHistory\":[";
|
|
for (size_t i = 0; i < tempHistory.size(); i++) {
|
|
response += String(tempHistory[i]);
|
|
if (i < tempHistory.size() - 1) response += ",";
|
|
}
|
|
response += "],";
|
|
|
|
response += "\"humidityHistory\":[";
|
|
for (size_t i = 0; i < humidityHistory.size(); i++) {
|
|
response += String(humidityHistory[i]);
|
|
if (i < humidityHistory.size() - 1) response += ",";
|
|
}
|
|
response += "]";
|
|
|
|
|
|
response += "}";
|
|
|
|
request->send(200, "application/json", response);
|
|
});
|
|
|
|
server.on("/control", HTTP_POST, [](AsyncWebServerRequest *request) {
|
|
int params = request->params();
|
|
for (int i = 0; i < params; i++) {
|
|
AsyncWebParameter* p = request->getParam(i);
|
|
if (p->name() == "dryerOn") {
|
|
dryerOn = (p->value() == "true");
|
|
if (dryerOn) {
|
|
startTime = millis();
|
|
fanRelayState = true;
|
|
}
|
|
} else if (p->name() == "targetTemperature") {
|
|
targetTemperature = p->value().toFloat();
|
|
} else if (p->name() == "dryingTime") {
|
|
dryingTime = p->value().toInt();
|
|
}
|
|
}
|
|
|
|
request->send(200, "application/json", "{\"status\":\"success\"}");
|
|
});
|
|
|
|
// CORS Handling
|
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
|
|
|
|
// Start Server
|
|
server.begin();
|
|
}
|
|
|
|
// Monitor and Update
|
|
void loop() {
|
|
sensors_event_t humidity, temp;
|
|
aht.getEvent(&humidity, &temp);
|
|
currentTemperature = temp.temperature;
|
|
currentHumidity = humidity.relative_humidity;
|
|
|
|
// Safety Controls
|
|
if (currentTemperature > 26.0) {
|
|
fanRelayState = true;
|
|
digitalWrite(FAN_RELAY_PIN, HIGH); // Force fan on
|
|
Serial.println("Safety: Fan forced ON due to high temperature.");
|
|
}
|
|
|
|
// Dryer Control Logic
|
|
if (dryerOn) {
|
|
if (currentTemperature < targetTemperature) {
|
|
heaterRelayState = true;
|
|
digitalWrite(HEATER_RELAY_PIN, HIGH);
|
|
} else {
|
|
heaterRelayState = false;
|
|
digitalWrite(HEATER_RELAY_PIN, LOW);
|
|
}
|
|
|
|
// Ensure the fan is always on when the heater is active
|
|
fanRelayState = true;
|
|
digitalWrite(FAN_RELAY_PIN, HIGH);
|
|
} else {
|
|
heaterRelayState = false;
|
|
digitalWrite(HEATER_RELAY_PIN, LOW);
|
|
if (currentTemperature <= 26.0) {
|
|
fanRelayState = false;
|
|
digitalWrite(FAN_RELAY_PIN, LOW);
|
|
}
|
|
}
|
|
|
|
// Manual Serial Command Handling
|
|
handleSerialCommands();
|
|
|
|
delay(5000); // Update sensor readings every 5 seconds
|
|
}
|
|
|
|
// Handle Serial Commands to Control Relays
|
|
void handleSerialCommands() {
|
|
if (Serial.available() > 0) {
|
|
String command = Serial.readStringUntil('\n');
|
|
command.trim();
|
|
|
|
if (command == "fan on") {
|
|
fanRelayState = true;
|
|
digitalWrite(FAN_RELAY_PIN, HIGH);
|
|
Serial.println("Fan relay activated.");
|
|
} else if (command == "fan off") {
|
|
fanRelayState = false;
|
|
digitalWrite(FAN_RELAY_PIN, LOW);
|
|
Serial.println("Fan relay deactivated.");
|
|
} else if (command == "heater on") {
|
|
heaterRelayState = true;
|
|
digitalWrite(HEATER_RELAY_PIN, HIGH);
|
|
fanRelayState = true;
|
|
digitalWrite(FAN_RELAY_PIN, HIGH);
|
|
Serial.println("Heater relay activated. Fan ON for safety.");
|
|
} else if (command == "heater off") {
|
|
heaterRelayState = false;
|
|
digitalWrite(HEATER_RELAY_PIN, LOW);
|
|
Serial.println("Heater relay deactivated.");
|
|
} else {
|
|
Serial.println("Unknown command. Use 'fan on', 'fan off', 'heater on', or 'heater off'.");
|
|
}
|
|
}
|
|
}
|