Be kind to your plants! Learn about the green house environment using MKR1000 and sensors. Control soil humidity and air conditions!
Things used in this project
Hardware components |
||||||
![]() |
|
× | 1 | |||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
![]() |
|
× | 1 | |||
![]() |
|
× | 1 | |||
Software apps and online services |
||||||
|
||||||
![]() |
|
Story
Grow plants and vegetables more aware of their environment conditions. Simply by using a MKR1000
Requirements for Plant Growth
Plant growth depends of several ideal environment conditions such as temperature, humidity, light and other mineral nutrients or oxygen.
Providing the plants with an adequate amount of water or keep the normal temperature in the green house can be a tricky process but not if you could do it it much easier.
Hardware overview
Temperature / Humidity
TH1 – Outside temp values will be provided from a waterproof DS18B20 sensor – D1 pin connection
TH2 – Inside temp. / hum. can be found out from DHT22 – pin D0
TH3 – FS200/SHT25 – will be introduced in soil conditions. Connections will at for SCL & SDA pins 12/11
Water lever
W1 – in order to get water level will be using a ultrasound sensor like HC – SR04 Connections at A0 – Echo and Trigger at A1. Based on this value you can control a valve using R1 – 4 channels relay.
Air Temperature / Oxygen
A1 – Base on temperature/ humidity values you can command when to open windows using R2 relay. Based on climate you should tune it as you wish.
Relays R1 / R2
To set some commands like open Windows or start any pump you could send commands to the relays … R1 is connected to digital pins 7,8,9,10 and R2 5,
Connections on the MKR1000
MKR1000 – aRest
Now that we connected all things together is time to get some data and make sens using aRest library, that will provide a web interface to MKR1000 device with json format string. Use the libraries, .ino files provided bellow and change your Wifi router connection accordingly.
aRest Interface
Data and Interface
As long that we have an interface our device we could also consume this data and see it on the local network.
We’ve been using Visual Studio 2015 and .net to build up a Windows application that will help you visualize green house live conditions but also a bit of daily history or all sort of logs that you want to integrate.





Next step will be to modify the DsKey and AKey provided in the Settings.txtfrom application folder. If everything works you should see some data online already.

