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 days6,982
iGrow: Truffle Irrigation Control and Monitoring

Things used in this project

Hardware components

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

Software apps and online services

php
mysql
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

Story

Read more

Schematics

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

MySQL status table

MySQL set table

Water tank measuring module schematics

Code

Pump control code (ArduinoMega)

C#
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
*/

//Libraries
#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
 
//GSM
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");
//GSM INTERNET START
Serial.println("Press any key to start");
while(!Serial.available()){}

GSM_GPRS_WAIT(); //Waiting til GPRS is working
}

void loop(void){

  //RF
  RF_SESSION(); //RF komunikacija (Distant tank watter level check)
  //GSM
  GSM_PROCESS(); //GSM services (GSM communication and controll)
  //Voltage
  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
  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

PHP
 <?php 
 date_default_timezone_set("Europe/Ljubljana");


//echo 'Hello World';
$RAW=file_get_contents("php://input");
//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=324&TS=2354&MTW=234

// $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;
    exit;
}

//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;
				responce($error_int);
			}


$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);
		mysqli_close($connect);
		die();
	}

mysqli_close($connect);	








  ?> 

PHP script for OpenWeather API

PHP
<?php
$apiKey = #your_api_key;

if(isset($_POST['submit'])){	
	$cityName = $_POST['kraj'];
	dobi_vreme($cityName,$apiKey);
}	else{
	$cityName = "Ljubljana";
	dobi_vreme($cityName,$apiKey);
}


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);

	curl_close($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();
	$j=0;
	for ($i=0; $i <= 15; $i+=5) {
		$t[$j]= round($data->list[$i]->main->temp);
		if(isset($data->list[$i]->rain)){
			$rain[$j] = $data->list[$i]->rain->{'3h'};
		}
		else{
			$rain[$j] = 0;
		}
		
		$j++;
	}


}



?>

Credits

Rok Vidmar

Rok Vidmar

1 project • 1 follower
Darjo Uršič

Darjo Uršič

0 projects • 2 followers
MATEVĹ˝ JELENKO

MATEVĹ˝ JELENKO

0 projects • 1 follower
Kristjan Jurčič

Kristjan Jurčič

0 projects • 1 follower

Comments