Project tutorial
AggroFox: Large-Scale and Urban Agriculture IoT Solution

AggroFox: Large-Scale and Urban Agriculture IoT Solution © MIT

IoT sensing, notifications, and analytics platform for urban and large-scale agriculture with automated irrigation, using Sigfox technology.

  • 7,969 views
  • 1 comment
  • 31 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
Screwdrivers
Soldering Tools

Apps and online services

About this project

AggroFox is an IoT sensing, notifications, dashboard and analytics platform for urban and large-scale agriculture with automated irrigation, using Sigfox technology.

Introduction

Imagine a world where there is not enough food for you and your loved ones, an arid world where there is nothing to satisfy your hunger. Because of the current methods of agriculture, where excess fertilizers and pesticides have been used. These methods are not sustainable and we have to find new methods to optimize crops. Remember, we cannot create new land to grow crops, and the water reserves are being reduced each year. For that, Industry 3.0, with IoT, Big Data and predictive analysis solutions have to emerge to avoid this scenario from happening.

Problem

Let's take a look at some facts:

• The population in Mexico (Both of the author's own country) and in the world will grow.

• By 2050 the production of food will have to DOUBLE to feed this population.

• The amount of arable Land will not increase.

• The amount of Water available will be decreasing.

• Sustainable Disruption is needed.

• Current methods are insufficient for this.

• Infrastructure is costly.

• Most fields are in remote areas.

• Urban agriculture needs a cheap and readily available solution, for it to be sustainable.

If only there was a way to monitor the field through a network of sustainable sensors, which could be monitored in real time 365 days a year, performing data analytics in the cloud and taking weather predictions to generate models. Taking all this information to manage resources such as water, in order to save most of them, and above all being powered by solar panels ....... oh wait, there is Aggrofox!

Our Solution

Our solution to the problem was to create a sustainable platform of sensing and irrigation automation with predictive analysis via cloud. With one objective in mind: SAVE WATER.

1. Using a temperature/humidity, soil moisture and soil temperature sensors, we used a Pycom FiPy dev board with Sigfox technology to obtain sensor data every 6 min. Sigfox chosen because the characteristics of long range and low power are excellent for remote areas.

  • Each batch of sensing is done at this frequency to send 120 data per day and not pass the data quota of Sigfox which is 140 data packets per day.
  • For this system it was decided to use an Arduino board to obtain the data from the sensors (using the vast array of libraries from Arduino) and send them through Serial at 9600 baud rate to the Pycom FiPy board.
  • Once on the Pycom board we receive the data from the sensors and through Sigfox we send them to the Sigfox Backend platform.

On the image above, you can see:

A. The main sensor circuit, with the Pycom FiPy with Sigfox and the sensors connected, also the solar power management.

B. The irrigation system circuit that uses a Particle Photon and a Solenoid Valve.

C. An implementation of the system.

The build process required some prototiping boards and basic soldering equipment. After that get some cases, they do not have to be 3D printed just grab whatever fits and get creative!

After that we added a hose and the Solar Panel and adapted for the chosen implementations. Also needed were some plumbing supplies to adapt it to the irrigation system or garden hose, and covering the electrical parts of the solenoid.

2. Once the data is in the Sigfox Backend, we send the data through a callback to the Thingspeak website through its API (more information in the link below).

Link: https://github.com/EddOliver/AggroFox/tree/master/Sigfox%20Configuration/Aggrofox%20Conf

3. Once we have the data at Thingspeak, through the Thingspeak API we send the data to IBM Bluemix.

  • On the Bluemix platform, we made it possible to develop almost any application with the obtained data. (All the applications are based on Node Red to make the prototyping easier).
  • Examples of these applications:Generate databases of our crops and their conditions.Do data analysis to obtain predictive models in the long term.Water automation systems with the data obtained (as we do in this project).Crop yield analysis.

3.1. We made a Dashboard with the data obtained for the complete and simple visualization of the data.

These other images above show the Web Desktop Dashboard and some screenshots of the mobile version.

  • For the application, we made a data crossing with the OpenWeatherMap API, to perform the control of an electrovalve connected to a Particle Photon microcontroller.
  • The crossing of data obtained is used to check if that day is going to rain and thus not use irrigation water in crops.
  • Also if the system detects that water is needed in the field by the humidity sensors, the irrigation system is turned on.
  • In turn once a day an email will be sent to the farmer with the general information of his field or he can check anytime on his dashboard.
  • Also everytime the irrigation system is online, a notification will be sent.

The notifications can be email, SMS, messages etc.

Here are some images of the solution implemented on various crops:

Video

AggroFox in action.

Getting Started

We now provide you with an extensive tutorial to do the full project. Every step is explained and all the parts are needed to get to the final product.

1. Do the first configuration for your board.

Link: https://github.com/EddOliver/AggroFox/tree/master/Sigfox%20Configuration/First%20Configuration

2. Enter the following folder: AggroFox Configuration, and complete all the steps to perform the corresponding configuration.

Link: https://github.com/EddOliver/AggroFox/tree/master/Sigfox%20Configuration/Aggrofox%20Conf

3. Do the Arduino configuration.

Link: https://github.com/EddOliver/AggroFox/tree/master/Arduino%20Code

4. Do the Pycom configuration.

Link: https://github.com/EddOliver/AggroFox/tree/master/Pycom%20Code

5. Make the circuits:

Link: https://github.com/EddOliver/AggroFox/tree/master/Circuit

6. Link it to IBM IoT Cloud for amazing dashboards, data storage and access to other cloud services.

Link: https://github.com/EddOliver/AggroFox/tree/master/IBM%20cloud%20AggroFox

7. Automation of irrigation via IBM cloud with weather forecast.

Link: https://github.com/EddOliver/AggroFox/tree/master/Irrigation%20System

8. Going Green (Add a Solar panel to your sensor module).

Link: https://github.com/EddOliver/AggroFox/tree/master/Solar%20Power

Enjoy!!

Full Repository: https://github.com/EddOliver/AggroFox

Future Rollout

• Adding a water fluxometer to know exactly how much water we use.

• Custom PCB for all the hardware components.

• Maybe migrate to the SiPy version of the Pycom Board.

• Get the data to a SQL database for long term predictive ML models.

• Expand to the use of several other clouds such as AWS and Google cloud which we already dominate.

• Replace the Particle Photon with Sigfox for the actuators so it uses only one communication platform.

References:

All the information about the technology used and direct references are in our Wiki: https://github.com/EddOliver/AggroFox/wiki

Code

Node-RED flow JavaScript
Node-RED flow that uses the openweathermap API, and the sensor readings to do data analytics and proceed to act, and in fact joins the whole platform.
[{"id":"d71476d5.e80198","type":"ui_gauge","z":"db15ed1.447301","name":"Tempamb","group":"1140416a.87e79f","order":0,"width":0,"height":0,"gtype":"gage","title":"","label":"°C","format":"{{value}}","min":0,"max":"55","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":818.888916015625,"y":61.111106872558594,"wires":[]},{"id":"741a342.e69decc","type":"inject","z":"db15ed1.447301","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":215.888916015625,"y":165.6111068725586,"wires":[["dd05b948.077978","31701415.b696cc"]]},{"id":"dd05b948.077978","type":"http request","z":"db15ed1.447301","name":"letempambchannel","method":"GET","ret":"obj","url":"","tls":"","x":399.888916015625,"y":193.9111099243164,"wires":[["322f8c31.bd4414","12ed7168.d0c4df","c172e706.5a17b8","72ffade5.3f5ab4","308cd76f.f79048"]]},{"id":"322f8c31.bd4414","type":"function","z":"db15ed1.447301","name":"Field1","func":"msg.payload = msg.payload.field1\nmsg.topic= msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":597.888916015625,"y":174.9111099243164,"wires":[["d71476d5.e80198","4f88b838.66f648"]]},{"id":"12ed7168.d0c4df","type":"function","z":"db15ed1.447301","name":"Field 2","func":"msg.payload = msg.payload.field2\nmsg.topic = msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":598.888916015625,"y":238.91109466552734,"wires":[["c0d96316.47c43","593ff4f5.3adbdc","c62f10b4.e10b7"]]},{"id":"c172e706.5a17b8","type":"function","z":"db15ed1.447301","name":"Field 3","func":"msg.payload = msg.payload.field3\nmsg.topic = 'Soil Temperature';\nreturn msg;","outputs":1,"noerr":0,"x":600.888916015625,"y":305.91109466552734,"wires":[["2406b943.7f83e6","51e17274.c84d4c","1498d2e9.247bfd"]]},{"id":"72ffade5.3f5ab4","type":"function","z":"db15ed1.447301","name":"Field 4","func":"msg.payload = msg.payload.field4\nmsg.topic = 'Soil Temperature';\nreturn msg;","outputs":1,"noerr":0,"x":739.888916015625,"y":498.9110641479492,"wires":[["8de7ad32.016bb","edb70d8.11d02f"]]},{"id":"308cd76f.f79048","type":"function","z":"db15ed1.447301","name":"Field 5","func":"msg.payload = msg.payload.field5\nmsg.topic = 'Soil Temperature';\nreturn msg;","outputs":1,"noerr":0,"x":693.888916015625,"y":596.9110336303711,"wires":[["faa295a5.21e348","573b06ef.515c48"]]},{"id":"4f88b838.66f648","type":"ui_chart","z":"db15ed1.447301","name":"","group":"1140416a.87e79f","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"dd HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"604800","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":837.888916015625,"y":189.1111068725586,"wires":[[],[]]},{"id":"c0d96316.47c43","type":"ui_gauge","z":"db15ed1.447301","name":"","group":"347821f3.6d19be","order":0,"width":0,"height":0,"gtype":"gage","title":"","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":852.888916015625,"y":256.1111068725586,"wires":[]},{"id":"593ff4f5.3adbdc","type":"ui_chart","z":"db15ed1.447301","name":"","group":"347821f3.6d19be","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"dd HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0f","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":848.888916015625,"y":296.1111068725586,"wires":[[],[]]},{"id":"2406b943.7f83e6","type":"ui_text","z":"db15ed1.447301","group":"cea5e94f.0954a8","order":0,"width":0,"height":0,"name":"","label":"32.2 °C is optimal Heat index","format":"{{msg.payload}}","layout":"row-spread","x":918.888916015625,"y":349.1111068725586,"wires":[]},{"id":"51e17274.c84d4c","type":"ui_chart","z":"db15ed1.447301","name":"","group":"cea5e94f.0954a8","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9367bc","#c5b0d5"],"useOldStyle":false,"x":839.888916015625,"y":392.1111068725586,"wires":[[],[]]},{"id":"1498d2e9.247bfd","type":"ui_gauge","z":"db15ed1.447301","name":"","group":"cea5e94f.0954a8","order":0,"width":0,"height":0,"gtype":"gage","title":"gauge","label":"°C","format":"{{value}}","min":"15","max":"44.4","colors":["#fff647","#0fe600","#ca3838"],"seg1":"","seg2":"","x":847.888916015625,"y":436.1111068725586,"wires":[]},{"id":"8de7ad32.016bb","type":"ui_gauge","z":"db15ed1.447301","name":"","group":"c9ffe2c3.b2bee","order":0,"width":0,"height":0,"gtype":"gage","title":"","label":"°C","format":"{{value}}","min":0,"max":"55","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":922.888916015625,"y":487.11104583740234,"wires":[]},{"id":"edb70d8.11d02f","type":"ui_chart","z":"db15ed1.447301","name":"","group":"c9ffe2c3.b2bee","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"dd HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#99df8b","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":919.888916015625,"y":527.1110458374023,"wires":[[],[]]},{"id":"faa295a5.21e348","type":"ui_gauge","z":"db15ed1.447301","name":"","group":"9304bf1b.ac483","order":0,"width":0,"height":0,"gtype":"gage","title":"gauge","label":"%","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":895.888916015625,"y":576.1110458374023,"wires":[]},{"id":"573b06ef.515c48","type":"ui_chart","z":"db15ed1.447301","name":"","group":"9304bf1b.ac483","order":0,"width":0,"height":0,"label":"","chartType":"line","legend":"false","xformat":"dd HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9367bc","#c5b0d5"],"useOldStyle":false,"x":899.888916015625,"y":614.1110458374023,"wires":[[],[]]},{"id":"31701415.b696cc","type":"openweathermap","z":"db15ed1.447301","name":"mexa weather","wtype":"forecast","lon":"","lat":"","city":"your city","country":"your country","language":"en","x":273.888916015625,"y":338.66109466552734,"wires":[["5f4900a3.6190e","e7a5f1c8.5a3e6"]]},{"id":"5f4900a3.6190e","type":"debug","z":"db15ed1.447301","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":395.888916015625,"y":257.76110076904297,"wires":[]},{"id":"e7a5f1c8.5a3e6","type":"function","z":"db15ed1.447301","name":"","func":"msg.payload= msg.payload[0].weather[0].main\nmsg.count = msg.payload\nreturn msg;","outputs":1,"noerr":0,"x":401.888916015625,"y":396.91109466552734,"wires":[["fc38b1e6.25317","f91a9562.a44228","e6fddeb2.80055","25fab1ba.80622e"]]},{"id":"fc38b1e6.25317","type":"debug","z":"db15ed1.447301","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":567.888916015625,"y":515.761100769043,"wires":[]},{"id":"f91a9562.a44228","type":"ui_text","z":"db15ed1.447301","group":"3f5cb968.f8d436","order":0,"width":0,"height":0,"name":"","label":"Weather forecast for the next 5 hours:","format":"{{msg.payload}}","layout":"row-spread","x":416.888916015625,"y":579.1110763549805,"wires":[]},{"id":"f6ffaae2.ceb3b8","type":"ParticleFunc out","z":"db15ed1.447301","baseurl":"","devid":"your device name","fname":"led","param":"","once":false,"repeat":0,"consolelog":false,"x":699.888916015625,"y":688.531120300293,"wires":[["a89561ff.e04d2"]]},{"id":"3256e5e6.f45a0a","type":"inject","z":"db15ed1.447301","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":246.888916015625,"y":646.6110763549805,"wires":[["f6ffaae2.ceb3b8"]]},{"id":"a89561ff.e04d2","type":"debug","z":"db15ed1.447301","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1030.888916015625,"y":737.761100769043,"wires":[]},{"id":"6dfced87.1b7e54","type":"inject","z":"db15ed1.447301","name":"","topic":"","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":215.888916015625,"y":692.6110763549805,"wires":[["f6ffaae2.ceb3b8"]]},{"id":"c62f10b4.e10b7","type":"link out","z":"db15ed1.447301","name":"","links":["17e4713e.55e1bf"],"x":835.888916015625,"y":124.76111602783203,"wires":[]},{"id":"17e4713e.55e1bf","type":"link in","z":"db15ed1.447301","name":"","links":["c62f10b4.e10b7"],"x":133.888916015625,"y":761.6110763549805,"wires":[["25fab1ba.80622e"]]},{"id":"25fab1ba.80622e","type":"function","z":"db15ed1.447301","name":"","func":"if (msg.topic<=10 && msg.count != 'Rain' && msg.count !=null){\n    msg.payload= 'on'\n}\nelse{\n    msg.payload= 'off'\n}\nreturn msg;","outputs":1,"noerr":0,"x":476.888916015625,"y":722.9111251831055,"wires":[["f6ffaae2.ceb3b8"]]},{"id":"e6fddeb2.80055","type":"debug","z":"db15ed1.447301","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"count","x":503.888916015625,"y":805.761100769043,"wires":[]},{"id":"9ec9146.d9b39e8","type":"inject","z":"db15ed1.447301","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":167.888916015625,"y":426.6111068725586,"wires":[["b7785f17.e9d8a"]]},{"id":"b7785f17.e9d8a","type":"function","z":"db15ed1.447301","name":"","func":"msg.count = 'Arid'\nreturn msg;","outputs":1,"noerr":0,"x":196.888916015625,"y":480.91109466552734,"wires":[["25fab1ba.80622e"]]},{"id":"abb64b9d.401e58","type":"inject","z":"db15ed1.447301","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":286.888916015625,"y":849.6110763549805,"wires":[["25fab1ba.80622e"]]},{"id":"1140416a.87e79f","type":"ui_group","z":"","name":"Soil Temperature","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"347821f3.6d19be","type":"ui_group","z":"","name":"Soil Moisture","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"cea5e94f.0954a8","type":"ui_group","z":"","name":"Heat Index","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"c9ffe2c3.b2bee","type":"ui_group","z":"","name":"Temperature (ambient)","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"9304bf1b.ac483","type":"ui_group","z":"","name":"Humidity","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"3f5cb968.f8d436","type":"ui_group","z":"","name":"Weather Forecast","tab":"dbbcdb89.f7c1c8","disp":true,"width":"6","collapse":false},{"id":"dbbcdb89.f7c1c8","type":"ui_tab","z":"","name":"AggroFox","icon":"dashboard"}]
Pycom FiPy Sigfox code.MicroPython
Pycom FiPy Sigfox code.....please, please, please always use the antenna. The code is to receive the sensor data from the arduino and then publish it in the Sigfox Backend.
from network import Sigfox
import socket
from machine import UART
# this uses the UART_1 default pins for TXD and RXD (``P3`` and ``P4``)
uart = UART(1, baudrate=9600)
dato="mensaje"
i=0

while i==0:
    dato = uart.read(12) # read up to 5 bytes}
    if dato == None:
        i=0
    else:
        print(dato.decode())
        i=1
print ("Recibidos")

datos=dato.decode()
tempe = int(datos[0:-10])
hume = int(datos[2:-8])
inde = int(datos[4:-6])
tempa = int(datos[6:-4])
huma = int(datos[8:-2])
inda = int(datos[10:])

# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ2)

# create a Sigfox socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)

# make the socket blocking
s.setblocking(True)

# configure it as uplink only
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)

# send some bytes
# s.send(bytes([temp,hume,inde,tempa,huma,inda]))
s.send(bytes([tempe,hume,inde,tempa,huma,inda]))

print("Datos Enviados")
Arduino Code C/C++
Code to send the sensor data to the pycom board via serial @ 9600 bauds.
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
#include "DHT.h"
#include <SoftwareSerial.h>

// All define components
#define ONE_WIRE_BUS A1
#define humedad A3
#define temp    A2
#define DHTTYPE DHT11
#define minu 60000

// Setup libraries variables
OneWire oneWire(ONE_WIRE_BUS);
DHT dht(temp, DHTTYPE);
SoftwareSerial mySerial(13, 10); // RX(DONT CARE) , TX (Pycom Serial Communication)

// DallasTemperature sensors definition
DallasTemperature sensors(&oneWire);

/*
 * The setup function. We only start all sensors here
 */
void setup(void)
{ 
  mySerial.begin(9600);
  Serial.begin(9600);
  sensors.begin();
  dht.begin();
}

/*
 * Main function, get all the sensor data
 */
void loop(void)
{
  sensors.requestTemperatures();
  int hume = analogRead(humedad);
  int hum  = map(hume, 0, 1023, 0, 950);
  int humes = -(hum*100)/950;
  int h = int(dht.readHumidity());
  int t = int(dht.readTemperature());
  int hica = int(dht.computeHeatIndex(t, h,false));
  int te = int(sensors.getTempCByIndex(0)); // Send the command to get temperatures
  int hice = int(dht.computeHeatIndex(sensors.getTempCByIndex(0), ((hum*100)/950),false));

// Serial Strings Declaration

  String dte;
  String dhume;
  String dhe;
  String dta;
  String dhuma;
  String dha;


  // These conditional forces the serial string to have the format of two digits for each value

  if (te < 10)
  {
    dte=String(0)+String(te);
  }
  else
  {
    dte=String(te);
  }
  if (humes < 10)
  {
    dhume=String(0)+String(humes);
  }
  else
  {
    dhume=String(humes);
  }
  if (hice < 10)
  {
    dhe=String(0)+String(hice);
  }
  else
  {
    dhe=String(hice);
  }
    if (t < 10)
  {
    dta=String(0)+String(t);
  }
  else
  {
    dta=String(t);
  }
    if (h < 10)
  {
    dhuma=String(0)+String(h);
  }
  else
  {
    dhuma=String(h);
  }
    if (hica < 10)
  {
    dha=String(0)+String(hica);
  }
  else
  {
    dha=String(hica);
  }
  
  mySerial.print(dte+dhume+dhe+dta+dhuma+dha);  // We send sensor data by serial to pycom
  Serial.println(dte+dhume+dhe+dta+dhuma+dha);  // This serial string is only for debugging
  delay(6*minu); // Update Frecuency Sensor Values, in this case 6 minutes, 120 data by day
}
Particle Photon CodeC/C++
This code is to activate the irrigation system whenever the conditions of the Node-RED flow are met. In fact whenever the platform detects that there will be no rain and the sensors indicate that the soil is dry, it will send a signal to the Valve portion and it will activate.
// -----------------------------------
// Controlling Aggrofox's irrigation over the Internet
// -----------------------------------

// First, let's create our "shorthand" for the pins
// Same as in the Blink an LED example:
// led1 is D0, led2 is D7

int led1 = D0;
int led2 = D7;

// Last time, we only needed to declare pins in the setup function.
// This time, we are also going to register our Particle function

void setup()
{

   // Here's the pin configuration, same as last time
   pinMode(led1, OUTPUT);
   pinMode(led2, OUTPUT);

   // We are also going to declare a Particle.function so that we can turn the LED on and off from the cloud.
   Particle.function("led",ledToggle);
   // This is saying that when we ask the cloud for the function "led", it will employ the function ledToggle() from this app.

   // For good measure, let's also make sure both LEDs are off when we start:
   digitalWrite(led1, LOW);
   digitalWrite(led2, LOW);

}


// Last time, we wanted to continously blink the LED on and off
// Since we're waiting for input through the cloud this time,
// we don't actually need to put anything in the loop

void loop()
{
   // Nothing to do here
}

// We're going to have a super cool function now that gets called when a matching API request is sent
// This is the ledToggle function we registered to the "led" Particle.function earlier.


int ledToggle(String command) {
    /* Particle.functions always take a string as an argument and return an integer.
    Since we can pass a string, it means that we can give the program commands on how the function should be used.
    In this case, telling the function "on" will turn the LED on and telling it "off" will turn the LED off.
    Then, the function returns a value to us to let us know what happened.
    In this case, it will return 1 for the LEDs turning on, 0 for the LEDs turning off,
    and -1 if we received a totally bogus command that didn't do anything to the LEDs.
    */

    if (command=="on") {
        
        digitalWrite(led1,HIGH);
        digitalWrite(led2,HIGH);
        delay(30000);
        digitalWrite(led1,LOW);
        digitalWrite(led2,LOW);
        return 1;
        
    }
    /*Well we are going to irrigate them plants for 30 seconds each time we need
    */
    else if (command=="off") {
        digitalWrite(led1,LOW);
        digitalWrite(led2,LOW);
        return 0;
    }
    else {
        return -1;
    }
}

Schematics

Sensor and Sigfox connectivity Diagram
These are the schematics for the Sensor and Sigfox communication portion of the system.
Circuit bvbx9ff4h6
Automated irrigation system.
These are the schematics for the irrigation part of the system.
Circuit1 ijdk8lyqcx

Comments

Similar projects you might like

Arduino Dual BME280 IoT Recording HygroThermoGraph

Project tutorial by jim Myracle

  • 5,488 views
  • 2 comments
  • 18 respects

Smart Garden

Project showcase by patel Dipen

  • 22,281 views
  • 15 comments
  • 59 respects

Fox Advisor

Project tutorial by Celia Garrido Hidalgo

  • 3,166 views
  • 2 comments
  • 12 respects

Mobile IoT Weather Station with UV Index

Project showcase by Carlos Orts

  • 8,255 views
  • 15 comments
  • 35 respects

TIA Weak Artificial Intelligence IoT Assistant

Project tutorial by Adam Milton-Barker

  • 3,898 views
  • 0 comments
  • 20 respects

Personal Weather Station (Arduino+ ESP8266 + Thingspeak)

Project tutorial by Jayraj Desai

  • 51,517 views
  • 32 comments
  • 107 respects
Add projectSign up / Login