#include <DHT.h>
#include <DHT_U.h>
#include <iostream>
#include <HardwareSerial.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// === OLED Setup ===
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// === MCP9808 Setup ===
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808(); // default I2C address 0x18
// === DHT11 Setup ===
#define DHTPIN 27
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// === Soil Moisture Sensor 1 Setup ===
const int moisture_pin = 34; // Analog pin GPIO35
int moisture_raw = 0;
int moisture_percent = 0;
// === Soil Moisture Sensor 2 Setup ===
const int moisture_pin2 = 12; // Analog pin GPIO34
int moisture_raw2 = 0;
int moisture_percent2 = 0;
// === LED Pins ===
const int yellowLED = 13; // Change if needed
const int redLED = 0; // Change if needed
void setup() {
Serial.begin(115200);
Wire.begin(21, 23); // SDA, SCL
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(5, 30);
display.println("Booting...");
display.display();
delay(1000);
// MCP9808
if (!tempsensor.begin(0x18)) {
Serial.println("Couldn't find MCP9808!");
display.clearDisplay();
display.setCursor(0, 10);
display.println("MCP9808 not found");
display.display();
while (true);
}
tempsensor.setResolution(3); // 0.0625°C
// DHT
dht.begin();
// LED setup
pinMode(yellowLED, OUTPUT);
pinMode(redLED, OUTPUT);
digitalWrite(yellowLED, LOW);
digitalWrite(redLED, LOW);
display.clearDisplay();
}
void loop() {
float dhtTemp = dht.readTemperature();
float humidity = dht.readHumidity();
float mcpTemp = tempsensor.readTempC();
moisture_raw = analogRead(moisture_pin);
// Updated mapping for resistive soil_moisture_1: 1580 (wet) -> 100%, 4095 (dry) -> 0%
moisture_percent = ((4095 - moisture_raw) / (4095.0 - 1300.0) * 100);
moisture_percent = constrain(moisture_percent, 0, 100); // Clamp between 0–100
moisture_raw2 = analogRead(moisture_pin2);
// Updated mapping for capacitive soil_moisture_2: 1550 (wet) -> 100%, 3700 (dry) -> 0%
moisture_percent2 = ((3700 - moisture_raw2) / (3700.0 - 1550.0)) * 100;
moisture_percent2 = constrain(moisture_percent2, 0, 100); // Clamp between 0–100
// === LED Logic ===
if (moisture_percent < 30) {
digitalWrite(yellowLED, HIGH);
delay(200);
digitalWrite(yellowLED, LOW);
delay(100); // Blinks 1x yellow LED
} else if (moisture_percent >= 30 && moisture_percent <= 50) {
digitalWrite(yellowLED, HIGH);
} else {
digitalWrite(yellowLED, LOW);
}
if (moisture_percent2 < 30) {
digitalWrite(redLED, HIGH);
delay(200);
digitalWrite(redLED, LOW);
delay(100);
digitalWrite(redLED, HIGH);
delay(200);
digitalWrite(redLED, LOW);
delay(100); // Blinks 2x red LED
} else if (moisture_percent2 >= 30 && moisture_percent2 < 50) {
digitalWrite(redLED, HIGH);
} else {
digitalWrite(redLED, LOW);
}
// === Serial Debug ===
Serial.printf("\nDHT11 Temp: %.1f C\nDHT11 Humidity: %.1f%%\n", dhtTemp, humidity);
Serial.printf("MCP Temp: %.1f C\n", mcpTemp);
Serial.printf("Soil Moisture 1: %d%% (raw: %d)\n", moisture_percent, moisture_raw);
Serial.printf("Soil Moisture 2: %d%% (raw: %d)\n", moisture_percent2, moisture_raw2);
// === Display Output ===
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.printf("MCP Temp : %.1f C\n", mcpTemp);
display.setCursor(0, 20);
display.printf("DHT11 Temp : %.1f C\n", dhtTemp);
display.setCursor(0, 30);
display.printf("Humidity : %.1f %%\n", humidity);
display.setCursor(0, 40);
display.printf("Soil Moisture 1: %d %%", moisture_percent); // Display unchanged
display.setCursor(0, 50);
display.printf("Soil Moisture 2: %d %%", moisture_percent2);
display.display();
delay(1000); // Delay before next reading
}