opencure/opncure.ino
2024-06-28 01:01:44 +08:00

292 lines
7.5 KiB
C++

#include <ESP8266WiFi.h>
#include <FS.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <ESP8266WebServer.h>
#define DHT_PIN 11
#define MOSFET_HEATING_PIN 13
#define MOSFET_COOLING_PIN 14
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);
LiquidCrystal_I2C lcd(0x27, 20, 4);
ESP8266WebServer server(80);
const char* ssid = "OpenCure";
const char* password = "12345678";
enum Mode { OFF, TIME_MODE, HOLD_MODE, CURVE_MODE };
Mode currentMode = OFF;
float targetTemperature = 25.0;
unsigned long startTime = 0;
unsigned long duration = 0;
float fridgeTemp = 0.0;
bool heatingActive = false;
bool coolingActive = false;
void setup() {
Serial.begin(115200);
pinMode(MOSFET_HEATING_PIN, OUTPUT);
pinMode(MOSFET_COOLING_PIN, OUTPUT);
analogWriteRange(255); // Set PWM range to 0-255
analogWriteFreq(20000); // Set PWM frequency to 20 kHz
dht.begin();
lcd.begin(20,4);
lcd.backlight();
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
WiFi.softAP(ssid, password);
server.on("/", handleRoot);
server.on("/bootstrap.min.css", []() {
serveFile("/bootstrap.min.css", "text/css");
});
server.on("/bootstrap.min.js", []() {
serveFile("/bootstrap.min.js", "application/javascript");
});
server.on("/jquery.min.js", []() {
serveFile("/jquery.min.js", "application/javascript");
});
server.on("/setTemperature", handleSetTemperature);
server.on("/setMode", handleSetMode);
server.begin();
Serial.println("HTTP server started");
lcd.setCursor(0, 0);
lcd.print("ESP8266 Peltier Fridge");
delay(2000);
}
void loop() {
server.handleClient();
updateSensors();
controlPeltier();
updateLCD();
switch (currentMode) {
case TIME_MODE:
timeMode();
break;
case HOLD_MODE:
holdMode();
break;
case CURVE_MODE:
curveMode();
break;
case OFF:
disablePeltier();
break;
}
}
void updateSensors() {
fridgeTemp = dht.readTemperature();
Serial.printf("Fridge Temp: %.1f C\n", fridgeTemp);
}
void controlHeating(int dutyCycle) {
analogWrite(MOSFET_COOLING_PIN, 0); // Ensure cooling is off
analogWrite(MOSFET_HEATING_PIN, dutyCycle);
heatingActive = true;
coolingActive = false;
}
void controlCooling(int dutyCycle) {
analogWrite(MOSFET_HEATING_PIN, 0); // Ensure heating is off
analogWrite(MOSFET_COOLING_PIN, dutyCycle);
coolingActive = true;
heatingActive = false;
}
void disablePeltier() {
analogWrite(MOSFET_HEATING_PIN, 0);
analogWrite(MOSFET_COOLING_PIN, 0);
heatingActive = false;
coolingActive = false;
}
void controlPeltier() {
if (currentMode == OFF) {
disablePeltier();
return;
}
if (targetTemperature < 25) {
if (fridgeTemp > targetTemperature) {
int dutyCycle = map(fridgeTemp - targetTemperature, 0, 10, 0, 255);
controlCooling(dutyCycle);
} else {
disablePeltier();
}
} else if (targetTemperature > 25) {
if (fridgeTemp < targetTemperature) {
int dutyCycle = map(targetTemperature - fridgeTemp, 0, 10, 0, 255);
controlHeating(dutyCycle);
} else {
disablePeltier();
}
} else {
disablePeltier();
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Target Temp: ");
lcd.print(targetTemperature, 1);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Fridge Temp: ");
lcd.print(fridgeTemp, 1);
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Mode: ");
switch (currentMode) {
case TIME_MODE:
lcd.print("Time Mode");
break;
case HOLD_MODE:
lcd.print("Hold Mode");
break;
case CURVE_MODE:
lcd.print("Curve Mode");
break;
case OFF:
lcd.print("Off");
break;
}
}
void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>OpenCure</title>
<link rel="stylesheet" href="/bootstrap.min.css">
<script src="/jquery.min.js"></script>
<script src="/bootstrap.min.js"></script>
<script>
function setTemperature() {
var temp = document.getElementById('temperature').value;
$.get("/setTemperature?temp=" + temp, function(data) {
alert(data);
});
}
function setMode(mode) {
var duration = 0;
if (mode === 'time' || mode === 'curve') {
var hours = parseInt(document.getElementById('hours').value);
var minutes = parseInt(document.getElementById('minutes').value);
duration = (hours * 60 + minutes) * 60;
}
$.get("/setMode?mode=" + mode + "&duration=" + duration, function(data) {
alert(data);
});
}
</script>
</head>
<body>
<div class="container">
<h1>OpenCure</h1>
<div class="form-group">
<label for="temperature">Set Temperature (°C):</label>
<input type="number" class="form-control" id="temperature" placeholder="Enter temperature">
<button class="btn btn-primary mt-2" onclick="setTemperature()">Set Temperature</button>
</div>
<div class="form-group">
<label for="mode">Select Mode:</label>
<select class="form-control" id="mode">
<option value="off">Off</option>
<option value="time">Time Mode</option>
<option value="hold">Hold Mode</option>
<option value="curve">Curve Mode</option>
</select>
</div>
<div class="form-group" id="time-settings" style="display: none;">
<label for="hours">Hours:</label>
<input type="number" class="form-control" id="hours" placeholder="Enter hours">
<label for="minutes">Minutes:</label>
<input type="number" class="form-control" id="minutes" placeholder="Enter minutes">
</div>
<button class="btn btn-primary mt-2" onclick="setMode(document.getElementById('mode').value)">Set Mode</button>
<script>
document.getElementById('mode').addEventListener('change', function () {
var mode = this.value;
if (mode === 'time' || mode === 'curve') {
document.getElementById('time-settings').style.display = 'block';
} else {
document.getElementById('time-settings').style.display = 'none';
}
});
</script>
</div>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}
void handleSetTemperature() {
if (server.hasArg("temp")) {
targetTemperature = server.arg("temp").toFloat();
server.send(200, "text/plain", "Temperature Set");
} else {
server.send(400, "text/plain", "Bad Request");
}
}
void handleSetMode() {
if (server.hasArg("mode")) {
String mode = server.arg("mode");
if (mode == "time") {
currentMode = TIME_MODE;
startTime = millis();
if (server.hasArg("duration")) {
duration = server.arg("duration").toInt();
}
} else if (mode == "hold") {
currentMode = HOLD_MODE;
} else if (mode == "curve") {
currentMode = CURVE_MODE;
startTime = millis();
if (server.hasArg("duration")) {
duration = server.arg("duration").toInt();
}
} else {
currentMode = OFF;
}
server.send(200, "text/plain", "Mode Set");
} else {
server.send(400, "text/plain", "Bad Request");
}
}
void serveFile(const char* path, const char* mimeType) {
File file = SPIFFS.open(path, "r");
if (file) {
server.streamFile(file, mimeType);
file.close();
} else {
server.send(404, "text/plain", "File Not Found");
}
}