#include <Wire.
h>
#include <LiquidCrystal_I2C.h>
#include <ModbusMaster.h>
#include "DHT.h"
#include <WiFi.h>
#include <WebSocketsServer.h> // WebSocket Server library
#include <WebSocketsClient.h>
// ================= WIFI CREDENTIALS =================
const char* ssid = "skit123";
const char* password = "skit@2026";
// ================= WEB SOCKET SERVER =================
WebSocketsServer webSocket = WebSocketsServer(81); // WebSocket port 81
// ================= SENSOR PINS =================
#define RE_DE 4
#define SOIL_PIN 35
#define DHTPIN 27
#define DHTTYPE DHT11
// ================= LCD =================
LiquidCrystal_I2C lcd(0x27, 16, 4);
// ================= SENSOR OBJECTS =================
DHT dht(DHTPIN, DHTTYPE);
ModbusMaster node;
// ================= SYSTEM VARIABLES =================
unsigned long lastDataSend = 0;
const long DATA_SEND_INTERVAL = 2000; // Send data every 2 seconds
// Sensor values
float temperature = 0;
float humidity = 0;
int soilMoisture = 0;
uint16_t nitrogen = 0;
uint16_t phosphorus = 0;
uint16_t potassium = 0;
bool npkAvailable = false;
// ================= MODBUS FUNCTIONS =================
void preTransmission() { digitalWrite(RE_DE, HIGH); }
void postTransmission() { digitalWrite(RE_DE, LOW); }
// ================= READ SENSORS =================
void readSensors() {
// Read DHT11
humidity = [Link]();
temperature = [Link]();
if (isnan(humidity) || isnan(temperature)) {
[Link]("⚠️DHT11 read error!");
humidity = 0;
temperature = 0;
}
// Read Soil Moisture
int soilRaw = analogRead(SOIL_PIN);
soilMoisture = map(soilRaw, 3500, 1200, 0, 100);
soilMoisture = constrain(soilMoisture, 0, 100);
// Read NPK via Modbus
uint8_t result = [Link](3, 3);
if (result == node.ku8MBSuccess) {
nitrogen = [Link](0);
phosphorus = [Link](1);
potassium = [Link](2);
npkAvailable = true;
} else {
npkAvailable = false;
[Link]("⚠️NPK Error: %d (12V needed)\n", result);
// ================= WEB SOCKET EVENT HANDLER =================
void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) {
switch (type) {
case WStype_DISCONNECTED:
[Link]("[%u] Client disconnected\n", num);
[Link](0, 2);
[Link]("Clients: 0 ");
break;
case WStype_CONNECTED:
IPAddress ip = [Link](num);
[Link]("[%u] Client connected from %d.%d.%d.%d\n", num, ip[0], ip[1], ip[2], ip[3]);
[Link](0, 2);
[Link]("Clients: ");
[Link]([Link]());
[Link](" ");
break;
case WStype_TEXT:
[Link]("[%u] Received: %s\n", num, payload);
// Handle commands from dashboard if needed
break;
// ================= SEND DATA TO ALL CLIENTS =================
void sendSensorData() {
if ([Link]() == 0) return;
// Create JSON string
String jsonData = "{";
jsonData += "\"temperature\":" + String(temperature, 1) + ",";
jsonData += "\"humidity\":" + String(humidity, 1) + ",";
jsonData += "\"soilMoisture\":" + String(soilMoisture) + ",";
jsonData += "\"npkAvailable\":" + String(npkAvailable ? "true" : "false") + ",";
jsonData += "\"nitrogen\":" + String(nitrogen) + ",";
jsonData += "\"phosphorus\":" + String(phosphorus) + ",";
jsonData += "\"potassium\":" + String(potassium) + ",";
jsonData += "\"uptime\":" + String(millis() / 1000);
jsonData += "}";
// Send to all connected clients
[Link](jsonData);
// Debug output
static int debugCount = 0;
if (debugCount++ % 10 == 0) {
[Link]("=== Data Broadcast ===");
[Link](" T: %.1f°C | 💧 H: %.1f%%\n", temperature, humidity);
[Link]("🌱 Soil: %d%%\n", soilMoisture);
[Link]("📡 Clients: %d\n", [Link]());
[Link]("======================");
// ================= UPDATE LCD DISPLAY =================
void updateLCD() {
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate < 1000) return;
lastUpdate = millis();
static int page = 0;
static unsigned long lastPageChange = 0;
if (millis() - lastPageChange > 3000) {
lastPageChange = millis();
page = (page + 1) % 2;
[Link]();
switch(page) {
case 0: // Sensor Data
[Link](0, 0);
[Link]("T:");
[Link](temperature, 1);
[Link]("C H:");
[Link](humidity, 1);
[Link]("%");
[Link](0, 1);
[Link]("Soil:");
[Link](soilMoisture);
[Link]("% ");
[Link](0, 2);
[Link]("IP:");
[Link]([Link]());
[Link](0, 3);
[Link]("Clients:");
[Link]([Link]());
[Link](" ");
break;
case 1: // NPK Data
[Link](0, 0);
[Link]("NPK VALUES");
[Link](0, 1);
if (npkAvailable) {
[Link]("N:");
[Link](nitrogen);
[Link](" P:");
[Link](phosphorus);
} else {
[Link]("NPK: No 12V!");
[Link](0, 2);
if (npkAvailable) {
[Link]("K:");
[Link](potassium);
[Link](0, 3);
if (soilMoisture < 30) {
[Link]("WATER NEEDED! ");
} else {
[Link]("STATUS: GOOD ");
break;
// ================= CONNECT TO WIFI =================
void connectToWiFi() {
[Link]("\n📡 Connecting to WiFi");
[Link](ssid, password);
int attempts = 0;
while ([Link]() != WL_CONNECTED && attempts < 20) {
delay(500);
[Link](".");
attempts++;
if ([Link]() == WL_CONNECTED) {
[Link]("\n✅ WiFi connected!");
[Link]("📱 ESP32 IP Address: ");
[Link]([Link]());
[Link]();
[Link](0, 0);
[Link]("ESP32 READY");
[Link](0, 1);
[Link]("IP:");
[Link]([Link]());
[Link](0, 2);
[Link]("Port: 81");
[Link](0, 3);
[Link]("WS Server Active");
delay(3000);
[Link]();
} else {
[Link]("\n❌ WiFi failed!");
// ================= SETUP =================
void setup() {
[Link](115200);
[Link]("\n\n==========================================");
[Link]("🌱 SMART AGRICULTURE MONITOR");
[Link]("==========================================\n");
// Initialize pins
pinMode(RE_DE, OUTPUT);
digitalWrite(RE_DE, LOW);
// Initialize LCD
[Link]();
[Link]();
[Link]();
[Link](0, 0);
[Link]("Starting...");
// Initialize sensors
[Link]();
// Initialize Modbus (NPK Sensor)
[Link](9600, SERIAL_8N1, 16, 17);
[Link](4, Serial2);
[Link](preTransmission);
[Link](postTransmission);
// Connect to WiFi
connectToWiFi();
// Start WebSocket server
[Link]();
[Link](webSocketEvent);
[Link]("\n✅ WebSocket Server Started!");
[Link]("📍 Connect to: [Link]
[Link]([Link]());
[Link](":81");
[Link]("==========================================\n");
// ================= MAIN LOOP =================
void loop() {
// Handle WebSocket connections
[Link]();
// Read sensors and send data at interval
if (millis() - lastDataSend > DATA_SEND_INTERVAL) {
lastDataSend = millis();
// Read all sensors
readSensors();
// Send data to all connected clients
sendSensorData();
// Update LCD display
updateLCD();
delay(2000);