Ultimate Garden Automation System — Esp32 Devkit C V4 simulation

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by tareq-neoaz.

Components

Sketch code

#include <Wire.h>
#include <SPI.h>
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h> 
#include <DHT.h>
#include <Adafruit_ADS1X15.h>

// --- E-PAPER ---
GxEPD2_BW<GxEPD2_290_T94, GxEPD2_290_T94::HEIGHT> display(
  GxEPD2_290_T94(/*CS=*/5, /*DC=*/17, /*RST=*/16, /*BUSY=*/4));

// --- DHT ---
#define DHT_PIN 33
DHT dht(DHT_PIN, DHT22);

// --- ADC ---
Adafruit_ADS1115 ads1; 

// --- PINS (ONLY TRUE ANALOG PINS) ---
const int espPins[4] = {35, 36, 39, 34}; 
const int numPlants = 8;
bool plantIsDry[numPlants];

// --- THRESHOLDS ---
int adcStartThreshold = 13000; 
int espStartThreshold = 100;  // Lowered to 100 for Velxio sensitivity
int adcStopThreshold = 7800;
int espStopThreshold = 80;    // Lowered to 80

#define PUMP_PIN 13
#define LED_PIN 14

bool isPumping = false;
unsigned long pumpStartTime = 0;
const unsigned long maxPumpTime = 15000; 

void setup() {
  Serial.begin(115200);
  
  SPI.begin(18, 19, 23, 5); 
  Wire.begin(21, 22);
  delay(500);
  
  display.init(115200, true, 50, false);
  display.setRotation(1);
  display.setFullWindow();
  
  if (!ads1.begin(0x48)) {
    Serial.println("ADC not found!");
  }
  ads1.setGain(GAIN_ONE);
  
  dht.begin();
  pinMode(PUMP_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  
  updateDisplay();
}

void updateDisplay() {
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);
    display.setTextColor(GxEPD_BLACK);
    display.setFont(&FreeMonoBold9pt7b); 
    
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    if (isnan(t)) t = 0;
    if (isnan(h)) h = 0;
    
    display.setCursor(8, 25);
    display.print("T:"); display.print(t, 1); display.print("C  H:"); display.print(h, 0); display.print("%");
    
    display.drawLine(0, 30, 296, 30, GxEPD_BLACK);
    
    int x = 8;
    int y = 55;
    
    for (int i = 0; i < numPlants; i++) {
      display.setCursor(x, y);
      display.print("P"); display.print(i + 1); display.print(":");
      if (plantIsDry[i]) display.print("DRY"); else display.print("WET");
      
      x += 70; 
      if (x > 250) { x = 8; y += 30; }
    }
    
    display.setCursor(8, 115);
    display.print(isPumping ? "PUMP: ON" : "PUMP: OFF");
    
  } while (display.nextPage());
  
  display.hibernate();
}

void loop() {
  bool needWater = false;
  bool allTargetReached = true;
  
  // 1. Read ADC (Plants 1-4)
  for (int i = 0; i < 4; i++) {
    int16_t adc0 = ads1.readADC_SingleEnded(i);
    if (adc0 > adcStartThreshold) { plantIsDry[i] = true; needWater = true; } 
    else { plantIsDry[i] = false; }
    if (adc0 > adcStopThreshold) { allTargetReached = false; }
  }
  
  // 2. Read ESP32 True Analog Pins (Plants 5-8)
  for (int i = 0; i < 4; i++) {
    int moisture = analogRead(espPins[i]);
    if (moisture > espStartThreshold) { plantIsDry[i + 4] = true; needWater = true; } 
    else { plantIsDry[i + 4] = false; }
    if (moisture > espStopThreshold) { allTargetReached = false; }
  }

  // 3. Pump Logic
  if (!isPumping) {
    if (needWater) 

More projects by tareq-neoaz