A microcontroller-based soil fertility detection system.
Abstract
Soil is the most used plant growth medium. However, due to various soil conditions, not all plants are also suitable for the particular soil to be used, so a tool or sensor is needed that can read and measure soil fertility. Simple soil fertility measurement can be measured from 2 elements of soil fertility attributes, namely the soil pH element and the soil moisture element. Most of the available soil fertility detection instruments or systems only use one of the soil fertility elements and the data on the detection results can't be stored for a long period, making the readings less effective. From these problems, we conducted research to build a soil fertility detection system that uses a soil pH sensor and a soil moisture sensor that is connected to the Arduino Nano microcontroller and can be run with an application on a smartphone. The results of this study are in the form of a soil fertility detection tool and system that can read soil pH and soil moisture content and an Android smartphone application that is connected to the device via the USB-OTG feature. With this application, a test location is obtained where the soil is tested and then stored in the TinyDB database in the application so that data will not be lost even if the tool is turned off.
Keywords: soil, fertility, pH sensor, moisture sensor, microcontroller, Android application
Hardware Specifications
1. Arduino Nano microcontroller
2. Soil pH meter sensor
3. Capacitive soil moisture sensor
4. LED lamp indicator
5. Active Buzzer
6. Voltage Regulator
7. Switch/Push button
8. Diode
9. Jumper cable
10. USB-OTG Adapter
11. Micro USB / Type C USB cable (depends on smartphone USB port)
12. Printed Circuit Board
13. Case
14. Smartphone with support for USB On-The-Go, GPS, and Location Sensor
System Design
System Block Diagram
Hardware Schematic
Hardware System Flowchart
Android App Main Program Flowchart
Android App Sub Program Flowchart
- Serial communication
- Clock
- Location sensor
- Show map marker
- Save data
- Delete data
- Save data list
Prototype Implementation
Hardware prototype
- PCB design
- Final prototype
- Prototype on use
Arduino Program
/* | |
Hasil Kalibrasi Sensor Moisture 5V | |
Air = 698 ~ 719 | |
Lembab = 719 ~ 852 | |
Kering = 852 ~ 876 | |
Nilai sensor pH | |
Asam = < 6 | |
Netral = 6 ~ 7 | |
Basa = > 7 | |
*/ | |
//Control panel alat dan pembacaan sensor | |
#define data 100 | |
int toleransiMoist = 20; | |
float toleransipH = 0.2; | |
int delay_pembacaan = 20; | |
//Output debug | |
bool debugMode = false; | |
float nilaiPHDebug = 5; | |
int nilaiMoistDebug = 850; | |
//Define PIN yang digunakan | |
#define analogMoisture A2 | |
#define analogPH A0 | |
#define sw 2 | |
#define buzzer 4 | |
//Nilai default untuk alat | |
int looping = 0; | |
int nilaimoist[data] = {0}; | |
float nilaipH[data] = {0}; | |
bool started = false; | |
float nilaiSensorpH = 0.0; | |
//Machine state | |
int state = 0; | |
//Untuk debouncing switch interrupt | |
unsigned long lastDebounceTime = 0; | |
unsigned long debounceDelay = 2000; | |
//Interrupt, dengan debouncing tombol | |
void interrupt_routine() { | |
if((millis() - lastDebounceTime) > debounceDelay && started) { | |
lastDebounceTime = millis(); | |
state = 1; | |
} | |
} | |
//Buzzer beep | |
void check() { | |
digitalWrite(buzzer, HIGH); | |
delay(50); | |
digitalWrite(buzzer, LOW); | |
} | |
//Output serial ke smartphone | |
void output(int inputMoistRef, float inputPHRef) { | |
int inputMoist; | |
float inputPH; | |
if(debugMode) { | |
inputMoist = nilaiMoistDebug; | |
inputPH = nilaiPHDebug; | |
} else { | |
inputMoist = inputMoistRef; | |
inputPH = inputPHRef; | |
} | |
//data bahasa | |
String keadaanKelembaban[4] = {"ERROR_", "kering", "lembab", "basah"}; | |
String keadaanPH[4] = {"ERROR_", "netral", "terlalu asam", "terlalu basa"}; | |
//integer untuk output | |
int outKelembaban = 0, outPH = 0; | |
//Setting output kelembaban | |
//Kering = 876 ~ 852 | |
if(inputMoist > 852) { | |
outKelembaban = 1; | |
} | |
//Lembab = 852 ~ 719 | |
else if(inputMoist <= 852 && inputMoist > 719) { | |
outKelembaban = 2; | |
} | |
//Basah = 719 ~ 698 | |
else if(inputMoist <= 719 && inputMoist > 698) { | |
outKelembaban = 3; | |
} | |
//Setting output pH | |
//Netral (6 ~ 7) | |
if(inputPH >= 6 && inputPH <= 7) { | |
outPH = 1; | |
} | |
//Terlalu asam (< 6) | |
else if(inputPH >= 0 && inputPH < 6) { | |
outPH = 2; | |
} | |
//Terlalu basa (> 7) | |
else if(inputPH > 7 && inputPH <= 14) { | |
outPH = 3; | |
} | |
//Output status tanah | |
while(digitalRead(sw)) { | |
Serial.print("Status tanah "); | |
Serial.print(keadaanPH[outPH]); | |
Serial.print(" pH "); | |
Serial.print(inputPH); | |
Serial.print(" dan "); | |
Serial.print(keadaanKelembaban[outKelembaban]); | |
if(outKelembaban == 0) { | |
Serial.print(inputMoist); | |
} | |
Serial.println("."); | |
delay(1000); | |
} | |
check(); | |
delay(500); | |
} | |
//State 1, mengukur | |
void mengukur() { | |
//User feedback | |
digitalWrite(buzzer, HIGH); | |
delay(200); | |
digitalWrite(buzzer, LOW); | |
//Mulai pengukuran | |
//Sensor kelembaban | |
while(looping != data) { | |
if(analogRead(analogMoisture) - nilaimoist[0] > toleransiMoist || nilaimoist[0] - analogRead(analogMoisture) > toleransiMoist) { | |
looping = 0; | |
nilaimoist[0] = analogRead(analogMoisture); | |
} else { | |
nilaimoist[looping] = analogRead(analogMoisture); | |
looping++; | |
} | |
delay(delay_pembacaan); | |
} | |
looping = 0; | |
//Sensor pH | |
while(looping != data) { | |
nilaiSensorpH = (-0.0693*analogRead(analogPH))+7.3855 | |
if(nilaiSensorpH - nilaipH[0] > toleransipH || nilaipH[0] - nilaiSensorpH > toleransipH) { | |
looping = 0; | |
nilaipH[0] = nilaiSensorpH; | |
} else { | |
nilaipH[looping] = nilaiSensorpH; | |
looping++; | |
} | |
delay(delay_pembacaan); | |
} | |
looping = 0; | |
//User feedback | |
digitalWrite(buzzer, HIGH); | |
delay(100); | |
digitalWrite(buzzer, LOW); | |
delay(100); | |
digitalWrite(buzzer, HIGH); | |
delay(100); | |
digitalWrite(buzzer, LOW); | |
//Output serial | |
output(nilaimoist[0], nilaipH[0]); | |
//state 0 | |
state = 0; | |
} | |
void setup() { | |
pinMode(sw, INPUT_PULLUP); | |
pinMode(buzzer, OUTPUT); | |
Serial.begin(9600); | |
check(); | |
attachInterrupt(digitalPinToInterrupt(sw), interrupt_routine, FALLING); | |
} | |
void loop() { | |
//sebagai syarat interrupt | |
started = true; | |
//state machine | |
switch(state) { | |
case 1: | |
mengukur(); | |
break; | |
default: | |
break; | |
} | |
} |
Android Application Program
This Android application uses Kodular Blocks, read more: https://docs.kodular.io/
The full image of these blocks can be seen on: kodular-blocks/kodular-blocks.png
.
- Main program initialization
- 0pen serial connection
- Read serial data
- Get location
- Address input
- Show location map
- Save data and list
- Delete data
Android Application User Interface
End Notes
This is a simple college project for Praktik Kerja Lapangan which is supervised by a lecturer. There is still much room for improvement.
Top comments (1)
Interesting! What was the most challenging part of building this?