Follow DasData’s hackster channel for more future updates
Green house Automation
You should decide what valves or motors will create more action based on your greenhouse configuration and sizes. All this could be controlled from relays.
Schematics
DasFilisera – Schematics
Code
Filisera_Arduino
C/C++
/* DASFilisera using aREST Library for the Arduino/Genuino MKR1000 board. aREST - Written in 2016 by Marco Schwartz under a GPL license. */ // Import required libraries #include <SPI.h> #include <WiFi101.h> #include <aREST.h> #include "DHT.h" #include <OneWire.h> #include <Wire.h> #include <DallasTemperature.h> #include <SHT2x.h> // ************************* // ** Senzori Temperatura ** // ************************* #define DHTPIN 0 // Inside humidity/temp/heat index #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 #define ONE_WIRE_BUS 1 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); float umidSol = 0; // Soil humidity float umidAer = 0; // Air humidity float tempIn = 0; // Temperature in float tempOut = 0; // Temperature out float tempSol = 0; // Container volume float umidexIn = 0; // Feels like temp //VOLUM #define echoPin A0 // Echo pin A0 #define trigPin A1 // Trigger pin A1 long duration ; // duration to calculate distance int HR_dist = 0; // Calculated distance int minimumRange=5; //Min Sonar range int maximumRange=200; //Max Sonar range unsigned long pulseduration=0; int nivelCm, nivelRamasCm; int nivelProc, nivelVol; int empty = 100; int full = 100; int sqrLevel, sqrInvertLevel ; // Status int status = WL_IDLE_STATUS; // Create aREST instance aREST rest = aREST(); // WiFi parameters char ssid[] = "WIFI_AP"; char password[] = "WIFI_PASSW"; // The port to listen for incoming TCP connections #define LISTEN_PORT 80 // Create an instance of the server WiFiServer server(LISTEN_PORT); //INITIALIZARE SENZORI DHT dht(DHTPIN, DHTTYPE); // RELEE RELEEE int aVentil, aLateral; int inReleu1Ventil = 6; int inReleu2Ventil = 7; int inReleu3Ventil = 8; int inReleu4Ventil = 9; int inReleu1Lateral = 10; int inReleu2Lateral = 11; // Declare functions to be exposed to the API int ledControl(String command); void setup(void) { // Start Serial Serial.begin(115200); // Init variables and expose them to REST API // rest.variable("temperature",&temperature); // rest.variable("humidity",&humidity); // Function to be exposed rest.function("led",ledControl); // Give name and ID to device rest.set_id("1"); rest.set_name("mkr1000"); // Connect to WiFi while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, password); // Wait 10 seconds for connection: delay(10000); } Serial.println("WiFi connected"); // Start the server server.begin(); Serial.println("Server started"); // Print the IP address IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // SETUP DHT - INSIDE DHT dht(DHTPIN, DHTTYPE); // sensors.begin(); // Pornire senzor temperatura exterioara DS-16B20 pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); // Init variables and expose them to REST API rest.variable("Vol_container",&sqrLevel ); rest.variable("Umiditate_sol",&umidSol ); rest.variable("Umiditate_aer",&umidAer ); rest.variable("Temp_in",&tempIn ); rest.variable("Temp_out",&tempOut ); rest.variable("Temp_sol",&tempSol ); // rest.variable("Umidex_in",&umidexIn ); // sensors.requestTemperatures(); // Temperatura Out } void loop() { getmyDistance(); // getSoilVals(); getInsideVals(); // getOutSideVals(); // Handle REST calls WiFiClient client = server.available(); if (!client) { return; } while(!client.available()){ delay(1); } rest.handle(client); } void getmyDistance() { digitalWrite(trigPin,LOW); delayMicroseconds(2); digitalWrite(trigPin,HIGH); delayMicroseconds(10); digitalWrite(trigPin,LOW); duration = pulseIn(echoPin,HIGH); //calculate distance HR_dist = duration/58.2; // sqrLevel = empty - HR_dist; if (HR_dist >= maximumRange || HR_dist <= minimumRange) { sqrLevel = 0; } else { sqrLevel = empty - HR_dist; Serial.println(HR_dist); } delay(100); } void getDistance() { digitalWrite(trigPin, LOW); delayMicroseconds(10); // now send the 10uS pulse out to activate Ping digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // finally, measure the length of the incoming pulse pulseduration = pulseIn(echoPin, HIGH); // divide the pulse length by half pulseduration = pulseduration/2; // convert to centimetres. nivelRamasCm = int(pulseduration/29); nivelCm = empty - nivelRamasCm; nivelVol = map(nivelRamasCm, full, empty, 100, 0); // Tipareste nivelul in centimetri if (nivelCm >= -5 && nivelCm <=135) { double a = nivelCm / 100 * nivelVol; int sqrLevel = 240 - nivelCm; int sqrInvertLevel = 120 + nivelRamasCm; if (nivelCm >65 && nivelCm <=85){ } if (nivelCm >85 && nivelCm <=100){ } } } long microsecondsToCentimeters (long microseconds) { // The speed of sound is 340 m/s or 29 microseconds per centimeter // The ping travels forth and back, so, the distance is half the distance traveled return microseconds / 29 / 2; } void getInsideVals() { float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); // Read temperature as Fahrenheit (isFahrenheit = true) // float f = dht.readTemperature(true); umidAer = h; tempIn = t; // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; } // Compute heat index in Fahrenheit (the default) //float hif = dht.computeHeatIndex(f, h); // Compute heat index in Celsius (isFahreheit = false) // float hic = dht.computeHeatIndex(t, h, false); // umidexIn = hic; } void getOutSideVals() { tempOut = sensors.getTempCByIndex(0) ; Serial.println("Temperature Out: "); Serial.print(tempOut); } void getSoilVals() { umidSol = SHT2x.GetHumidity(); tempSol = SHT2x.GetTemperature(); Serial.println("Humidity Soil(%RH): "); Serial.print(umidSol); Serial.print(" Temperature Soil (C): "); Serial.print(tempSol); } // sensors.requestTemperatures(); // Temperatura Out // Custom function accessible by the API int ledControl(String command) { // Get state from command int state = command.toInt(); digitalWrite(6,state); return 1; }
libraries.zip
C/C++
No preview (download only).
Filisera – vb.zip
VBScript
No preview (download only).
Filisera – VS
VBScript
Imports System.Globalization Imports System.IO Imports System.Net Imports System.Threading Imports System.Windows.Forms.DataVisualization.Charting Imports Newtonsoft.Json Public Class Form1 Private _deviceIP As String = "" 'DEVICE IP Private intVolumContainer, intUmidSol, intUmidSera, intTempAfara, intTempSera, intTempSol, intUmidex As String ' VARIABILES Private strR1, strR2 As String 'RELAYS Public Count As CountDown 'COUNTDOWN TICK Private _dasResult As String = "" 'RESULTAT CITIRE SENZORI DEVICE Private _AKey As String = "" 'USER KEY DASDATA Private _DSKey As String = "" 'DATASET KEY DASDATA Private _myDas As New dasData.das Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Count = New CountDown(50, 0) '5 SECONDS UPDATE AddHandler Count.Tick, AddressOf Count_Tick AddHandler Count.TimesOut, AddressOf Times_up Try 'READ SETTINGS FROM .txt FILE Dim path As String = Directory.GetCurrentDirectory() Dim FILE_NAME As String = path & "\Settings.txt" Dim myText As String = "" ' If System.IO.File.Exists(FILE_NAME) = True Then Dim objReader As New System.IO.StreamReader(FILE_NAME, System.Text.Encoding.Default) Do While objReader.Peek() <> -1 myText &= objReader.ReadLine() Loop Dim _settingItems() As String = myText.Split(" ") _deviceIP = _settingItems(0) 'IP-ul DEVICE _AKey = _settingItems(1).Replace("akey:", "") _DSKey = _settingItems(2).Replace("dskey:", "") cbxEnabled.Text = "Device:" & _deviceIP txtInfo.Text = "IP device: " & _deviceIP & vbNewLine & "AKey: " & _AKey & vbNewLine & "DSKey: " & _DSKey & vbNewLine strR1 = _settingItems(3).Replace("relay1:", "") txtInfo.Text += "Relay1: " & strR1 & vbNewLine strR2 = _settingItems(4).Replace("relay2:", "") txtInfo.Text += "Relay2: " & strR2 & vbNewLine ' txtInfo.Text = "Settings: " & myText objReader.Dispose() objReader.Close() End If Catch ex As Exception lblDevice.Text = ex.Message.ToString End Try cmdCheckDevice() 'LOCAL SETTINGS Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US") 'Thread.CurrentThread.CurrentUICulture = New CultureInfo("ro-RO") cmdStartFilisera() End Sub Private Sub Count_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) cmdGetSensorValues() cmdTriggers() If CDate(dtFrom.Text).ToString("dd.MM.yyyy") = Date.Now().ToString("dd.MM.yyyy") Then cmdStartFilisera() End If End Sub Private Sub Times_up(ByVal sender As System.Object, ByVal e As System.EventArgs) ' Count.Reset() 'Count.Pause() End Sub Private Sub cmdStartFilisera() Try dtFrom.MaxDate = DateTime.Now _dasResult = _myDas.getDas(_DSKey, "json", 0, 100) cmdFillData() Catch ex As Exception lblDevice.Text += ex.Message.ToString End Try End Sub Private Sub cbxEnabled_CheckedChanged(sender As Object, e As EventArgs) Handles cbxEnabled.CheckedChanged cmdCheckDevice() End Sub Private Sub cmdCheckDevice() Try If cbxDemo.Checked = False Then lblDevice.Text = ("Enable device!") lblEvenimente.Text = Date.Now.ToString("dd.MM.yyyy HH:mm:ss") If cbxEnabled.Checked = True Then Dim pingsender As New Net.NetworkInformation.Ping If Not pingsender.Send(_deviceIP).Status = Net.NetworkInformation.IPStatus.Success Then lblDevice.Text = ("Device not availble on the local network!") cbxEnabled.Checked = False btnTemperatura.Enabled = False btnVolumContainer.Enabled = False Count.Reset() Count.Pause() MessageBox.Show("Device at " & _deviceIP & " not found!") Else lblDevice.Text = ("Device connected!") btnTemperatura.Enabled = True btnVolumContainer.Enabled = True cmdGetSensorValues() Timer1.Enabled = True cmdAddData() Count.Start() End If Else End If Else btnTemperatura.Enabled = True btnVolumContainer.Enabled = True cmdGetSensorValues() Timer1.Enabled = True cmdAddData() Count.Start() End If Catch ex As Exception End Try End Sub Private Sub btnVolumContainer_Click(sender As Object, e As EventArgs) Handles btnVolumContainer.Click ' http://192.168.0.102/digital/7/1 'CLOSE WATER FROM BUTTON Dim _ItemsR1() As String = strR1.Split(",") If btnVolumContainer.Text.Contains("Open") Then cmdRelay(_ItemsR1(0), 1) cmdRelay(_ItemsR1(1), 1) cmdRelay(_ItemsR1(2), 0) cmdRelay(_ItemsR1(3), 0) btnVolumContainer.Text = "Close water" Else cmdRelay(_ItemsR1(0), 0) cmdRelay(_ItemsR1(1), 0) cmdRelay(_ItemsR1(2), 1) cmdRelay(_ItemsR1(3), 1) btnVolumContainer.Text = "Open water" End If ' Dim _url As String = _deviceIP & "digital/7/1" End Sub Private Sub btnTemperatura_Click(sender As Object, e As EventArgs) Handles btnTemperatura.Click 'CLOSE WINDOW FROM BUTTON Dim _ItemsR2() As String = strR2.Split(",") If btnTemperatura.Text.Contains("Open") Then cmdRelay(_ItemsR2(0), 1) cmdRelay(_ItemsR2(1), 1) btnTemperatura.Text = "Close window" Else cmdRelay(_ItemsR2(0), 0) cmdRelay(_ItemsR2(1), 0) btnTemperatura.Text = "Open window" End If End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick cmdAddData() End Sub Private Sub btnTestCloud_Click(sender As Object, e As EventArgs) Handles btnTestCloud.Click Try cmdStartFilisera() Catch ex As Exception MessageBox.Show("Lost connection with DasData!") End Try End Sub Private Function cmdRelay(ByVal _DPin As String, ByVal _cmd As Int16) Try Dim _urlCommand As String = _deviceIP & "/digital/" & _DPin & "/" & _cmd Dim client As New WebClient() client.Headers.Add("user-agent", "Arduino/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)") Dim data As Stream = client.OpenRead(_urlCommand) Dim reader As New StreamReader(data) Dim s As String = reader.ReadToEnd() ' txtInfo.Text += (s) data.Close() reader.Close() Catch ex As Exception End Try End Function Private Sub dtFrom_ValueChanged(sender As Object, e As EventArgs) Handles dtFrom.ValueChanged Try 'GET VALUES BASED ON DATE SELECTION _dasResult = _myDas.getDas(_DSKey, "jsond", CDate(dtFrom.Text).ToString("dd.MM.yyyy"), CDate(dtFrom.Text).ToString("dd.MM.yyyy")) cmdFillData() Catch ex As Exception MessageBox.Show(ex.Message.ToString) End Try End Sub Private Sub cmdGetSensorValues() Try ''GET SENSOR VALUES FROM DEVICE If cbxDemo.Checked = False Then Dim client As New WebClient() client.Headers.Add("user-agent", "Arduino/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)") Dim data As Stream = client.OpenRead("http://" & _deviceIP & "/index.html") Dim reader As New StreamReader(data) Dim s As String = reader.ReadToEnd() s = s.Replace("""", "").Replace("}", "").Replace("{", "").Replace(" ", "").Replace("variables:", "") Dim sItems() As String = s.Split(",") intVolumContainer = cmdGetVal(sItems(0)) intUmidSol = cmdGetVal(sItems(1)) intUmidSera = cmdGetVal(sItems(2)) intTempSera = cmdGetVal(sItems(3)) intTempAfara = cmdGetVal(sItems(4)) intTempSol = cmdGetVal(sItems(5)) data.Close() reader.Close() Else intVolumContainer = _rnd(60) intUmidSol = _rnd(80) intUmidSera = _rnd(20) intTempSera = _rnd(45) intTempAfara = _rnd(57) intTempSol = _rnd(66) End If ggVolum.Value = intVolumContainer rgVolum.Value = intVolumContainer ggUmidSol.Value = intUmidSol ggUmidSera.Value = intUmidSera ggTempSera.Value = intTempSera ggTempOut.Value = intTempAfara ggTempSol.Value = intTempSol Catch ex As Exception '{"variables" {"Volum_container": 0, "Umiditate_sol": 0.00, "Umiditate_aer": 36.60, "Temp_in": 26.50, "Temp_out": 0.00, "Temp_sol": 0.00, "Umidex_in": 26.37}, "id": "1", "name": "FiliSera", "hardware": "arduino", "connected": true} End Try End Sub Private Function cmdGetVal(ByVal _sItem As String) Try 'SPLIT STRING AND GET VALUES BACK Dim _s() As String = _sItem.Split(":") Return _s(1) Catch ex As Exception End Try End Function Private Sub cmdAddData() Try 'SEND DATA TO DASDATA CLOUD STORAGE Dim _strFiliseraDataSend As String = intVolumContainer & "|" & intUmidSol & "|" & intUmidSera & "|" & intTempAfara & "|" & intTempSera & "|" & intTempSol '& "|"& intUmidex & "|"& Dim _dasResult As String = _myDas.sendDas(_strFiliseraDataSend, _DSKey, _AKey) Catch ex As Exception cmdLogMe("ERROR..." & ex.Message.ToString(), "error") End Try End Sub Private Sub cmdFillData() Try 'FILL INTERFACE WILL ALL SORT OF DATA Dim dataSet As DataSet = JsonConvert.DeserializeObject(Of DataSet)(_dasResult) Dim dataTable As DataTable = dataSet.Tables(0) 'GRIDVIEW DataGridView1.DataSource = dataSet.Tables(0) DataGridView1.AutoGenerateColumns = True 'CHARTS ChartTemp.DataSource = dataTable ChartTemp.Series.Clear() chartUmid.DataSource = dataTable chartUmid.Series.Clear() chartVolum.DataSource = dataTable chartVolum.Series.Clear() Dim i As Integer = 0 Dim j As Integer = 0 Dim k As Integer = 0 For Each table In dataSet.Tables For Each row In table.Rows For Each col In table.Columns Dim colName As String = col.ColumnName.ToString If colName <> "id" And colName <> "AIDate" Then Try Dim serieName As String = RTrim(colName) 'VOLUME If colName.Contains("Nivel") Then chartVolum.Series.Add(serieName) chartVolum.Series(serieName).LabelFormat = "N1" chartVolum.Series(i).ChartType = SeriesChartType.Line chartVolum.Series(i).BorderWidth = 2 chartVolum.Series(i).Color = Color.Aqua chartVolum.Series(i).BorderDashStyle = ChartDashStyle.Solid chartVolum.Series(serieName).YValueMembers = RTrim(colName) chartVolum.Series(serieName).XValueMember = "AIDate" i += 1 End If 'HUMIDITY If colName.Contains("Umid") Then chartUmid.Series.Add(serieName) chartUmid.Series(serieName).LabelFormat = "N1" chartUmid.Series(j).ChartType = SeriesChartType.Line chartUmid.Series(j).BorderWidth = 2 chartUmid.Series(j).BorderDashStyle = ChartDashStyle.Solid chartUmid.Series(serieName).YValueMembers = RTrim(colName) chartUmid.Series(serieName).XValueMember = "AIDate" j += 1 End If 'TEMP If colName.Contains("Temp") Then ChartTemp.Series.Add(serieName) ChartTemp.Series(serieName).LabelFormat = "N1" ChartTemp.Series(k).ChartType = SeriesChartType.Line ChartTemp.Series(k).BorderWidth = 2 ChartTemp.Series(k).BorderDashStyle = ChartDashStyle.Solid ChartTemp.Series(serieName).YValueMembers = RTrim(colName) ChartTemp.Series(serieName).XValueMember = "AIDate" k += 1 End If Catch ex As Exception End Try End If Next Exit For Next Next 'FILL THE CHARTS ChartTemp.DataBind() ChartTemp.Visible = True chartUmid.DataBind() chartUmid.Visible = True chartVolum.DataBind() chartVolum.Visible = True Catch ex As Exception cmdLogMe("ERROR..." & ex.Message.ToString(), "error") End Try End Sub Private Sub cmdTriggers() 'SET TRIGGERS AND STORE THE LOG Select Case intVolumContainer Case > 80 cmdLogMe("HIGH HIGH - Container volume - stop water", "0") Case > 70 ' cmdLogMe("HIGH - Container volume - water will start", "1") Case < 20 ' cmdLogMe("LOW - Container volume low - water will stop", "1") Case < 10 cmdLogMe("LOW LOW - Container volume high high high - start water", "0") End Select Select Case intTempSera Case > 38 cmdLogMe("HIGH HIGH - Temperature in green house - open windows", "0") Case > 30 ' cmdLogMe("HIGH - Temperature in green house - prepare windows", "1") Case < 10 ' cmdLogMe("LOW - Temperature in green house - prepare windows", "1") Case < 10 cmdLogMe("LOW LOW - Container volume high high high - start water", "0") End Select End Sub Public Function _rnd(ByVal n As Integer) As Integer 'initialize random number generator Dim r As New Random(System.DateTime.Now.Millisecond) Return r.Next(1, n) End Function Private Sub cmdLogMe(message As String, _type As String) Try Dim _strLog As String = "adeewdf4-4aa34-14ass24-8436-aea1" 'LOG DASDATA DS KEY lstEvenimente.Items.Add((System.DateTime.Now & " " & message) + Constants.vbNewLine) 'STORE LOGS TO DASDATA _myDas.sendDas(message & "|" & _type, _strLog, _AKey) Catch ex As Exception cmdLogMe("ERROR..." & ex.Message.ToString(), "error") End Try End Sub End Class
Source : DasFilisera Green House