#include <WiFi.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const char* FW_VERSION = "1.0";
const char* VERSION_URL = "https://raw.githubusercontent.com/DannelsCS/firmware-motiva/main/version.json";
#define LED_RED_PIN 25
#define LED_GREEN_PIN 26
#define LED_BLUE_PIN 27
const unsigned long READING_INTERVAL = 2000;
const unsigned long SESSION_INTERVAL = 48000;
const int READINGS_PER_SESSION = 5;
const int MIN_SESSIONS_BEFORE_OTA = 3;
float readings[READINGS_PER_SESSION];
int readingIndex = 0;
unsigned long sessionStartTime = 0;
int sessionCount = 0;
bool sessionActive = false;
bool otaAttempted = false;
void setup() {
Serial.begin(115200);
delay(500);
pinMode(LED_RED_PIN, OUTPUT);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(LED_BLUE_PIN, OUTPUT);
setLEDBlue();
randomSeed(analogRead(0));
Serial.println("========================================");
Serial.println("MONITORAMENTO DE VEGETACAO - FW 1.0");
Serial.println("========================================");
connectWiFi();
startNewSession();
}
void loop() {
unsigned long now = millis();
if (sessionActive) {
unsigned long nextReadingTime = sessionStartTime + ((unsigned long)readingIndex * READING_INTERVAL);
if (readingIndex < READINGS_PER_SESSION && now >= nextReadingTime) {
takeReading();
}
if (readingIndex >= READINGS_PER_SESSION) {
finishSession();
}
} else {
unsigned long nextSessionTime = sessionStartTime + SESSION_INTERVAL;
if (now >= nextSessionTime) {
startNewSession();
}
}
}
void startNewSession() {
sessionStartTime = millis();
readingIndex = 0;
sessionActive = true;
sessionCount++;
Serial.println();
Serial.print("--- Sessao ");
Serial.print(sessionCount);
Serial.println(" ---");
}
void takeReading() {
float value = random(1000, 2001) / 100.0;
readings[readingIndex] = value;
Serial.print("Leitura ");
Serial.print(readingIndex + 1);
Serial.print(": ");
Serial.print(value, 1);
Serial.println(" cm");
readingIndex++;
}
void finishSession() {
float sum = 0;
for (int i = 0; i < READINGS_PER_SESSION; i++) {
sum += readings[i];
}
float average = sum / READINGS_PER_SESSION;
Serial.print("Media da sessao: ");
Serial.print(average, 1);
Serial.println(" cm");
Serial.println("Proxima sessao em 48 segundos.");
sessionActive = false;
if (sessionCount >= MIN_SESSIONS_BEFORE_OTA) {
checkForUpdate();
}
}
void connectWiFi() {
Serial.print("Conectando ao Wi-Fi");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Wi-Fi conectado. IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("[ERRO] Nao foi possivel conectar ao Wi-Fi.");
}
}
void checkForUpdate() {
if (otaAttempted) return;
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[OTA] Sem conexao Wi-Fi. Nao e possivel verificar atualizacoes.");
return;
}
Serial.println("[OTA] Consultando manifesto de versao...");
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
http.begin(client, VERSION_URL);
int httpCode = http.GET();
if (httpCode != 200) {
Serial.print("[OTA] Falha ao acessar o manifesto. Codigo HTTP: ");
Serial.println(httpCode);
http.end();
return;
}
String payload = http.getString();
http.end();
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println("[OTA] Erro ao interpretar version.json.");
return;
}
String remoteVersion = doc["version"].as<String>();
String binUrl = doc["url"].as<String>();
Serial.print("[OTA] Versao instalada: ");
Serial.println(FW_VERSION);
Serial.print("[OTA] Versao disponivel: ");
Serial.println(remoteVersion);
if (remoteVersion == String(FW_VERSION)) {
Serial.println("[OTA] Ja esta na versao mais recente.");
return;
}
if (binUrl.length() == 0) {
Serial.println("[OTA] Manifesto sem URL de firmware valida.");
return;
}
Serial.println("[OTA] Nova versao encontrada. Baixando e atualizando...");
otaAttempted = true;
WiFiClientSecure otaClient;
otaClient.setInsecure();
t_httpUpdate_return result = httpUpdate.update(otaClient, binUrl);
switch (result) {
case HTTP_UPDATE_FAILED:
Serial.printf("[OTA] Falha na atualizacao. Erro (%d): %s\n",
httpUpdate.getLastError(),
httpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("[OTA] Nenhuma atualizacao necessaria.");
break;
case HTTP_UPDATE_OK:
Serial.println("[OTA] Atualizacao concluida. Reiniciando...");
break;
}
}
void setLEDBlue() {
digitalWrite(LED_RED_PIN, LOW);
digitalWrite(LED_GREEN_PIN, LOW);
digitalWrite(LED_BLUE_PIN, HIGH);
}