#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <math.h>
/* ================= PIN ================= */
#define DHT_PIN 4
#define NTC_PIN 35
#define POT_PIN 34
#define LED_RED 13
#define LED_GREEN 12
#define LED_BLUE 14
#define LED_WHITE 27
#define DHTTYPE DHT22
/* ================= WIFI & MQTT ================= */
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "broker.hivemq.com";
const int mqttPort = 1883;
const char* mqttTopic = "ridhoarya/esp32/ifl/sensor";
/* ================= OBJECT ================= */
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHT_PIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
/* ================= NTC PARAM ================= */
const float SERIES_RESISTOR = 10000.0;
const float THERMISTOR_NOMINAL = 10000.0;
const float TEMPERATURE_NOMINAL = 25.0;
const float B_COEFFICIENT = 3950.0;
/* ================= NOISE PARAM ================= */
const float NOISE_DHT_TEMP = 0.5;
const float NOISE_DHT_HUM = 2.0;
const float NOISE_NTC = 0.8;
const int NOISE_POT = 50;
/* ================= GLOBAL DATA ================= */
float temp_dht, hum, temp_ntc;
float temp_dht_n, hum_n, temp_ntc_n;
int pot, pot_n;
unsigned long lastUpdate = 0;
const unsigned long interval = 2000;
/* ================= IFL STRUCT ================= */
struct IFL {
float mu;
float nu;
float pi;
};
/* ================= NOISE ================= */
float gaussianNoise(float v, float n) {
float u1 = random(1, 10000) / 10000.0;
float u2 = random(1, 10000) / 10000.0;
float z = sqrt(-2 * log(u1)) * cos(2 * PI * u2);
return v + z * n;
}
int uniformNoise(int v, int n) {
return constrain(v + random(-n, n + 1), 0, 4095);
}
/* ================= IFL TEMPERATURE ================= */
IFL iflCold(float t) {
IFL f;
if (t <= 15) { f.mu = 1; f.nu = 0; }
else if (t < 25) { f.mu = (25 - t) / 10; f.nu = (t - 15) / 10; }
else { f.mu = 0; f.nu = 1; }
f.pi = 0.1;
float s = f.mu + f.nu + f.pi;
f.mu /= s; f.nu /= s; f.pi /= s;
return f;
}
IFL iflNormal(float t) {
IFL f;
if (t <= 15 || t >= 35) { f.mu = 0; f.nu = 1; }
else if (t < 25) { f.mu = (t - 15) / 10; f.nu = (25 - t) / 10; }
else { f.mu = (35 - t) / 10; f.nu = (t - 25) / 10; }
f.pi = 0.1;
float s = f.mu + f.nu + f.pi;
f.mu /= s; f.nu /= s; f.pi /= s;
return f;
}
IFL iflHot(float t) {
IFL f;
if (t <= 25) { f.mu = 0; f.nu = 1; }
else if (t < 35) { f.mu = (t - 25) / 10; f.nu = (35 - t) / 10; }
else { f.mu = 1; f.nu = 0; }
f.pi = 0.1;
float s = f.mu + f.nu + f.pi;
f.mu /= s; f.nu /= s; f.pi /= s;
return f;
}
/* ================= LED IFL (INDIKATOR SENSOR) ================= */
int ledRedIFL() {
IFL c = iflCold(temp_dht_n);
IFL n = iflNormal(temp_dht_n);
IFL h = iflHot(temp_dht_n);
float out =
c.mu * 255 * (1 - c.pi) +
n.mu * 100 * (1 - n.pi) +
h.mu * 0 * (1 - h.pi);
return constrain(out, 0, 255);
}
int ledGreenIFL() {
return constrain(map(hum_n, 0, 100, 0, 255), 0, 255);
}
int ledBlueIFL() {
return constrain(map(temp_ntc_n, 0, 50, 255, 0), 0, 255);
}
int ledWhiteIFL() {
return constrain(map(pot_n, 0, 4095, 0, 255), 0, 255);
}
/* ================= SENSOR ================= */
void readSensors() {
hum = dht.readHumidity();
temp_dht = dht.readTemperature();
int adc = analogRead(NTC_PIN);
float r = SERIES_RESISTOR / ((4095.0 / adc) - 1.0);
float s = log(r / THERMISTOR_NOMINAL);
s = 1.0 / (s / B_COEFFICIENT + 1.0 / (TEMPERATURE_NOMINAL + 273.15)) - 273.15;
temp_ntc = s;
pot = analogRead(POT_PIN);
temp_dht_n = gaussianNoise(temp_dht, NOISE_DHT_TEMP);
hum_n = constrain(gaussianNoise(hum, NOISE_DHT_HUM), 0, 100);
temp_ntc_n = gaussianNoise(temp_ntc, NOISE_NTC);
pot_n = uniformNoise(pot, NOISE_POT);
}
/* ================= MQTT ================= */
void connectMQTT() {
while (!client.connected()) {
if (client.connect("ESP32-IFL-SENSOR")) {
Serial.println("MQTT Connected");
} else {
delay(2000);
}
}
}
/* ================= SETUP ================= */
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_WHITE, OUTPUT);
dht.begin();
randomSeed(analogRead(0));
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer(mqttServer, mqttPort);
connectMQTT();
lcd.setCursor(0, 0);
lcd.print("IFL SENSOR READY");
}
/* ================= LOOP ================= */
void loop() {
if (!client.connected()) connectMQTT();
client.loop();
if (millis() - lastUpdate >= interval) {
lastUpdate = millis();
readSensors();
analogWrite(LED_RED, ledRedIFL());
analogWrite(LED_GREEN, ledGreenIFL());
analogWrite(LED_BLUE, ledBlueIFL());
analogWrite(LED_WHITE, ledWhiteIFL());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp_dht_n, 1);
lcd.print(" H:");
lcd.print(hum_n, 0);
lcd.setCursor(0, 1);
lcd.print("N:");
lcd.print(temp_ntc_n, 1);
lcd.print(" P:");
lcd.print(map(pot_n, 0, 4095, 0, 100));
char payload[200];
snprintf(payload, sizeof(payload),
"{\"node\":\"sensor\",\"temp\":%.2f,\"hum\":%.2f,\"ntc\":%.2f,\"pot\":%d}",
temp_dht_n, hum_n, temp_ntc_n, map(pot_n, 0, 4095, 0, 100));
client.publish(mqttTopic, payload, true);
Serial.println(payload);
}
}