Smart Farming System

3 14217 Medium

A Smart Farming System that is unlike anything you have ever seen before! Our innovative Smart Farm will deter pests and detect intruders!

projectImage

Things used in this project

 

Hardware components

HARDWARE LIST
1 DFRobot 6 DOF Sensor - MPU6050
1 DFRobot Gravity: I2C BME280 Environmental Sensor
1 DFRobot Gravity: Analog Capacitive Soil Moisture Sensor- Corrosion Resistant
1 Adafruit Ultimate GPS Breakout
1 ElectroPeak 0.96" OLED 64x128 Display Module
1 Seeed Studio Grove - Dust Sensor(PPD42NS)
1 Digilent Stepper Motor
1 SparkFun Stepper motor driver board A4988
1 Ultrasonic Sensor - HC-SR04 (Generic)
1 Breadboard (generic)
1 Particle Argon
1 Battery Charger for 1 Cell of NiMH battery, 5.5V input
1 Development Kit Accessory, Solar Cell

Software apps and online services

 

Microsoft Visual Studio Code Extension for Arduino

 

Slack

 

Github

 

makercase.com

 

Fritzing

 

Adobe Illustrator

 

Hackster.io

 

Adafruit.IO

Hand tools and fabrication machines

 

Laser cutter (generic)

 

Plier, Long Nose

 

Plier, Cutting

 

Wire Stripper, Serrated Plier Nose

 

Hot glue gun (generic)

Story

 

This innovative smart farm system will alleviate the tedious but crucial work that farmers all over the globe suffer from. The system will be able to communicate with the farmers anywhere that there is a smart device with Bluetooth capabilities. In comparison to previous farming systems, this smart farming system is the tesla of farming systems because it utilizes the newest in cutting edge technology in order to boost yields and maintain farmer morale!

 

The PURPOSE of this project came about because of real-life experiences during New Mexico’s first hemp farming season in 2019.

 

Hemp legalization occurred under the 2019 Farm Bill, which was passed on December 20, 2018; however, an approved USDA Domestic Hemp Production Program was not established until March 22, 2021.​​ Since farmers had no established guidance from the USDA; the first 2 hemp farming seasons were negatively impacted.​​ One of the hardest hit aspects of hemp farming was PESTCONTROL. This was because there were no approved pesticides to keep hemp crops free from diseases and pests.​ With more farms going organic, the pesticide problem needs to be addressed. Another problematic factor hemp farmers are dealing with is physical SECURITY and safe keeping of hemp. Hemp contains Delta 9 tetrahydrocannabinol (THC) which is listed under Schedule I by US federal law[16] under the Controlled Substances Act. The THC content creates a unique aspect, theft. Theft is problematic not only because of the loss in yield but also because of the farmer’s legal responsibility to maintain control of all THC production. Another factor farmers dealt with and still are dealing with is controlling hemp POLLINATION. When hemp is pollinated, it begins the process of seed propagation and in turn DECREASES trichome production.​ Trichomes are the mechanism by which hemp produces cannabinoids, such as cannabidiol (CBD) Majority of New Mexican farmers grew high CBD hemp strains to​ produce, manufacture and sell high quality CBD hemp OIL not seeds.

 

The Smart Farming System houses a weather station and a plant monitoring system.​ The weather station is comprised of 2 components and a cloud- based website. ​The first component is the BME280 which is a temperature, humidity and pressure sensor.​ The second component is a monochrome I2C OLED Display unit with a 128 x 64 resolution dot matrix panel.​ The weather data can be accessed from anywhere in the world via Adafruit.io which provides real-time data on the status of the crop’s environment. The plant monitoring system comprises of two components, a soil sensor and the Grove Dust sensor. Both of these components are rather simple in both implantation and function; however, they both play critical roles in alleviating burden from farmers. The soil sensor is implanted directly into the ground via stake, and gathers the moisture readings from the surrounding region in order to aid the farmer in determining plant health. The dust sensor sits inside of our fabricated box in order to gather pollen readings in a valiant attempt to aid the farmer in determining the overall pollination levels in the surrounding region. Both of these two systems can be monitored in a user friendly interface known as Adafruit.IO dashboard, in which, the data has already been collected, converted, and crafted to be aesthetically pleasing.

 

The Smart Farming System also houses a security system and pest deterrent system. The components necessary for these functions are the Ultrasonic Sensor, the Stepper motor and it's driver board. The Stepper motor's only function is to turn the Ultrasonic sensor 180 degrees and back to its starting position. The main magic comes from the Ultrasonic sensor! This advanced sensor coupled with our innovative code and thinking, can pulse out frequencies that will naturally deter pests from the given region (26 feet). Furthermore, the Ultrasonic sensor also has the capability to simultaneously count the amount of time between each given pulse and its return in order to determine not only distance, but INTRUDERS as well! This component will notify the farmer about any changes in location pulsing via SMS text messaging through Zapier.com as well as by changing the colors on the Adafruit.IO dashboard.

 

