Thinger Arduino Greenhouse

Hi,

I’ve been working on a automated greenhouse project using thinger. I can display sensor values and read slider values, however when i try to use the if statements in ‘void loop’ to control the actuators the values are not read from thinger sliders and are instead constantly 0. I think it is something to do with the structure of the code or interrupts. Does anyone have an idea?

Thanks,
Elliot

#include <SPI.h> //include SPI library
#include <WiFiNINA.h>//include WiFiNINA library
#include <NTPClient.h>//include NTPClient library
#include <WiFiUdp.h>//include WiFiUDP library
#include "arduino_secrets.h"//include arduino secrets document
#define THINGER_SERIAL_DEBUG
#include <ThingerWiFiNINA.h>////include ThingerWiFiNINA library
#include <DHT.h>//include DHT library
#define DHTPIN 2//setting D2 to DHT22
#define DHTTYPE DHT22   // DHT 22

ThingerWiFiNINA thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);//WiFi and Thinger.io settings
int LDRPin = A0;//set LDR to pin A0
int MoisturePin = A1;//set MoisturePin to pin A1
int LEDOutPin = 11;//set LED relay pin to D11
int FanOutPin = 12;//set Fan relay pin to D12
int PumpOutPin = 13;//set LED relay pin to D13
int LDRValue;//Initialise LDRValue as integer variable   
int MoistureValue;//Initialise MoistureValue as integer variable 
pson Max_Moist;//Initialise Max_Moist as pson variable 
pson Min_Moist;//Initialise Min_Moist as pson variable 
pson Max_Temp;//Initialise Max_Temp as pson variable 
pson Min_Temp;//Initialise Min_Temp as pson variable 
pson Light_Hours;//Initialise Light_Hours as pson variable 
pson Enable_Disable;
volatile int min_moist;//Initialise min_moist as integer variable 
volatile int max_moist;//Initialise max_moist as integer variable 
volatile int max_temp;//Initialise max_temp as integer variable 
volatile int min_temp;//Initialise min_temp as integer variable
volatile int light_hours;//Initialise light_hours as integer variable
volatile int MinLight = 300;//Initialise MinLight as integer variable and set value to 300
volatile int MaxLight = 800;//Initialise MaxLight as integer variable and set value to 800
volatile int timelimit;//Initialise timelimit as integer variable
float t;//Initialise t as decimal variable
float h;//Initialise h as decimal variable
bool change = false;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

DHT dht = DHT(DHTPIN, DHTTYPE);//assigning dht variables

void Watering(){//initialising function Watering 
    digitalWrite(PumpOutPin, HIGH);//set pump pin high, turn on pump
    delay(2000);//delay for 2 seconds
    digitalWrite(PumpOutPin, LOW);//set pump pin low, turn pump off
    delay(4000);//delay for 4 seconds
  }

void Cooling (){//initialising function Cooling 
  digitalWrite(FanOutPin, HIGH);//set fan pin high, turn on fan
  delay(10000);//delay for 10 seconds
  digitalWrite(FanOutPin, LOW);//set fan pin low, turn fan off
  delay(4000);//dealy for 4 seconds
}

void LightingOn (){//initialising function LightingOn
  digitalWrite(LEDOutPin, HIGH);//set LED pin high
}

void LightingOff(){//initialising function LightingOff
  digitalWrite(LEDOutPin, LOW);//set LED pin high
}

