ACT1_SAGARAL — ESP32 simulation

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by sagaral-juliana03.

Components

Sketch code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// ---- Pins ----
#define SOIL_PIN   34
#define RED_LED    13
#define BLUE_LED   12
#define GREEN_LED  14

// ---- CALIBRATION: put the raw values you read in the Serial Monitor ----
#define DRY_RAW    3400   // raw reading with slider at 0%
#define WET_RAW    1400   // raw reading with slider at 100%  <-- CHANGE THIS

// ---- State limits (in percent) ----
#define DRY_PERCENT   30   // below this -> DRY
#define WET_PERCENT   60   // above this -> WET

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Serial.begin(115200);

  pinMode(RED_LED, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);

  analogReadResolution(12);

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Soil Condition:");
}

void setLEDs(bool r, bool g, bool b) {
  digitalWrite(RED_LED, r);
  digitalWrite(GREEN_LED, g);
  digitalWrite(BLUE_LED, b);
}

int readSoilRaw() {
  long sum = 0;
  for (int i = 0; i < 10; i++) {      // average 10 samples to smooth noise
    sum += analogRead(SOIL_PIN);
    delay(2);
  }
  return sum / 10;
}

void loop() {
  int raw = readSoilRaw();

  // Scale between the calibration points (works whichever one is larger)
  float p = (float)(raw - DRY_RAW) * 100.0 / (float)(WET_RAW - DRY_RAW);
  int percent = constrain((int)round(p), 0, 100);

  String state;
  if (percent < DRY_PERCENT) {
    state = "DRY";
    setLEDs(HIGH, LOW, LOW);      // RED   = dry
  } else if (percent < WET_PERCENT) {
    state = "MOIST";
    setLEDs(LOW, LOW, HIGH);      // BLUE  = moist
  } else {
    state = "WET";
    setLEDs(LOW, HIGH, LOW);      // GREEN = wet
  }

  Serial.printf("Raw: %d  ->  %d%%  (%s)\n", raw, percent, state.c_str());

  lcd.setCursor(0, 1);
  lcd.print(F("                "));   // clear line 2 (16 spaces)
  lcd.setCursor(0, 1);
  lcd.print(state);
  lcd.print(" ");
  lcd.print(percent);
  lcd.print("%");

  delay(500);
}