Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

NodeMCU ESP8266 Water Monitoring System with Ultrasonic Sensor and OLED Display

View and Edit Project In Cirkit DesignerImage of NodeMCU ESP8266 Water Monitoring System with Ultrasonic Sensor and OLED Display

Circuit Documentation

Summary

The circuit in question is designed to monitor water levels and flow rates using a NodeMCU V3 ESP8266 microcontroller as the central processing unit. The circuit includes an HC-SR04 Ultrasonic Sensor for measuring water levels, a water flow sensor for monitoring flow rates, a 0.96" OLED display for data output, and a 9V battery for power supply. The NodeMCU V3 ESP8266 is programmed to calculate and display the water level and flow rate on the OLED screen.

Component List

NodeMCU V3 ESP8266

HC-SR04 Ultrasonic Sensor

Water Flow Sensor

9V Battery

0.96" OLED

Wiring Details

NodeMCU V3 ESP8266

HC-SR04 Ultrasonic Sensor

Water Flow Sensor

9V Battery

0.96" OLED

Documented Code

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Pin definitions for NodeMCU (ESP8266)
#define TRIG_PIN 14  // GPIO14 (D5)
#define ECHO_PIN 12  // GPIO12 (D6)
#define FLOW_SENSOR_PIN 13  // GPIO13 (D7)
#define SDA_PIN 4  // GPIO4 (D2)
#define SCL_PIN 5  // GPIO5 (D1)

// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Constants
const int tankHeight = 100;  // Height of the tank in cm
const float calibrationFactor = 4.5; // Calibration factor for YF-S201 water flow sensor

// Variables
volatile int pulseCount = 0;
unsigned long previousMillis = 0;
const long interval = 1000; // Interval for flow rate calculation (1 second)

// Function to measure distance using Ultrasonic Sensor
long getDistance() {
  // Clear the TRIG pin
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);

  // Trigger the TRIG pin
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Read the ECHO pin, measure the time it takes for the echo
  long duration = pulseIn(ECHO_PIN, HIGH);

  // Calculate distance in cm
  long distance = (duration * 0.034) / 2;
  return distance;
}

// Function to calculate water level
long getWaterLevel() {
  long distance = getDistance();
  long waterLevel = tankHeight - distance;
  return max((long)0, waterLevel); // Ensure water level is non-negative by casting to long
}

// Interrupt function to count pulses from water flow sensor
void pulseCounter() {
  pulseCount++;
}

// Function to calculate flow rate (in L/min)
float getFlowRate() {
  float flowRate = (pulseCount / calibrationFactor);
  pulseCount = 0;  // Reset pulse count for next measurement
  return flowRate;
}

// Function to display data on OLED
void displayData(long waterLevel, float flowRate) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  
  display.setCursor(0, 0);
  display.print("Water Level: ");
  display.print(waterLevel);
  display.println(" cm");

  display.setCursor(0, 16);
  display.print("Flow Rate: ");
  display.print(flowRate);
  display.println(" L/min");

  display.display(); // Update OLED display
}

void setup() {
  // Initialize serial communication
  Serial.begin(115200);

  // Initialize pins
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(FLOW_SENSOR_PIN, INPUT);

  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  // Display a startup message
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Starting Water Monitoring");
  display.display();
  delay(2000);

  // Attach interrupt to the flow sensor pin to count pulses
  attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), pulseCounter, FALLING);
}

void loop() {
  // Calculate water level
  long waterLevel = getWaterLevel();

  // Calculate flow rate every second
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    float flowRate = getFlowRate();

    // Display data on the OLED screen
    displayData(waterLevel, flowRate);
  }

  delay(1000); // Delay before the next loop
}

This code is designed to run on the NodeMCU V3 ESP8266 microcontroller. It initializes the HC-SR04 Ultrasonic Sensor and the water flow sensor, calculates the water level and flow rate, and displays the data on the 0.96" OLED screen. The code includes functions for measuring distance, calculating water level, counting pulses from the water flow sensor, calculating flow rate, and displaying data. It also sets up the necessary pins and interrupts for the sensors and the OLED display.