AgriSensor : Arduino-Based Sensor for Agriculture

From air
Revision as of 18:20, 8 March 2016 by Donsez (talk | contribs) (Donsez moved page Arduino-Based Sensor for Agriculture to AgriSensor : Arduino-Based Sensor for Agriculture)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


AgriSensor internals

Hardware Requirement

Extra weather sensors:

Arduino sketch


// Hardware requirement
// Soil http://dx.com/p/soil-humidity-moisture-detection-sensor-module-blue-black-white-200142
// DHT http://dx.com/p/arduino-digital-temperature-humidity-sensor-module-121350
// Photocell https://www.sparkfun.com/products/9088
// Extra sensors:
// http://air.imag.fr/index.php/SEN-08942
// http://dx.com/p/rain-raindrops-sensor-module-for-arduino-black-works-with-official-arduino-boards-228260

#include "DHT.h"

int SOIL_DIGITAL_PIN=2;
int SOIL_ANALOG_PIN=A0;  

int LIGHT_ANALOG_PIN=A1;

int DHT_PIN=4;

#define DHT_TYPE DHT11   // DHT 11 
//#define DHT_TYPE DHT22   // DHT 22  (AM2302)
//#define DHT_TYPE DHT21   // DHT 21 (AM2301)

// Connect middle pin of the sensor breadout to +5V
// Connect pin S of the sensor to whatever your DHTPIN is
// Connect pin - (on the right) of the sensor to GROUND

DHT dht(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(9600);
 
  pinMode(SOIL_DIGITAL_PIN, INPUT);
 
  dht.begin();
}

void loop() {

    Serial.print("/soil/humidity ");
    Serial.print(map(analogRead(SOIL_ANALOG_PIN),200,1023,100,0));
//    Serial.print("/soil/alert ");
//    Serial.println(digitalRead(SOIL_DIGITAL_PIN));
    Serial.println();

  delay(1000);

  int lightSensorValue = analogRead(LIGHT_ANALOG_PIN);
  Serial.print("/light/intensity ");
  Serial.print(map(lightSensorValue,0,1023,10,0));
  Serial.println();

  delay(1000);

  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("/error DHT");
  } else {
    Serial.print("/air/humidity ");
    Serial.print(humidity);
    Serial.println();
    Serial.print("/air/temperature ");
    Serial.print(temperature);
    Serial.println();
    Serial.print("/air/dewpoint ");
    Serial.print(dewPoint(temperature, humidity));
    Serial.println();
  }
  
  delay(1000); 
}


// from http://arduino-info.wikispaces.com/DHT11-Humidity-TempSensor


/*-----( Declare User-written Functions )-----*/
//
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
        return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
        return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        double SUM = -7.90298 * (A0-1);
        SUM += 5.02808 * log10(A0);
        SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
        SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
        SUM += log10(1013.246);
        double VP = pow(10, SUM-3) * humidity;
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * celsius) / (b + celsius) + log(humidity/100);
        double Td = (b * temp) / (a - temp);
        return Td;
}

Python script on host (with Mosquitto)

Term 1

BROKER=test.mosquitto.org
mosquitto_sub -h $BROKER -t "sensor/#" -v 

Term 2

BROKER=test.mosquitto.org
python agrisensor.py $BROKER
#!/usr/bin/python
#
# simple app to read topic and value strings from serial port (arduino board)
# and publish via MQTT
#
# uses the Python MQTT client from the Mosquitto project
# http://mosquitto.org
#
# Didier Donsez, 2013
# initially from Andy Piper http://andypiper.co.uk
# 2011/09/15

import serial
import mosquitto
import os
import sys

broker=sys.argv[1]
#broker = "10.0.1.3"
#broker = "test.mosquitto.org"
port = 1883

# serialdev = '/dev/ttyACM0'
serialdev = '/dev/tty.usbserial-A400DNT0'

# for instance, an IPv6 address
sensorid="123456789"

topicPrefix="sensor/" + sensorid

#MQTT callbacks

def on_connect(mosq, obj, rc):
    if rc == 0:
        print("Connected successfully.")
    else:
        raise Exception


def on_disconnect(mosq, obj, rc):
    print("Disconnected successfully.")


def on_publish(mosq, obj, mid):
    print("Message "+str(mid)+" published.")


def on_subscribe(mosq, obj, mid, qos_list):
    print("Subscribe with mid "+str(mid)+" received.")


def on_unsubscribe(mosq, obj, mid):
    print("Unsubscribe with mid "+str(mid)+" received.")


def on_message(mosq, obj, msg):
    print("Message received on topic "+msg.topic+" with QoS "+str(msg.qos)+" and payload "+msg.payload)


#called on exit
#close serial, disconnect MQTT
def cleanup():
    print "Ending and cleaning up"
    ser.close()
    mqttc.disconnect()

try:
    print "Connecting... ", serialdev
    #connect to serial port
    ser = serial.Serial(serialdev, 9600, timeout=20)
except:
    print "Failed to connect serial"
    #unable to continue with no serial input
    raise SystemExit


try:
    ser.flushInput()
    #create an mqtt client
    mypid = os.getpid()
    client_uniq = "arduino_pub_"+str(mypid)
    mqttc = mosquitto.Mosquitto(client_uniq)

    #attach MQTT callbacks
    mqttc.on_connect = on_connect
    mqttc.on_disconnect = on_disconnect
    mqttc.on_publish = on_publish
    mqttc.on_subscribe = on_subscribe
    mqttc.on_unsubscribe = on_unsubscribe
    #mqttc.on_message = on_message

    #connect to broker
    mqttc.connect(broker, port, 60)

    #remain connected to broker
    #read data from serial and publish
    while mqttc.loop() == 0:
        line = ser.readline()
        #split line as it contains topic and value
        list = line.split(" ")
        #second list element is value

        topic = list[0].rstrip()
        if topic.startswith('/'):        
            value = list[1].rstrip()
            print(topic + " is " + value)
            mqttc.publish(topicPrefix + topic, value)
            
        pass


# handle list index error (i.e. assume no data received)
except (IndexError):
    print "No data received within serial timeout period"
    cleanup()
# handle app closure
except (KeyboardInterrupt):
    print "Interrupt received"
    cleanup()
except (RuntimeError):
    print "uh-oh! time to die"
    cleanup()