Guys... I'm having a lot of trouble solving a problem. In this loop, I need to count the remaining time for the phase but I am not able to. In this part:
unsigned long elapsedTimeInSeconds = (targetTime - millis()) / 1000UL;
Serial.println("Time passing: ");
Serial.println(elapsedTimeInSeconds);
the return is being a big number:
4294905
I've tried everything but it doesn't work. What could be wrong?
This is the complete code:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <FS.h>
#include "secrets.h"
const char* ssid = STASSID;
const char* pass = STAPSK;
// Sensor de temperatura conectado na GPIO 4 / D2
#define ONE_WIRE_BUS 4
// Pinos do relê
#define HEATER_RELAY_PIN 5
#define COOLER_RELAY_PIN 4
// Hysteresis da temperatura
#define HYSTERESIS 0.4
// Web server
ESP8266WebServer server(80);
// Sensor de temperatura
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Temperaturas e tempos
struct TemperatureData {
float temperature;
unsigned long time;
};
const int MAX_TEMPERATURES = 15; // Limite de 15 passos
TemperatureData temperatureData[MAX_TEMPERATURES];
int numTemperatures = 0;
int currentTemperatureIndex = 0;
bool fermentationStarted = false;
unsigned long targetTime;
unsigned long remainingTime;
unsigned long elapsedTime;
// Helper function to convert float to string with given precision
String floatToString(float value, int precision) {
char buffer[20];
sprintf(buffer, "%.*f", precision, value);
return String(buffer);
}
// Load temperature data from file
void loadTemperatureData() {
if (SPIFFS.begin()) {
if (SPIFFS.exists("/temperatures.txt")) {
File file = SPIFFS.open("/temperatures.txt", "r");
if (file) {
numTemperatures = 0;
while (file.available() && numTemperatures < MAX_TEMPERATURES) {
String line = file.readStringUntil('\n');
int separatorIndex = line.indexOf(',');
if (separatorIndex != -1) {
temperatureData[numTemperatures].temperature = line.substring(0, separatorIndex).toFloat();
temperatureData[numTemperatures].time = line.substring(separatorIndex + 1).toInt();
numTemperatures++;
}
}
file.close();
}
}
SPIFFS.end();
}
}
// Save temperature data to file
void saveTemperatureData() {
if (SPIFFS.begin()) {
File file = SPIFFS.open("/temperatures.txt", "w");
if (file) {
for (int i = 0; i < numTemperatures; i++) {
file.println(floatToString(temperatureData[i].temperature, 2) + "," + String(temperatureData[i].time));
}
file.close();
}
SPIFFS.end();
}
}
// Script da página html
void handleRootPage() {
String html = "<html><head><title>Controle de Temperatura</title></head><body>";
html += "<h1>Controle de Temperatura</h1>";
html += "<h2>Temperaturas Cadastradas:</h2>";
html += "<ul>";
for (int i = 0; i < numTemperatures; i++) {
html += "<li>";
html += "Temperatura: " + floatToString(temperatureData[i].temperature, 2) + " °C, ";
html += "Tempo: " + String(temperatureData[i].time) + " segundos";
html += " [<a href='/delete?index=" + String(i) + "'>Deletar</a>]";
html += "</li>";
}
html += "</ul>";
html += "<p>Temperatura Atual: <span id='current-temp'></span> °C</p>";
html += "<p>Temperatura Alvo: <span id='target-temp'></span> °C</p>";
html += "<p>Tempo na Temperatura Alvo: <span id='targetTime'>" + String(targetTime) + "</span> segundos</p>";
html += "<p>Tempo Restante para a próxima etapa: <span id='remaining-time'></span> segundos</p>";
// Adicione o botão de iniciar
html += "<h2>Iniciar Controle de Temperatura:</h2>";
html += "<form action='/start' method='POST'>";
html += "<input type='submit' value='Iniciar' onclick='startTemperatureControl(event)'>";
html += "</form>";
html += "<script>";
html += "function startTemperatureControl(event) {";
html += " event.preventDefault();";
html += " var xhr = new XMLHttpRequest();";
html += " xhr.open('GET', '/start', true);";
html += " xhr.send();";
html += "}";
html += "setInterval(function() {";
html += " var currentTemp = document.getElementById('current-temp');";
html += " var targetTemp = document.getElementById('target-temp');";
html += " var remainingTime = document.getElementById('remaining-time');";
html += " var targetTime = document.getElementById('targetTime');";
html += " var xhr = new XMLHttpRequest();";
html += " xhr.onreadystatechange = function() {";
html += " if (xhr.readyState === 4 && xhr.status === 200) {";
html += " var data = JSON.parse(xhr.responseText);";
html += " currentTemp.innerText = data.currentTemperature.toFixed(2);";
html += " targetTemp.innerText = data.targetTemperature.toFixed(2);";
html += " remainingTime.innerText = data.remainingTime;";
html += " targetTime.innerText = data.targetTime;";
html += " }";
html += " };";
html += " xhr.open('GET', '/temperature', true);";
html += " xhr.send();";
html += "}, 1000);";
html += "</script>";
html += "</body></html>";
server.send(200, "text/html", html);
}
// Script para adicionar nova temperatura/tempo
void handleAddTemperature() {
float temperature = server.arg("temperature").toFloat();
unsigned long time = server.arg("time").toInt();
if (numTemperatures < MAX_TEMPERATURES) {
temperatureData[numTemperatures].temperature = temperature;
temperatureData[numTemperatures].time = time;
numTemperatures++;
saveTemperatureData();
}
server.sendHeader("Location", "/");
server.send(303);
}
// Script para deletar temperature/tempo
void handleDeleteTemperature() {
int index = server.arg("index").toInt();
if (index >= 0 && index < numTemperatures) {
for (int i = index; i < numTemperatures - 1; i++) {
temperatureData[i] = temperatureData[i + 1];
}
numTemperatures--;
saveTemperatureData();
}
server.sendHeader("Location", "/");
server.send(303);
}
// Leitura da temperatura do sensor DS18B20
float readTemperature() {
sensors.requestTemperatures();
return sensors.getTempCByIndex(0);
}
// Initialização dos relays
void initializeRelays() {
pinMode(HEATER_RELAY_PIN, OUTPUT);
digitalWrite(HEATER_RELAY_PIN, LOW);
pinMode(COOLER_RELAY_PIN, OUTPUT);
digitalWrite(COOLER_RELAY_PIN, LOW);
}
// Controle dos relays basedo na temperatura corrente e temperatura alvo
void controlRelays(float currentTemperature, float targetTemperature) {
static unsigned long lastCoolerOffTime = 0;
bool heaterState = digitalRead(HEATER_RELAY_PIN);
bool coolerState = digitalRead(COOLER_RELAY_PIN);
if (currentTemperature < targetTemperature - HYSTERESIS) {
digitalWrite(HEATER_RELAY_PIN, HIGH);
heaterState = true;
Serial.println("Aquecedor ligado");
Serial.println("Temperatura alvo: ");
Serial.println(targetTemperature);
Serial.println("Tempo alvo: ");
Serial.println(targetTime);
} else if (currentTemperature > targetTemperature + HYSTERESIS) {
if (!coolerState && millis() - lastCoolerOffTime >= 5 * 60 * 1000) {
digitalWrite(COOLER_RELAY_PIN, HIGH);
Serial.println("Geladeira ligada");
coolerState = true;
}
}
if (targetTemperature - HYSTERESIS <= currentTemperature && currentTemperature <= targetTemperature + HYSTERESIS && coolerState) {
digitalWrite(COOLER_RELAY_PIN, LOW);
Serial.println("Geladeira desligada");
coolerState = false;
lastCoolerOffTime = millis();
}
if (targetTemperature - HYSTERESIS <= currentTemperature && currentTemperature <= targetTemperature + HYSTERESIS && heaterState) {
digitalWrite(HEATER_RELAY_PIN, LOW);
Serial.println("Aquecedor desligado");
heaterState = false;
}
}
// Verifica se o processo de fermentatação está completo
bool isFermentationComplete() {
return currentTemperatureIndex == numTemperatures;
}
// Recebe o comando para iniciar a fermentação alterando para true, que vai ser lido no loop
void handleStartTemperatureControl() {
fermentationStarted = true;
server.send(200, "text/plain", "Fermentação Iniciada");
}
// Envia para html indicação de fermentação completa
void handleFermentationComplete() {
String html = "<html><head><title>Fermentação Concluída</title></head><body>";
html += "<h1>Fermentação Concluída!</h1>";
html += "<p>A fermentação atingiu todas as temperaturas alvo.</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}
// Script de envio de dados de temperatura/tempo para o html
void handleTemperatureData() {
float currentTemperature = readTemperature();
float targetTemperature = temperatureData[currentTemperatureIndex].temperature;
targetTime = temperatureData[currentTemperatureIndex].time;
elapsedTime = millis() / 1000 - temperatureData[currentTemperatureIndex].time;
// remainingTime = (temperatureData[currentTemperatureIndex].time > elapsedTime) ? temperatureData[currentTemperatureIndex].time - elapsedTime : 0;
// Create JSON response
String jsonResponse = "{";
jsonResponse += "\"currentTemperature\": " + floatToString(currentTemperature, 2) + ",";
jsonResponse += "\"targetTemperature\": " + floatToString(targetTemperature, 2) + ",";
jsonResponse += "\"remainingTime\": " + String(remainingTime) + ",";
jsonResponse += "\"targetTime\": " + String(targetTime);
jsonResponse += "}";
server.send(200, "application/json", jsonResponse);
}
void setup() {
Serial.begin(115200);
// Connecta ao Wi-Fi
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Inicia o servidor web
server.on("/", handleRootPage);
server.on("/add", handleAddTemperature);
server.on("/delete", handleDeleteTemperature);
server.on("/temperature", handleTemperatureData);
server.on("/start", handleStartTemperatureControl);
server.begin();
// Inicializa o sensor de temperatura
sensors.begin();
// Lê o arquivo de temperatura/tempo
loadTemperatureData();
// Inicializa os relays
initializeRelays();
// Seta o currentTemperatureIndex para 0 inicialmente
currentTemperatureIndex = 0;
}
void loop() {
server.handleClient();
// Lê a temperatura atual
float currentTemperature = readTemperature();
// Controla o início e término da fermentação
if (isFermentationComplete()) {
handleFermentationComplete();
} else if (fermentationStarted && currentTemperatureIndex < numTemperatures) {
float targetTemperature = temperatureData[currentTemperatureIndex].temperature;
controlRelays(currentTemperature, targetTemperature);
if (currentTemperature >= targetTemperature - HYSTERESIS && currentTemperature <= targetTemperature + HYSTERESIS) {
Serial.println("Temperatura alvo atingida! Início da contagem do tempo!");
unsigned long elapsedTimeInSeconds = (targetTime - millis()) / 1000UL;
Serial.println("Time passing: ");
Serial.println(elapsedTimeInSeconds);
if (elapsedTimeInSeconds <= 0) {
Serial.println("Tempo no alvo alcançado. Passando para a próxima etapa!");
currentTemperatureIndex++;
}
}
}
}