Finally, the Smart Farming System has two vital functions! The second to last is GPS and fall detection systems. The GPS functions are utilized in determining the location of the unit but this function is catered more towards large farm field owners. Furthermore, the GPS constantly populates a street map of real time coordinates on the Adafruit.IO dashboard. The fall detection system utilizes the MPU 6050 component in order to constantly give back data as to the orientation of the box. This data is expected to consistently give back the same date (primarily because the box stays in place). However, if the MPU reads a change in data on any of the axis planes (Z, X, Y), it will notify the farmer via SMS text message as well as changing the colors on the Adafruit.IO dashboard.

 

Here is the link to our Adafruit.IO dashboard: IO - Smart Farming System(adafruit.com)

 

Here is the link to our GitHub repository: Smart Farming Project (github.com)

 

Stephanie working hard

 

Stephanie working hard

 

Picture of the enclosure

 

Picture of the enclosure

 

Stephanie holding the robo head

 

Stephanie holding the robo head

 

The laser cut outs

 

The laser cut outs

 

Kareem just doing his job

 

Kareem just doing his job

 

Stephanie cradling the baby

 

Stephanie cradling the baby

 

 

Schematics

 

Fritzing Diagram for Smart Farming System

This the Fritzing diagram

icon smart-farm-systemfritz_0AIPrTwW63.zip 238KB Download(0)

Code

 

Smart Farming Code

C/C++

To work the farm

CODE
/*
 * Project Master-Code
 * Description: The Smart Farming System Master Code
 * Author: Stephanie Perea and Kareem Crum
 * Date: 19-MAY-2021
 */
#include <TinyGPS++/TinyGPS++.h>
#include <Adafruit_MQTT.h>

#include "math.h"
#include "Adafruit_MQTT/Adafruit_MQTT.h" 
#include "Adafruit_MQTT/Adafruit_MQTT_SPARK.h" 
#include "Adafruit_MQTT/Adafruit_MQTT.h"
#include "Adafruit_SSD1306.h"
#include "Adafruit_GFX.h"
#include "Adafruit_BME280.h"
#include "Adafruit_Sensor.h"
#include "Particle.h"
#include "Stepper.h"
#include "credentials.h"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET    D4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define XPOS 0
#define YPOS 1
#define echoPin D6 // attach pin D6 Arduino to pin Echo of HC-SR04
#define trigPin D7 //attach pin D7 Arduino to pin Trig of HC-SR04



//Global State
TCPClient TheClient;

//Adafruit BME class
Adafruit_BME280 bme;

//Adafruit OLED Class
Adafruit_SSD1306 display(OLED_RESET);

//Stepper Class
Stepper myStepper(2048, D5, D3, D4, D2);

//MQTT Client Class
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY); 

//TinyGPS++ Object
TinyGPSPlus gps;

//Feeds
Adafruit_MQTT_Publish Trigger = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/UltraSonic");
Adafruit_MQTT_Publish Satellites = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Satellites");
Adafruit_MQTT_Publish GPS = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Location");
Adafruit_MQTT_Publish Moist = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/SoilMoisture");
Adafruit_MQTT_Publish Pressure = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Pressure");
Adafruit_MQTT_Publish Humid = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity");
Adafruit_MQTT_Publish Temp = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temperature");
Adafruit_MQTT_Publish Dust = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/DustSensor");
Adafruit_MQTT_Publish FallSense = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Acceleration");


//Variable for BMe
float tempC;
float humidRH;
float pressPA;
float tempF;
float inHg;

//Variables for Soil Sensor
int soilSensor = A1;
int soilMoisturePercent; 
int soilMoistureValue; 

//Variables for DustSensor
unsigned long dustTime;
unsigned long duration;
unsigned long lastMQTT;
unsigned long lastPub;
int dustSensor = A0;
float dustSense;
unsigned long lowpulseoccupancy = 0;
float concentration = 0;
float ratio = 0;

//Variables for UltraSonic Sensor
long amount; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
bool intruder;

//Variables for Stepper and OLED
const int stepsRev = 2048;
int16_t stepperSpeed=15;
int16_t stepperSteps;

//Variables for GPS
const unsigned long PUBLISH_PERIOD = 120000;
const unsigned long SERIAL_PERIOD = 5000;
const unsigned long MAX_GPS_AGE_MS = 10000; // GPS location must be newer than this to be considered valid
const int UTC_offset = -6; 
unsigned long lastSerial = 0;
unsigned long lastPublish = 0;
unsigned long startFix = 0;
bool gettingFix = false;
char buffer[50];
uint8_t hr,mn,se,sat;
float lat,lon,alt;

