You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.7 KiB
128 lines
3.7 KiB
#include <PID_v1.h> |
|
#include <Arduino.h> |
|
#include <ESP8266WiFi.h> |
|
#include <LittleFS.h> |
|
#include <ESPAsyncWebServer.h> |
|
#include <max6675.h> |
|
|
|
// Wifi credentials |
|
const char* ssid = "ReflowOven"; |
|
const char* password = "12345678"; |
|
AsyncWebServer server(80); |
|
AsyncWebSocket ws("/ws"); |
|
|
|
// SSR relay pin |
|
const int SSR_PIN = 5; // D1 (GPIO5) par exemple |
|
|
|
// PID variables |
|
double setpoint = 150, input = 0, output = 0; |
|
const int PWM_PERIOD = 2000; |
|
double Kp = 2, Ki = 5, Kd = 1; |
|
PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT); |
|
|
|
// Broches MAX6675 (exemple : SCK=14, CS=12, SO=13) |
|
const int thermoSO = 13; |
|
const int thermoCS = 12; |
|
const int thermoSCK = 14; |
|
MAX6675 thermocouple(thermoSCK, thermoCS, thermoSO); |
|
float lastTemp = NAN; |
|
|
|
unsigned long lastSend = 0; |
|
unsigned long pwmStart = 0; |
|
|
|
void setup() { |
|
|
|
// Action chauffe manuelle |
|
server.on("/action/preheat", HTTP_POST, [](AsyncWebServerRequest *request){ |
|
if (!request->hasArg("temp")) { |
|
request->send(400, "text/plain", "Paramètre 'temp' manquant"); |
|
return; |
|
} |
|
setpoint = request->arg("temp").toDouble(); |
|
Serial.printf("Chauffe manuelle demandée : %.1f°C (setpoint PID fixé)\n", setpoint); |
|
request->send(200, "text/plain", "OK"); |
|
}); |
|
|
|
// Action chauffe profil |
|
server.on("/action/profile", HTTP_POST, [](AsyncWebServerRequest *request){ |
|
if (!request->hasArg("profile") || !request->hasArg("preheatTemp") || !request->hasArg("preheatTime") || |
|
!request->hasArg("soakTemp") || !request->hasArg("soakTime") || |
|
!request->hasArg("reflowTemp") || !request->hasArg("reflowTime")) { |
|
request->send(400, "text/plain", "Paramètres manquants"); |
|
return; |
|
} |
|
String profile = request->arg("profile"); |
|
int preheatTemp = request->arg("preheatTemp").toInt(); |
|
int preheatTime = request->arg("preheatTime").toInt(); |
|
int soakTemp = request->arg("soakTemp").toInt(); |
|
int soakTime = request->arg("soakTime").toInt(); |
|
int reflowTemp = request->arg("reflowTemp").toInt(); |
|
int reflowTime = request->arg("reflowTime").toInt(); |
|
Serial.printf("Profil %s lancé : Preheat %d°C/%ds, Soak %d°C/%ds, Reflow %d°C/%ds\n", |
|
profile.c_str(), preheatTemp, preheatTime, soakTemp, soakTime, reflowTemp, reflowTime); |
|
request->send(200, "text/plain", "OK"); |
|
}); |
|
|
|
pinMode(SSR_PIN, OUTPUT); |
|
digitalWrite(SSR_PIN, LOW); |
|
myPID.SetMode(AUTOMATIC); |
|
myPID.SetOutputLimits(0, PWM_PERIOD); // output = ms ON sur 2s |
|
Serial.begin(115200); |
|
delay(100); |
|
|
|
// Configure ESP8266 as Access Point |
|
WiFi.mode(WIFI_AP); |
|
WiFi.softAP(ssid, password); |
|
Serial.print("AP IP address: "); |
|
Serial.println(WiFi.softAPIP()); |
|
|
|
// Initialisation LittleFS |
|
if (!LittleFS.begin()) { |
|
Serial.println("Erreur LittleFS"); |
|
return; |
|
} |
|
Serial.println("LittleFS monté"); |
|
|
|
// Route pour servir les fichiers statiques (html, js, css) |
|
server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); |
|
|
|
// WebSocket |
|
server.addHandler(&ws); |
|
|
|
// Démarrer le serveur web |
|
server.begin(); |
|
Serial.println("Serveur web démarré sur port 80"); |
|
} |
|
|
|
void loop() { |
|
|
|
ws.cleanupClients(); |
|
unsigned long now = millis(); |
|
|
|
|
|
|
|
// PID |
|
myPID.Compute(); |
|
// PWM logiciel SSR (2s) |
|
if (now - pwmStart >= PWM_PERIOD) { |
|
pwmStart = now; |
|
} |
|
if ((now - pwmStart) < (unsigned long)output) { |
|
digitalWrite(SSR_PIN, HIGH); |
|
} else { |
|
digitalWrite(SSR_PIN, LOW); |
|
} |
|
// WebSocket température (1Hz) |
|
if (now - lastSend > 1000) { |
|
lastSend = now; |
|
// Lecture température |
|
float t = thermocouple.readCelsius(); |
|
|
|
if (!isnan(t)) { |
|
input = t; |
|
} |
|
String msg = String(input, 1); |
|
Serial.println("Température: " + msg + " °C"+" | Output PID: "+ String(output)); |
|
ws.textAll(msg); |
|
} |
|
} |