Soil pH Meter using Soil pH Sensor, ESP32, RP2040, and LoRa
Table of Contents
Soil pH Meter:
Soil pH Meter using Soil pH Sensor, ESP32, RP2040, and LoRa- If you want to make a farming-related project for yourself or for a client then you must read this article from start to end. That’s because in this article, not only will we cover the pH sensor, but I will also explain:
- How to upload a program to the ESP32S3 module using a USB to TTL converter.
- How to add the RP2040 board in the Arduino IDE and upload a program to it.
- How to modify existing codes.
- How to change the sleep time interval so the battery can last for months.
- How to split the entire string message and save different values into corresponding variables.
- How to use long-range LoRa transceiver modules to send battery voltage, temperature, humidity, and soil pH values from the transmitter side to the receiver side.
- At the end, we will visit the fields and check the soil’s pH value in different areas to understand how pH affects plant growth.
Today, I received this parcel from Makerfabs. They provide a wide range of services and products for makers, DIY enthusiasts, and electronics hobbyists. Honestly, I was so excited about this package that I couldn’t wait at all, and as soon as I got the box, I opened it right away.
Inside this box is the ‘Industrial-grade Soil Remote Monitor,’ which we can use to monitor humidity, temperature, and soil pH value. For you guys, I am going to do the unboxing again, so without any further delay, let’s get started.
Product Links:
Soil pH Meter “AgroSense LoRaWAN”
SenseLoRa “LoRa Receiver V1.0”
USB to TTL Converter on Amazon
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
Soil pH Meter Unboxing:
You can see the Receiver side and LoRa Antenna are nicely packed. This Antenna will be connected to the Receiver. The wire is quite long, and if installed outside, the LoRa communication range can increase up to around 5km.
This is the sensor that we will use to monitor temperature, soil moisture, and Soil pH values. The sensor has stainless steel rods. Insert these rods into the soil to read the temperature, humidity, and pH value.
This sensor looks just like the NPK sensor, which we use to measure soil nutrients like nitrogen, phosphorus, and potassium. I have already written a detailed article on the NPK sensor, where I monitored it using an Android application with Arduino and the HC-05 Bluetooth module. So, if you want to learn how to detect nitrogen, phosphorus, and potassium content in soil, I highly recommend reading that article.
Anyway, the Soil pH sensor is connected to Makerfabs “AgroSense LoRaWAN Sensor module” through a long wire, and this module is completely waterproof.
To power this whole system, a 6V and 1A solar panel is connected.
SenseLoRa LoRa Receiver V1.0:
This is the SenseLoRa LoRa Receiver V1.0, based on the RP2040 and the 868MHz LoRa transceiver module. You can also get the same receiver module with 433MHz and 915MHz LoRa modules.
- With this receiver, you also get a micro SD card for data logging.
- PCB Mount Golden connector for the LoRa.
- This receiver also has a display, where you can directly monitor the sensor. If you want to monitor the received data on a computer, you can connect this receiver to the computer using this USB-A interface, which I will explain later.
- On the top side, you can see there are 3 push buttons: Left to Right;
- Display Rotation Button
- Burn Button and
- Reset Button
Let me also tell you that this receiver is completely open-source. You can download the schematic, PCB design, and program from Makerfabs GitHub repository.
Now, let’s go ahead and connect the antenna to the receiver and mount the bracket on the solar panel.
AgroSense LoRaWAN Sensor Monitor:
Although the Soil pH sensor and solar panel are connected to the “AgroSense LoRaWAN Sensor monitor” it still won’t work because it’s OFF. To turn it ON, we need to open it.
As you can see, this button is currently OFF. Before turning it ON, let me explain a bit about the other components.
On the right bottom side, solar panel wires are connected.
You can connect a 1000mAh battery. Since batteries were not allowed in the shipment, so they didn’t send one. So, that’s why I have connected this small LiPo battery. I didn’t have a PH2.0 connector, so I soldered the battery wires directly.
On the top side you can see the LoRa transceiver module, and next to it is the ESP32-S3-WROOM-1 WiFi + Bluetooth Module.
On the Left side, the Soil pH Sensor wires are soldered. You can desolder these wires and use the pH sensor with an Arduino or any other controller board you want to use.
On the right side of the ESP32S3, you can see I have also soldered female headers. Normally, it’s ready to use because the company has already uploaded a program to it. So, when you open it, you won’t see male or female headers. But if you want to upload your own program, you will need to solder male or female headers here so that you can easily use a USB to TTL converter with it. Don’t worry, the headers are clearly labeled on the bottom side as:
RESET
IO0
RXD
TXD
GND and
VCC
I will explain later how to connect the USB to TTL converter and upload code to the ESP32S3.
Also, like the receiver, the AgroSense LoRaWAN Sensor is completely open source. You can find the circuit diagram, PCB design, and program for this board on Makerfabs GitHub repository.
PCBWay:
PCBWay is a trusted leader in the PCB industry, offering custom-designed boards at competitive prices to suit projects of all sizes—from basic to highly specialized.
Whether you’re working with standard FR-4 or need advanced solutions like Rogers, HDI, or Flexible and Rigid-Flex boards, PCBWay provides high-quality options without the high cost. Get an instant quote at pcbway.com/orderonline.
Curious about what others are creating? Explore innovative projects and ideas from the PCB community on PCBWay’s open-source platform at pcbway.com/project/.
AgroSense LoRaWAN; WiFi Setup:
To configure and set up the remote side sensor, first place it outside so the solar panel can charge the battery. As you can see, the red LED is ON.
Next, turn this button ON to power up the transmitter side and then quickly press the other button. You don’t have to do this every time, only when you need to change the ID or the interval time.
Then, open the internet browser on your laptop.
Press the WiFi button and select “Makerfabs” from the list, then click on the Connect button.
Enter the network security key, which is ‘12345678’.
Once connected, enter this IP Address: “http://192.168.4.1/”.
Using this web page, you can set any sensor ID you want and also set the interval time in seconds. The default interval time is 3600 seconds, which is equal to 1 hour. If you use this interval, you will get the sensor reading after 1 hour. The advantage of using a longer interval is that the battery won’t discharge quickly. So, this way, you can even use a small battery for moths.
Anyway, let’s say we want to get the sensor reading every 10 seconds. To do that, we will enter “10” in the Interval Time box.
For now, I am going to use the same Sensor ID.
Finally, click on the Setup and Restart Button.
If you can see the Set Success message, then congratulations, you have deployed your remote sensor monitor successfully. Now, the remote sensor monitor will send the soil condition based on the set interval time.
Remove this part of the URL and press enter.
If you get the error “Your connection was interrupted” or a similar error, it means the WiFi connection was lost.
As you can see, the Makerfabs module is not available in the WiFi list. To fix this issue, you need to restart the remote module. Whenever you change the sensor ID or interval time, always restart the circuit.
As you can see, it is connected again.
You can see the same sensor ID, and the interval time is changed to 10 seconds.
In the same way, you can change the sensor ID or interval time at any moment. Using the same steps I changed the Sleep Interval time to 20 Seconds.
Throughout this project I will use 20 seconds Interval Time.
After making the desired changes, turn OFF the AgroSense LoRaWAN Module and then turn it ON again, and to be on the safe side also press the reset button. After that, tightly close the cover.
The transmitter side is now fully ready. I have placed it outside again so the battery can charge during testing. Anyway, next, we will start with the receiver side.
SenseLoRa Receiver V1.0:
We don’t need to do any settings on the receiver side; it’s ready to use. We just need to connect it to the laptop and wait for 20 seconds.
As you can see, we have received the values. If you don’t want to use it with a laptop and want to make it completely portable, you can use my designed 5V and 3A power supply. I have already written a detailed article on this.
With this 5V and 3A power supply, you can use any power supply from 9V to 25V. Right now, I am using this 4S lithium-ion battery pack that I made myself. I actually made this battery for my racing drone. If you want to make the same 4S lithium-ion battery, you can read my article.
Anyway, as you can see, it is receiving the data wirelessly through LoRa and printing it on the OLED display module. Now, if you want, you can also see this data on the computer. For that, you will need to download the SSCOM32E software.
Make sure to select the correct communication port and baud rate. Right now, you can see we are getting new data every 20 seconds, as we selected a 20-second interval time during the transmitter settings.
Not only this, you can also send this data from the receiver side to any IoT cloud. I will explain this in one of my upcoming articles. Anyway, if your main goal is just to monitor soil pH, humidity, and temperature, and you don’t want to make any changes to the programs, then your work is done here.
Because the next things I am going to explain are only for those who want to program both the receiver and transmitter sides. It might be a little boring, but trust me, you will learn a lot. Anyway, first, let’s start with the receiver side.
RP2040 Board installation in the Arduino IDE:
To use the SenseLoRa receiver with Arduino IDE, first, we need to install the RP2040 board in the Arduino IDE. Let’s do it.
While the Arduino IDE is Open, go to the Tools menu then to Board and click on the Boards Manager. Type RP2040 in the Search Box.
Install the Arduino Mbed OS RP2040 Boards, make sure you install the 4.0.4 version, this version of the RP2040 is recommended by the Manufacturer. Anyway, once you have installed this specific version of the RP2040 board, next you need to confirm if its available in the boards list. For this go to the Tools menu, then to boards, you can see the Arduino Mbed OS RP2040 Boards has been added; you should see Raspberry Pi Pico, so, simply go ahead and select it.
SenseLoRa RP2040 Programming:
Complete program for the SenseLoRa Receiver can be download from the Makerfabs GitHub repository, which, as you know, is based on the RP2040. Link to the repository I have already share above. I also downloaded this code from there. In the folder you will see two files
Firmware and config.h
First, we need to install the required libraries, and let me tell you, you must install the exact same versions. I have already installed all these libraries, so let me show them to you.
Arduino libraries:
RP2040_SD 1.0.1
RadioLib 4.6.0
Adafruit_SSD1306 2.5.1
Adafruit_GFX_Library 1.11.5
Adafruit_BusIO 1.14.1
Let’s install the above libraries one by one. To install a library, go to the Tools Menu, then to Include Library, and click on the Manage library. In the search box type RP2040_SD and make sure you install the same exact version.
Next, install the RadioLib library version 4.6.0
Next install the Adafruit_SSD1306 version 2.5.1
Next install the Adafruit_GFX_Library version 1.11.5
Next install the Adafruit_BusIO version 1.14.1
After installing the board and all the libraries, next, you need to go to this path:
C:\Users\OK\AppData\Local\Arduino15\packages\arduino\hardware\mbed_rp2040\4.0.4\variants\RASPBERRY_PI_PICO and change the SDA and SCL from (4u) and (5u) to (6u) and (7u).
In the RASPBERRY_PI_PICO Folder, scroll down and Open the pins_arduino.h in the notepad file. If you find it difficult, watch the video tutorial given at the end of this article.
Set PIN_WIRE_SDA to (6u) and set PIN_WIRE_SCL to (7u) and then save the file.
Next, connect receiver to the laptop and upload the program.
For this select the Raspberry pi Pico board.
Then select the correct communication port and finally click on the upload button.
Once the code is successfully upload then wait for set interval time to complete, if you remember we selected 20 seconds.
Perfect! The receiver has wirelessly received the data. So, this means the program we uploaded is working. Now, we can modify the receiver’s program as per the requirements. I will do it later in this article. For now, let’s move on to the transmitter side.
AgroSense LoRaWAN Sensor:
the AgroSense LoRaWAN Sensor is completely open source. You can find the circuit diagram, PCB design, and program for this board on Makerfabs’ GitHub repository.
This is the complete program for the transmitter side, which we need to upload to the ESP32-S3-WROOM-1. But before that, you need to install the ESP32 board in Arduino IDE, just like we installed the RP2040 board. I have already written a detailed “Getting Started article” on the ESP32, where I explained the board installation process.
This time, you don’t need to install the libraries because we have already installed all the required ones. The final step is to upload the program, and as you know, we need to use a USB to TTL converter for this. So, let’s do it!
USB to TTL converter with ESP32S3:
I have already connected USB to TTL converter. Its wiring is so simple.
- Connect the VCC and GND pins of the USB to TTL converter to the VCC and GND pins on the AgroSense LoRaWAN Sensor module.
- Connect TX to the RX.
- Connect RX to the TX, and finally
- Connect the IO0 to the GND.
Uploading the Programming:
- Connect the USB to TTL converter to your laptop.
- Next, on the AgroSense LoRaWAN Sensor Module turn ON the button.
- Now, go to the Tools menu, then to Board, ESP32 Arduino, and select ESP32S3 Dev Module.
- Again go to the Tools Menu then to Port and select the correct communication port.
- Finally, click on the upload button.
Once the program is successfully uploaded.
- Now, remove the USB cable and also turn OFF the button on the AgroSense LoRa module.
- Next, remove all the wires if you no longer want to make any changes in the code.
- Don’t forget to Turn ON the switch before you tightly close the cover.
Our transmitter side is now completely ready and right now its transmitting the data. Let’s power up the Receiver side to check if its working.
Perfect, we received the data which means we did everything correctly. But its quite hard to read the values. Let’s remove the ID, count, and sleep values from the display.
This is the received message format i.e when the transmitter side sends the data; on the receive side you get a complete message as you can see below.
1 |
{"ID":"SoilM01","COUNT":162,"SLEEP":20,"bat":3.48,"temp":30.60,"humi":0.80,"PH":4.00} |
We have to split this entire message and save the ID, COUNT, SLEEP, battery voltage, temperature, humidity, and PH values in the corresponding variables. Then we can apply certain conditions on any of these values. let’s say when the battery voltage falls below 3 volts, we can print a message on the display or we can generate a notification message. The same exact thing we can do with the Temperature, Humidity, and PH values as well. For now, I don’t want to add any conditions, but I want to remove the ID, count, and sleep values from the display. So, let’s go ahead and modify the receiver side program.
Modified Program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
// Arduino Mbed OS RP2040 Boards version 4.0.4 #include "config.h" Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); SX1276 radio = new Module(LORA_CS, LORA_DIO0, LORA_RST, LORA_DIO1, SPI, SPISettings()); File root; File myFile; long unsigned int runtime = 0; int count = 0; int sd_flag = 0; int screen_rotation = 2; int button_flag = 0; int last_rssi = 0; String oled_str = "no message"; int flesh_flag = 0; // Declare variables to store the extracted values String sensorID = ""; int msgCount = 0; int sleep = 0; float battery = 0.0; float temperature = 0.0; float humidity = 0.0; float pH = 0.0; void setup(void) { Serial.begin(115200); pinMode(LORA_CS, OUTPUT); pinMode(SD_CS, OUTPUT); pinMode(PIN_SPI_MISO, INPUT); pinMode(PIN_SPI_MOSI, OUTPUT); pinMode(PIN_SPI_SCK, OUTPUT); pinMode(BUTTON_PIN, INPUT_PULLUP); delay(2000); Serial.println(F("Hello! SenseLoRa LoRa Receiver")); oled_init(); sd_flag = sd_init(); lora_init(); while (0) { lora_send_task("AAAA"); delay(10000); } runtime = millis(); attachInterrupt(BUTTON_PIN, button_func, FALLING); // CHANGE FALLING RISING flesh_flag = 1; } void loop() { if (button_flag == 1) { if (screen_rotation == 2) screen_rotation = 0; else screen_rotation = 2; display.setRotation(screen_rotation); Serial.println("Rotation OLED"); button_flag = 0; flesh_flag = 1; } if (flesh_flag == 1) { oled_display(); flesh_flag = 0; } lora_node_general(); if ((millis() - runtime) > 5000) { runtime = millis(); } } void lora_init() { SD_CS_OFF; LORA_CS_ON; int state = radio.begin(FREQUENCY, BANDWIDTH, SPREADING_FACTOR, CODING_RATE, SX127X_SYNC_WORD, OUTPUT_POWER, PREAMBLE_LEN, GAIN); if (state == ERR_NONE) { Serial.println(F("Lora init success!")); } else { Serial.print(F("Lora init failed, code ")); Serial.println(state); while (true); } } void lora_node_general() { String str; int state = radio.receive(str); if (state == ERR_NONE) { int rssi = radio.getRSSI(); Serial.println(str); String temp = ""; temp = temp + "Num:" + ++count; record_msg(temp); record_msg(str); oled_str = str; last_rssi = rssi; // Parse the received message parseMessage(oled_str); flesh_flag = 1; } else if (state == ERR_RX_TIMEOUT) { // Timeout occurred } else if (state == ERR_CRC_MISMATCH) { Serial.println(F("CRC error!")); } else { Serial.print(F("failed, code ")); Serial.println(state); } } // Function to parse the message and extract values void parseMessage(String message) { // Example message: {"ID":"SoilM01","COUNT":150,"SLEEP":20,"bat":3.49,"temp":30.60,"humi":0.00,"PH":4.00} // Extract the ID int idStart = message.indexOf("\"ID\":\"") + 6; int idEnd = message.indexOf("\"", idStart); sensorID = message.substring(idStart, idEnd); // Extract COUNT int countStart = message.indexOf("\"COUNT\":") + 8; int countEnd = message.indexOf(",", countStart); msgCount = message.substring(countStart, countEnd).toInt(); // Extract SLEEP int sleepStart = message.indexOf("\"SLEEP\":") + 8; int sleepEnd = message.indexOf(",", sleepStart); sleep = message.substring(sleepStart, sleepEnd).toInt(); // Extract battery voltage int batStart = message.indexOf("\"bat\":") + 6; int batEnd = message.indexOf(",", batStart); battery = message.substring(batStart, batEnd).toFloat(); // Extract temperature int tempStart = message.indexOf("\"temp\":") + 7; int tempEnd = message.indexOf(",", tempStart); temperature = message.substring(tempStart, tempEnd).toFloat(); // Extract humidity int humiStart = message.indexOf("\"humi\":") + 7; int humiEnd = message.indexOf(",", humiStart); humidity = message.substring(humiStart, humiEnd).toFloat(); // Extract pH int phStart = message.indexOf("\"PH\":") + 5; int phEnd = message.indexOf("}", phStart); pH = message.substring(phStart, phEnd).toFloat(); } int sd_init() { LORA_CS_OFF; SD_CS_ON; int fail_count = 0; while (1) { if (fail_count > 2) return 0; if (!SD.begin(SD_CS)) { SD.end(); Serial.println("SD init failed!"); fail_count++; delay(500); continue; } else { Serial.println("SD init done."); record_msg("New Restart......."); return 1; } } } void record_msg(String data) { if (!sd_flag) return; LORA_CS_OFF; SD_CS_ON; File myFile = SD.open(LOG_FILE, FILE_WRITE); myFile.println(data.c_str()); myFile.close(); SD_CS_OFF; LORA_CS_ON; } void oled_init() { Wire.begin(); Wire.setClock(100000UL); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 Serial.println(F("SSD1306 allocation failed")); for (;;); } Serial.println("SSD1306 found"); display.setRotation(screen_rotation); display.clearDisplay(); for (int16_t x = 0; x < display.width(); x += 1) { for (int16_t y = 0; y < display.height(); y += 1) { display.drawPixel(x, y, SSD1306_WHITE); } delay(1); } display.display(); delay(2000); display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(2); display.setCursor(0, 0); display.println("SenseLoRa"); display.println("LoRa"); display.println("Receiver"); display.display(); display.setTextSize(1); } void button_func() { button_flag = 1; } void oled_display() { display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1.5); display.println("Soil Monitoring"); display.println(""); // Display the extracted values on the OLED //display.println("ID: " + sensorID); //display.println("COUNT: " + String(msgCount)); //display.println("SLEEP: " + String(sleep)); display.println("Bat: " + String(battery) + "V"); display.println("Temp: " + String(temperature) + " C"); display.println("Hum: " + String(humidity) + " %"); display.println("pH: " + String(pH)); display.display(); } void lora_send_task(String data) { Serial.println(data); int state = radio.transmit(data.c_str()); if (state == ERR_NONE) { Serial.println(F(" success!")); Serial.print(F("[SX1276] Datarate:\t")); Serial.print(radio.getDataRate()); Serial.println(F(" bps")); } else if (state == ERR_PACKET_TOO_LONG) { Serial.println(F("too long!")); } else if (state == ERR_TX_TIMEOUT) { Serial.println(F("timeout!")); } else { Serial.print(F("failed, code ")); Serial.println(state); } } |
About the Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
void parseMessage(String message) { // Example message: {"ID":"SoilM01","COUNT":150,"SLEEP":20,"bat":3.49,"temp":30.60,"humi":0.00,"PH":4.00} // Extract the ID int idStart = message.indexOf("\"ID\":\"") + 6; int idEnd = message.indexOf("\"", idStart); sensorID = message.substring(idStart, idEnd); // Extract COUNT int countStart = message.indexOf("\"COUNT\":") + 8; int countEnd = message.indexOf(",", countStart); msgCount = message.substring(countStart, countEnd).toInt(); // Extract SLEEP int sleepStart = message.indexOf("\"SLEEP\":") + 8; int sleepEnd = message.indexOf(",", sleepStart); sleep = message.substring(sleepStart, sleepEnd).toInt(); // Extract battery voltage int batStart = message.indexOf("\"bat\":") + 6; int batEnd = message.indexOf(",", batStart); battery = message.substring(batStart, batEnd).toFloat(); // Extract temperature int tempStart = message.indexOf("\"temp\":") + 7; int tempEnd = message.indexOf(",", tempStart); temperature = message.substring(tempStart, tempEnd).toFloat(); // Extract humidity int humiStart = message.indexOf("\"humi\":") + 7; int humiEnd = message.indexOf(",", humiStart); humidity = message.substring(humiStart, humiEnd).toFloat(); // Extract pH int phStart = message.indexOf("\"PH\":") + 5; int phEnd = message.indexOf("}", phStart); pH = message.substring(phStart, phEnd).toFloat(); } |
I created the parseMessage() function which takes only one argument of the type string. This will take the received message as an input. And then using these instructions we extract the ID, COUNT, SLEEP, BATTERY VOLTAGE, TEMPERATURE, HUMIDITY, and pH values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
void oled_display() { display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1.5); display.println("Soil Monitoring"); display.println(""); // Display the extracted values on the OLED //display.println("ID: " + sensorID); //display.println("COUNT: " + String(msgCount)); //display.println("SLEEP: " + String(sleep)); display.println("Bat: " + String(battery) + "V"); display.println("Temp: " + String(temperature) + " C"); display.println("Hum: " + String(humidity) + " %"); display.println("pH: " + String(pH)); display.display(); } |
I have commented the ID, COUNT, and SLEEP values and I am only printing the Battery voltage, Temperature, Humidity, and pH values.
Practical demonstration:
Now you can see the display is very neat and clean. We can easily read the battery voltage, temperature, humidity, and pH value.
Now, I will dip this sensor in water to check if the humidity and pH values change or not. We’ll have to wait a bit, as you know we’ve set the interval time to 20 seconds.
This is simply mind blowing, humidity value is changed to 100% and the pH value is changed to 6.8.
Next, we are going to test this sensor with dry soil and then we will also add some water. Let’s do it.
Right now, you can see the soil humidity is 6.3% and the pH value is 7.3. Let’s go ahead and add some water.
Its working exceptionally well. This time the Humidity value changed to 23.5% and the Soil pH value is changed to 7.5.
I have come outside towards the fields to check if it’s true that tobacco farming damages the soil, because it makes the soil acidic. And this is what we are going to find out. But first, let me tell you for most vegetables the Soil pH value is between 6.0 and 7.0.
- Root vegetables (carrots, beets, radishes): 6.0-6.8
- Brassicas (broccoli, cauliflower, kale): 6.0-7.0
- Leafy greens (lettuce, spinach, arugula): 6.0-7.0
- Tomatoes and peppers: 6.0-6.8
- Cucumbers and squash: 6.0-6.8
- Corn: 6.0-7.0
- Beans and peas: 6.0-7.0
Soil pH value below 6.0 may cause nutrient deficiencies, especially phosphorus and calcium.
Whereas Soil pH value Above 7.0 may cause nutrient deficiencies, especially iron, zinc, and manganese.
Here we have some chilli plants, and most of the leaves are turning yellow. Let’s start here and find out the main reason behind these yellowing leaves.
I have inserted the pH sensor into the soil and placed the solar panel a little distance away. I powered up the receiver side using a 4S lithium-ion battery pack with my 5V and 3A power supply. On the display, you can see that the pH value is exactly 7, which is the upper limit. A pH of 7 means the soil is neutral.
One thing I noticed here is that almost all the farmers are only using manure as organic fertilizer.
Manure is made from animal waste, usually from farms or livestock. This is making the soil more alkaline because manure increases the pH value of the soil. It’s good to use organic fertilizer, but using too much can harm the soil by making it too alkaline.
There is some manure here already, so let’s check its pH value. As I said, this type of fertilizer increases the pH value, so let’s see what the receiver shows.
You can clearly see that the pH value is 7.5, which confirms that only using manure raises the soil’s pH. If the pH value is 7 or above, the soil becomes too alkaline, which can limit the availability of nutrients like phosphorus, iron, and manganese, causing poor growth and yellowing leaves.
According to experts, the best pH range for chilli plants is between 6.0 and 6.5. In this range, plants can absorb nutrients better. So now we know why the chilli plants’ leaves are turning yellow.
Soil pH Value Test in Tobacco Field:
The tobacco season is over, but before I start testing, let me tell you. For tobacco cultivation, the ideal soil pH range is between 5.8 and 6.5, which is slightly acidic. This pH range helps the tobacco plants get the nutrients they need and grow healthy.
If pH is below 5.8 the soil is too acidic, it can lead to nutrient imbalances, particularly deficiencies in calcium and magnesium, which are vital for tobacco growth.
If pH is above 6.5 the soil becomes too alkaline, it can reduce the availability of key nutrients like phosphorus and potassium, leading to poor plant development and lower-quality leaves.
Maintaining the pH within this range is crucial for a successful tobacco plantation, ensuring good leaf texture and quality.
I noticed tobacco plants with mostly yellow leaves, and when I spoke to the farmer, he said the plants didn’t grow well. Anyway, let’s first check the soil pH and then discuss it further. so let’s check the soil’s pH value on the receiver.
I am completely shocked. This pH value is not acceptable for tobacco plantation. The pH value of the soil should be between 5.8 and 6.5. The soil here is too alkaline because the farmer is using the same fertilizer as before. I confirmed this by talking directly to the farmer. I also asked about the plant growth and the leaf color, and according to the farmer, the tobacco plants didn’t grow as they should.
I must say, every farmer should have this pH sensor. It’s very easy to use, comes with a solar panel, and is completely waterproof. It has a good range, so you can monitor your fields from home. In upcoming videos, I will also show how to use this pH sensor with an IoT platform. So that’s all for now.