#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "LittleFS.h"
#include "connect.h"
// MQTT Topic
const char* topic = "water/quality";
// Temperature Sensor (DS18B20)
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Analog Pins (Wired to Potentiometers in Wokwi)
#define PH_PIN 34
#define TURBIDITY_PIN 35
#define TDS_PIN 32
// Using standard WiFiClient for port 1883 browser simulation
WiFiClient espClient;
PubSubClient client(espClient);
// Timing
unsigned long lastMsg = 0;
const long interval = 10000; // 5 seconds
// ==========================================
// SETUP WIFI
// ==========================================
void setup_wifi() {
delay(10);
Serial.println("Connecting to WiFi...");
WiFi.begin(esp_SSID, esp_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
// ==========================================
// RECONNECT MQTT
// ==========================================
void reconnectMQTT() {
while (!client.connected()) {
Serial.print("Connecting MQTT...");
// Randomized Client ID to prevent MQTT Explorer collisions
String clientId = "Aqua";
clientId += String(random(0, 100));
if (client.connect(clientId.c_str())) {
Serial.println("MQTT Connected");
replayBufferedData();
} else {
Serial.print("Failed MQTT: ");
Serial.println(client.state());
delay(20000);
}
}
}
// ==========================================
// SAVE TO LITTLEFS
// ==========================================
void saveToBuffer(String payload) {
File file = LittleFS.open("/buffer.txt", FILE_APPEND);
if (!file) {
Serial.println("โ Failed to open buffer file");
return;
}
file.println(payload);
file.close();
Serial.println("๐ Data buffered locally");
}
// ==========================================
// REPLAY BUFFERED DATA
// ==========================================
void replayBufferedData() {
File file = LittleFS.open("/buffer.txt", FILE_READ);
if (!file || file.size() == 0) {
Serial.println("โ
No buffered data to replay");
return;
}
Serial.println("๐ Replaying buffered data...");
while (file.available()) {
String line = file.readStringUntil('\n');
line.trim();
if (line.length() > 0) {
bool success = client.publish(topic, line.c_str());
if (success) {
Serial.println("โ
Replayed: " + line);
} else {
Serial.println("โ Replay failed");
break;
}
delay(300);
}
}
file.close();
LittleFS.remove("/buffer.txt");
Serial.println("๐งน Buffer cleared");
}
// ==========================================
// SIMPLIFIED SENSOR FUNCTIONS (SILENT)
// ==========================================
float readPH() {
int raw = analogRead(PH_PIN);
return (raw / 4095.0) * 14.0;
}
float readTurbidity() {
int raw = analogRead(TURBIDITY_PIN);
return (raw / 4095.0) * 29.0 + 1.0;
}
float readTDS(float temperature) {
int raw = analogRead(TDS_PIN);
return (raw / 4095.0) * 1000.0;
}
// ==========================================
// SETUP
// ==========================================
void setup() {
Serial.begin(115200);
if (!LittleFS.begin(true)) {
Serial.println("โ LittleFS Mount Failed - Proceeding without offline buffer");
} else {
Serial.println("โ
LittleFS Ready");
}
setup_wifi();
client.setServer(mqtt_SERVER, 1883);
client.setBufferSize(1024);
sensors.begin();
}
// ==========================================
// MAIN LOOP
// ==========================================
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("โ WiFi Lost");
setup_wifi();
}
if (!client.connected()) {
reconnectMQTT();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > interval) {
lastMsg = now;
// Read Sensors silently
sensors.requestTemperatures();
float temperature = sensors.getTempCByIndex(0);
float ph = readPH();
float turbidity = readTurbidity();
float tds = readTDS(temperature);
// Create JSON Payload
String payload = "{";
payload += "\"ph\":" + String(ph, 2) + ",";
payload += "\"temperature\":" + String(temperature, 2) + ",";
payload += "\"tds\":" + String(tds, 2) + ",";
payload += "\"turbidity\":" + String(turbidity, 2);
payload += "}";
// Publish and Print Result
bool success = client.publish(topic, payload.c_str());
if (!success) {
Serial.println("โ MQTT Publish Failed");
saveToBuffer(payload);
} else {
Serial.println("โ
MQTT Published: " + payload);
}
}
}