iGrow: Truffle Irrigation Control and Monitoring

IoT water control for irrigation of truffles. It monitors and controls amount of water in storage tanks on field.

AdvancedWork in progressOver 5 days4,885
iGrow: Truffle Irrigation Control and Monitoring

Things used in this project

Hardware components

SIM800H IoT module
Eclo Solutions SIM800H IoT module
Microchip Technology ATmega328
Arduino Mega 2560
Arduino Mega 2560
lm2596 dc-dc buck converter
SparkFun Transceiver Breakout - nRF24L01+
SparkFun Transceiver Breakout - nRF24L01+
Battery Holder, 18650 x 1
Battery Holder, 18650 x 1
battery li-ion 18650
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
TP4057 Li-Ion charger IC
T2 SIM card
Step-Up Voltage Regulator - 3.3V
SparkFun Step-Up Voltage Regulator - 3.3V
Development Kit Accessory, Solar Cell
Development Kit Accessory, Solar Cell
double MOSFET li-ion protection FS8205a
DV01 li-ion protection IC

Software apps and online services

Arduino IDE
Arduino IDE
Circuit Maker
CircuitMaker by Altium Circuit Maker
Pcbway, PCB manufacturer

Hand tools and fabrication machines

USBasp AVR programmer
Soldering Station Power Supply, For Weller WX Soldering System
Soldering Station Power Supply, For Weller WX Soldering System


Read more


Custom PCB for off the grid sensor value transmitter with solar power

MySQL status table

MySQL set table

Water tank measuring module schematics


Pump control code (ArduinoMega)

Main function flow of pump control
 * This is Igrow project main code
 * Compatible with ArduinoMega and modules SIM800L, NRF24L01 and ultrasonic distance sensor. 
 * Code version: V5

#include "nRF24L01.h" // NRF24L01 library https://github.com/TMRh20/RF24
#include "RF24.h"
#include "SPI.h"

// Server database address
const String URL = "http://<domain name>";
int ReceivedMessage[2] = {000}; //NRF24L01 packet
RF24 radio(49,48); // NRF24L01 used SPI pins
const uint64_t pipe = 0xE6E6E6E6E6E6; //NRF24L01 communication pipe

int Voltage_sense = A14; //Power supply voltage sense pin
// data
int main_tank_value = 100; //Water level in % of distant water tank
long main_tank_value_received_time = 0; //Last receiving time of distant water tank data
int main_tank_value_wanted = 50; // Wanted level in distant water tank
int secondary_tank_value = 0; //Water level in % of secondary storage tank
int Battery = 0; //Battery voltage
byte Battery_state_of_charge = 50; //SOC of battery in %
bool pump = 0; //Pump status; 1 = ON, 0 = OFF
//Mode sistema
 * 0 -> sistem ustavljen
 * 1 -> sistem deluje normalno
 * 2 -> napaka v sistemu, sistem ustavljen
 * 3 -> varčevanje z energijo
int mode = 1; //mode sistema
int GSM_sending_period_s = 60; //Na koliko časa se pošiljajo podatki na splet 
long gsm_time = 0; //Čas zadnje komunikacije z serverjem
long gsm_session_time = 0; //Čas zadnje menjave sessiona na GSM
long GSM_session_period_s = 300; //5min //Čas kolikor traja 1 session GSM interneta
long last_sucsessful_session_time = 0; //Čas zadnjega uspešnega odziva serverja