void setup() {
  dht.begin();
  Serial.begin(115200);//Initialize serial and wait for port to open
  thing.add_wifi(SSID, SSID_PASSWORD);//initialising thinger wifi
  pinMode(PumpOutPin, OUTPUT);//set pump pin output
  pinMode(FanOutPin, OUTPUT);//set fan pin as output
  pinMode(LEDOutPin, OUTPUT);//set LED pin as output
  t = dht.readTemperature();//read temperature and setting it to variable t
  h = dht.readHumidity();//read humidity and setting it to variable h
  MoistureValue = analogRead(MoisturePin);
  LDRValue = analogRead(LDRPin);
  thing["LDR_Value"] >> [](pson& out){//thinger resource "LDR_Value" as output
      out = analogRead(LDRPin);//output is equal to LDR reading
  };
  thing["Temperature"] >> [](pson& out){//initialising thinger resource "Temperature" and setting as output
      out = t;//output is equal to DHT22 temperature reading
  };
  thing["Humidity"] >> [](pson& out){//initialising thinger resource "Humidity" and setting as output
      out = dht.readHumidity();//output is equal to DHT22 humidity reading
  };
  thing["Moisture_Value"] >> [](pson& out){//initialising thinger resource "Moisture_Value" and setting as output
      out = analogRead(MoisturePin);//output is equal to Moisture sensor reading
  };
  thing["Max_Moist"] << [](pson& in){//initialising thinger resource "Max_Moist" and setting as input
    if(in.is_empty()){// in is empty
      in= max_moist;//in is equal to max_moist
    }else{
      max_moist=in;//max_moist in is equal to in
    }
  };
  thing["Min_Moist"] << [](pson& in){//initialising thinger resource "Min_Moist" and setting as input
    if(in.is_empty()){// in is empty
      in= min_moist;//in is equal to min_moist
    }else{
      min_moist=in;//min_moist is equal to in
    }
  };
  thing["Max_Temp"] << [](pson& in){//initialising thinger resource "Max_Temp" and setting as input
    if(in.is_empty()){// in is empty
      in = max_temp;//in is equal to max_temp
    }else{
      max_temp = in;//max_temp is equal to in
    }
  };
  thing["Min_Temp"] << [](pson& in){//initialising thinger resource "Min_Temp" and setting as input
    if(in.is_empty()){// in is empty
      in = min_temp;//in is equal to min_temp
    }else{
      min_temp = in;//min_temp is equal to in
    }
  };
  thing["Light_Hours"] << [](pson& in){//initialising thinger resource "Light_Hours" and setting as input
    if(in.is_empty()){// in is empty
      in = light_hours;//in is equal to light_hours
    }else{
      light_hours = in;//light_hours is equal to in
    }
  };
}

void loop(){
  thing.handle();//loops thing procedures
  timeClient.begin();//begins time function
  timeClient.update();//updates time 
  int CurrentHour = timeClient.getHours();//sets CurrentHour equal to real time hour
  timelimit = (0+Light_Hours);//add input light hours to 0 to getlighting time limit
  thing["Max_Moist"] << inputValue(max_moist);//set max_moist to input Max_Moist value
  thing["Min_Moist"] << inputValue(min_moist);//set min_moist to input Min_Moist value
  thing["Max_Temp"] << inputValue(max_temp);//set max_temp to input Max_Temp value
  thing["Min_Temp"] << inputValue(min_temp);//set min_temp to input Max_Temp value
  thing["Light_Hours"] << inputValue(light_hours);//set light_hours to input Light_hours value
  if (MoistureValue < min_moist)//if the moisture value less then min_moist
  {
    Watering();//call watering function
  }
  if ((CurrentHour >= 0) && (CurrentHour <= timelimit)){//if the current hour is greater than or equal to 0 and less than time limit
    if (LDRValue < MinLight){//if LDR value is less than MinLight value
      LightingOn();//calls lighting on function
    }if(CurrentHour > timelimit){ 
      LightingOff();//calls lighting off function
    }
  }
  if (t > max_temp){//if t is greater than max temp limit 
    Cooling();//call cooling function
  }
}

Hi,

I’ve seen that you are calling the resources definition into the loop:

This is not neccesary, you need to define the resource just once at the setup code, therefore the handler will listen the changes made to them.

Please paste the code in the right way, is not comfortable at all to read code like plain text, uset the “</>” button at the menu.

Hope this helps.

without those lines of code the silders do not hold their value. Should they be put in the slider functions instead? I’m not sure what you mean about “uset the “</>” button at the menu” could you elaborate?

Thanks,
Elliot

As @ega suggested, all device resources must be defined once, i.e., in the setup method.

These variables are not being used, so, I do not know why are there:

pson Max_Moist;//Initialise Max_Moist as pson variable 
pson Min_Moist;//Initialise Min_Moist as pson variable 
pson Max_Temp;//Initialise Max_Temp as pson variable 
pson Min_Temp;//Initialise Min_Temp as pson variable 
pson Light_Hours;//Initialise Light_Hours as pson variable 
pson Enable_Disable;

I do not recommend using PSON as a variable storage in your code. Just use variables like floats, integers, or anything else required, and use PSON just in the resource for the transmission. In fact, you have these variables already defined in your code, so, why are they duplicated? I think you can remove the volatile flag from all your variables.

Moreover, be careful about those lines in the loop (not sure if they are syncing time over and over again). I think begin should be called just once, and update periodically, i.e., every hour.

  timeClient.begin();//begins time function
  timeClient.update();//updates time

And finally, I recommend you to always initialize the value of your variables, i.e., setting to zero.