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

Arduino UNO-Based NPK Soil Sensor with OLED Display and RS-485 Communication

View and Edit Project In Cirkit DesignerImage of Arduino UNO-Based NPK Soil Sensor with OLED Display and RS-485 Communication

Circuit Documentation

Summary

This circuit is designed to measure soil nutrients (Nitrogen, Phosphorous, and Potassium) using an NPK Soil Sensor and display the results on a 0.96" OLED display. The circuit utilizes an Arduino UNO as the main microcontroller, an RS-485 module for communication with the soil sensor, and a battery for powering the soil sensor.

Component List

  1. Arduino UNO

    • Description: A microcontroller board based on the ATmega328P.
    • Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0, A1, A2, A3, A4, A5, SCL, SDA, AREF, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
  2. NPK Soil Sensor

    • Description: A sensor used to measure the levels of Nitrogen, Phosphorous, and Potassium in the soil.
    • Pins: 12V DC, A, B, GND
  3. RS-485 Module

    • Description: A module used for RS-485 communication.
    • Pins: VCC, B, A, GND, RO, RE, DE, DI
  4. 0.96" OLED

    • Description: A small OLED display used to show the measured nutrient levels.
    • Pins: GND, VDD, SCK, SDA
  5. Battery

    • Description: A power source for the NPK Soil Sensor.
    • Pins: -, +

Wiring Details

Arduino UNO

NPK Soil Sensor

RS-485 Module

0.96" OLED

Battery

Documented Code

Arduino UNO Code

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

#define RE 8
#define DE 7
const byte nitro[] = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xB5, 0xCC};
const byte phos[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xE4, 0x0C};
const byte pota[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xC0};

byte values[11];
SoftwareSerial mod(2, 3);  // RS485 TX (2) and RX (3)
LiquidCrystal_I2C lcd(0x27, 16, 2);  // LCD I2C address 0x27, 16x2 display

void setup() {
  Serial.begin(9600);
  mod.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  lcd.init();            // Initialize the LCD
  lcd.backlight();       // Turn on the backlight
  lcd.setCursor(0, 0);   // Set cursor to the first row
  lcd.print("  Initializing");
  delay(2000);
  lcd.clear();
  lcd.print("   NPK Sensor");
  delay(3000);
}

void loop() {
  byte val1, val2, val3;
  val1 = nitrogen();
  delay(250);
  val2 = phosphorous();
  delay(250);
  val3 = potassium();
  delay(250);

  Serial.print("Nitrogen: ");
  Serial.print(val1);
  Serial.println(" mg/kg");
  Serial.print("Phosphorous: ");
  Serial.print(val2);
  Serial.println(" mg/kg");
  Serial.print("Potassium: ");
  Serial.print(val3);
  Serial.println(" mg/kg");
  delay(2000);

  // Display NPK values on LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("N: ");
  lcd.print(val1);
  lcd.print(" mg/kg");
  lcd.setCursor(0, 1);
  lcd.print("P:");
  lcd.print(val2);
  lcd.print(" K:");
  lcd.print(val3);
  delay(2000);
}

byte nitrogen() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(20);  // Increased delay
  if (mod.write(nitro, sizeof(nitro)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    delay(20);  // Added delay
    for (byte i = 0; i < 7; i++) {
      if (mod.available()) {
        byte readValue = mod.read();
        values[i] = readValue;
      } else {
        values[i] = 255;  // Default value if no data is available
      }
    }
  }
  return values[4];
}

byte phosphorous() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(20);  // Increased delay
  if (mod.write(phos, sizeof(phos)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    delay(20);  // Added delay
    for (byte i = 0; i < 7; i++) {
      if (mod.available()) {
        byte readValue = mod.read();
        values[i] = readValue;
      } else {
        values[i] = 255;  // Default value if no data is available
      }
    }
  }
  return values[4];
}

byte potassium() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(20);  // Increased delay
  if (mod.write(pota, sizeof(pota)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    delay(20);  // Added delay
    for (byte i = 0; i < 7; i++) {
      if (mod.available()) {
        byte readValue = mod.read();
        values[i] = readValue;
      } else {
        values[i] = 255;  // Default value if no data is available
      }
    }
  }
  return values[4];
}

NPK Soil Sensor Code

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

0.96" OLED Code

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}