void setup(void){

pinMode(Voltage_sense, INPUT);

Serial.begin(9600); //Debug port
Serial1.begin(9600); //GSM module

radio.begin(); // Start the NRF24L01
radio.openReadingPipe(1,pipe); // Get NRF24L01 ready to receive
radio.startListening(); // Listen to see if information received
//Waiting for any data from debug port for a system to start
Serial.println("RF24 receiver running");
Serial.println("Press any key to start");

GSM_GPRS_WAIT(); //Waiting til GPRS is working

void loop(void){

  RF_SESSION(); //RF komunikacija (Distant tank watter level check)
  GSM_PROCESS(); //GSM services (GSM communication and controll)
  Battery = Battery_sense(); //Measuring power supply voltage
  Battery_state_of_charge = Battery_percentage_calculation(Battery); //Calculating battery SOC from power supply voltage
  //Water tank
  //secondary_tank_value = ; //Measuring water level in secundary storage tank
  PUMP_PROCESS(main_tank_value,main_tank_value_received_time,secondary_tank_value,main_tank_value_wanted, Battery_state_of_charge); //Pump controll
  //System check
  mode = System_check(mode); //System health check

PHP script for intercepting data from transmitter


//echo 'Hello World';
//echo $RAW;

parse_str($RAW, $OUTPUT);

$TM=$OUTPUT["TM"]; //tank main

$TS=$OUTPUT["TS"]; //tank secondary

$MTWS=$OUTPUT["MTWS"]; //main tank wanted status

$M=$OUTPUT["M"]; //mode

$B=$OUTPUT["BAT"]; //battery voltage

$BSOC=$OUTPUT["BSOC"]; //battery percentage

$TM = $_POST["TM"];  //tank main
$TS = $_POST["TS"];	//tank secondary
$MTW = $_POST["MTW"]; //main tank wanted


// $TM=99;
// $TS=99;
// $MTW=99;
echo $TM;
echo $TS;
echo $MTW;
$link = mysqli_connect("IP", "USERNAME", "PASSWORD", "TARTUF");

if (!$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;

//echo "Success: A proper connection to MySQL was made! The my_db database is great." . PHP_EOL;
//echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;

$shrani= "INSERT INTO stanje (TM,TS,MTWS,battery,mode,BSOC) VALUES (".$TM.",".$TS.",".$MTWS.",".$B.",".$M.",".$BSOC.")"; //kasneje to zamenjaj s proceduro
if (!mysqli_query($link, $shrani)) {
				$error_int = 3;

$sql = "SELECT MTWSET from nastavi order by datumcas desc limit 1";
$MTWSET = $link->query($sql)->fetch_object()->MTWSET;
echo "{MTWSET=".$MTWSET."}";

function responce($error_int){
        $response = array();
	    $response["error"] = $error_int;
	    $response["success"] = false; 
		echo json_encode($response);



PHP script for OpenWeather API

$apiKey = #your_api_key;

	$cityName = $_POST['kraj'];
}	else{
	$cityName = "Ljubljana";

function dobi_vreme($city,$api){
	global $Imkraja, $dan11, $dan12, $dan13, $dan14, $t1, $t2, $t3, $t4, $t, $rain, $data ;

	$apiUrl = "api.openweathermap.org/data/2.5/forecast?q=" .$city . "&appid=" .$api. "&units=metric";
	$ch = curl_init();

	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_URL, $apiUrl);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_VERBOSE, 0);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	$response = curl_exec($ch);

	$data = json_decode($response);
	$currentTime = time();

	$Imkraja = ucwords($data->city->name);
	$dan11 = $data->list[0]->dt;
	$dan12 = $data->list[5]->dt;
	$dan13 = $data->list[10]->dt;
	$dan14 = $data->list[15]->dt;

	$t1 = round($data->list[0]->main->temp);
	$t2 = round($data->list[5]->main->temp);
	$t3 = round($data->list[10]->main->temp);
	$t4 = round($data->list[15]->main->temp);

	$t = array();
	$rain = array();
	for ($i=0; $i <= 15; $i+=5) {
		$t[$j]= round($data->list[$i]->main->temp);
			$rain[$j] = $data->list[$i]->rain->{'3h'};
			$rain[$j] = 0;




Rok Vidmar

Rok Vidmar

1 project • 1 follower
Darjo Uršič

Darjo Uršič

0 projects • 2 followers


0 projects • 1 follower
Kristjan Jurčič

Kristjan Jurčič

0 projects • 1 follower