//Variables for Acceleromotor
byte accel_x_h, accel_x_L;
int16_t accel_x;
float accelX;

byte accel_y_h, accel_y_L;
int16_t accel_y;
float accelY;

byte accel_z_h, accel_z_L;
int16_t accel_z;
float accelZ;
float accelTot;

bool MPUfall = false;
float MPUValue = 0.0;
const float fall = 1.0;

SYSTEM_MODE(SEMI_AUTOMATIC);

// setup() runs once, when the device is first turned on.
void setup() 
{
  // Put initialization like pinMode and begin functions here.
  pinMode(soilSensor, INPUT);
  pinMode(dustSensor, INPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT

  dustTime = millis();

  Serial.begin(9600);

//I2C Setup
  Wire.begin();

  Wire.beginTransmission(0x68);

  Wire.write(0x6B);
  Wire.write(0);

  Wire.endTransmission(true);

//GPS Setup
	Serial1.begin(9600);
	startFix = millis();
	gettingFix = true;

	Serial.println(F("DeviceExample.ino"));
	Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
	Serial.print(F("Testing TinyGPS++ library v. ")); 
	Serial.println(TinyGPSPlus::libraryVersion());
	Serial.println(F("by Mikal Hart"));
	Serial.println();

	//OLED Setup
	display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
	helloWorld();
	Serial.printf("Hello World \n");

  bool status;
  status = bme.begin(0x76);
  myStepper.setSpeed(15);
  myStepper.step(0);

  Serial.printf("Connecting to Internet \n");
  WiFi.connect();
  while(WiFi.connecting()) 
  {
    Serial.printf(".");
    delay(100);
  }
  Serial.printf("\n Connected!!!!!! \n");

  //UltraSonic Sensor Setup
  Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
  Serial.println("with Argon");

}

// loop() runs over and over again, as quickly as it can execute.
void loop()
{
  // The core of your code will likely live here.
  codingFunction();
  printValues();
  adafruitPublish();
  MQTT_connect();
}

void helloWorld() 
{
	display.clearDisplay();
	display.setTextSize(1);
	display.setTextColor(WHITE);
	display.setCursor(20,5);
	display.println("GPS Initializing");
	display.display();
}

void codingFunction()
{

  //Code for Stepper Motor
    myStepper.setSpeed(7);
    myStepper.step(1024);
    delay(2000);
    myStepper.step(-1024);
    delay(2000);

  //Code for Dust Sensor
  duration = pulseIn(dustSensor, LOW);
  lowpulseoccupancy = lowpulseoccupancy + duration;
  if ((millis()-dustTime) >= 30000)
  {
    ratio = lowpulseoccupancy/(30000*10.0);
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    if(concentration > 1){
      dustSense = concentration;
    }
    lowpulseoccupancy = 0;
    dustTime = millis();
  }
  
  //Code for Soil Sensor
  soilMoistureValue = analogRead(soilSensor);
  Serial.printf("Soil moisture is %i\n", soilMoistureValue);
  soilMoisturePercent = map(soilMoistureValue, 1800, 3500, 100, 0);
 
 //Code for UltraSonic Sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  amount = pulseIn(echoPin, HIGH);
  Serial.println("The Data is:");
  // Calculating the distance
  distance = amount * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  if(distance <=96)
  {
    intruder = true;
    adafruitPublish();
  }

 //Code for BME
  tempC = bme.readTemperature();
  tempF = map(tempC,0.0,100.0,32.0,212.0);
  pressPA = bme.readPressure();
  inHg = pressPA/3386.389;
  humidRH = bme.readHumidity();
  
  //Code for Acceleromotor
  float accelZ, accelX, accelY;
  delay(1000);
  findAcceleration();
  
  Wire.requestFrom(0x68, 6, true);
  accel_x_h = Wire.read();
  accel_x_L = Wire.read();
  accel_x = accel_x_h << 8 |accel_x_L;
  accelX = accel_x / 15000.0;
  Serial.printf("X-axis acceleration is %0.2f\n", accelX);

  accel_y_h = Wire.read();
  accel_y_L = Wire.read();
  accel_y = accel_y_h <<8 | accel_y_L;
  accelY = accel_y / 16000.0;
  Serial.printf("Y-axis acceleration is %0.2f\n", accelY);

  accel_z_h = Wire.read();
  accel_z_L = Wire.read();
  accel_z = accel_z_h << 8 | accel_z_L;
  accelZ = accel_z / 15250.0;
  Serial.printf("Z-axis acceleration is %0.2f\n", accelZ);
  
  accelTot = sqrt(pow(accelX,2)+pow(accelY,2)+pow(accelZ,2));
  Serial.printf("Accel Total Value: %0.2f \n", accelTot);

  if(!MPUfall) 
  {
    MPUValue = accelTot;
    MPUfall = (MPUValue > fall);
    Serial.printf("MPU Value is %0.2f\n", MPUValue);
  }

  //Code for GPS
   while (Serial1.available() > 0)
  {
    if (gps.encode(Serial1.read()))
	 { 
      displayInfo();
   }
  }
  delay(1000);

}

void findAcceleration()
{

  Wire.beginTransmission(0x68);
  Wire.write(0x3B);
  Wire.endTransmission(false);

}

void displayInfo()
{
	float lat,lon,alt;
	uint8_t hr,mn,se,sat;
	if (millis() - lastSerial >= SERIAL_PERIOD)
	{
		lastSerial = millis();

		char buf[128];
		if (gps.location.isValid() && gps.location.age() < MAX_GPS_AGE_MS) 
		{
			lat = gps.location.lat();
			lon = gps.location.lng(); 
			alt = gps.altitude.meters();
			hr = gps.time.hour();
			mn = gps.time.minute();
			se = gps.time.second();
			sat = gps.satellites.value();

			if(hr > 7) 
			{
				hr = hr + UTC_offset;
			}
			else 
			{
				hr = hr + 24 + UTC_offset;
			}
			Serial.printf("Time: %02i:%02i:%02i --- ",hr,mn,se);
			Serial.printf("lat: %f, long: %f, alt: %f \n", lat,lon,alt);
			if (gettingFix) 
			{
				gettingFix = false;
				unsigned long elapsed = millis() - startFix;
				Serial.printlnf("%lu milliseconds to get GPS fix", elapsed);
			}
			display.clearDisplay();
			display.setCursor(0,0);
			display.printf("Time: %02i:%02i:%02i \n",hr,mn,se);
			display.printf("lat  %f \nlong %f \nalt %f\n", lat,lon,alt);
			display.printf("satelites %i", sat);
			display.display();
      createEventPayload(lat, lon, alt, sat);
    }
    else 
		{
			strcpy(buf, "no location");
			if (!gettingFix) 
			{
				gettingFix = true;
				startFix = millis();
			}
		}
	}

}

void createEventPayload(float jlat, float jlon, float jalt, int sat)
{
  sprintf(buffer, "{\"lat\":%0.6f,\"lon\":%0.6f,\"ele\":%0.2f}", jlat, jlon, jalt); 
  
}

void printValues() 
{
    Serial.printf("Temperature = %f\n", tempF);
    Serial.print(bme.readTemperature());
    Serial.println(" *F");
    
    Serial.printf("Pressure = %f\n", inHg);
    Serial.print(bme.readPressure());
    Serial.println(" hPa");

    Serial.printf("Humidity = %f\n", humidRH);
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println("cm");
    
    Serial.printf("Moist: %i %%\n", soilMoisturePercent);
    Serial.printf("Dust: %0.2f\n", dustSense);

    Serial.println();
}

void adafruitPublish()
{
    //Code for Adafruit.IO
    if(intruder)
    {
      Trigger.publish(distance);
      intruder = false;
    }
    if((millis()-lastPub > 30000)) 
    {
      if(mqtt.Update()) 
      {
        Serial.printf("Publishing %s\n", buffer);
        GPS.publish(buffer);
        Moist.publish(soilMoisturePercent);
        Temp.publish(tempF);
        Humid.publish(humidRH);
        Dust.publish(dustSense);
        Pressure.publish(inHg);  
        Satellites.publish(sat);
        if(MPUfall)
        {
          FallSense.publish(MPUValue);
          Serial.printf("MPU Fell %0.2f\n", MPUValue);
          MPUfall = false;
          MPUValue = 0.0;
        }
      } 
      lastPub = millis();
    }
}

void MQTT_connect() 
{
  int8_t ret;
 
  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }
 
  Serial.print("Connecting to MQTT... ");
 
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
    // Ping MQTT Broker every 2 minutes to keep connection alive
  if ((millis()-lastMQTT)>120000) 
  {
      Serial.printf("Pinging MQTT \n");
      if(! mqtt.ping()) {
        Serial.printf("Disconnecting \n");
        mqtt.disconnect();
      }
      lastMQTT = millis();
  }
}

The article was first published in hackster, May 21, 2022

cr: https://www.hackster.io/stephanie-and-kareem/smart-farming-system-3ad87e

author: Team Stephanie and Kareem: Kareem Crum, Stephanie Perea

License
All Rights
Reserved
licensBg
3