Shawn Murphy
Published © GPL3+

Arduino Cloud Controlled SmartGarden

Arduino Cloud controlled and monitored Smart irrigation garden powered with solar, and powered with a home built 12v lithium Ion 18650 batt.

IntermediateFull instructions provided4 hours1,506
Arduino Cloud Controlled SmartGarden

Things used in this project

Hardware components

Arduino Oplà IoT Kit
Arduino Oplà IoT Kit
×1
normally closed 3/4 solenoid valve
×1
DROK Adjustable Buck Converter Step Down Voltage Regulator 6V-32V
×1
voltage sensor
×1
waterproof enclosure
×1

Software apps and online services

Arduino IoT Cloud
Arduino IoT Cloud
Arduino Web Editor
Arduino Web Editor
Visual Studio Code Extension for Arduino
Microsoft Visual Studio Code Extension for Arduino

Story

Read more

Schematics

Fritzing screenshot

Fritzing.org not taking new projects currently

SmartGarden IOT schematic

SmartGarden IOT schematic. Fritzing application

Code

SmartGarden_1_01

C/C++
Code for smart garden on mkr 1010 wifi with IOT carrier and Arduino Cloud
/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/7ce5686a-0aba-49c7-9f46-9d831495eb75

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float packVoltage;
  float temperature;
  float usbVolt;
  int moisture;
  bool setRelay1State;
  bool setRelayState;
  bool useSensor;
  bool useSensor1;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include <Arduino_MKRIoTCarrier.h>
MKRIoTCarrier carrier;


#define Sensor A6 // defining the voltage sensor for the 12v battery pack
float vOUT = 0.0; // setting vOUT to zero at start
float vIN = 0.0; // setting vIN to zero at start
float R1=30000.0;//30kohms resistor
float R2=7500.0;//7.5kohms resistor

int fanRelay;

int valveRelay; // defining the valveRelay variable - boolean

int moistPin = A5; // defining the moisture sensor variable and assigning it to pin A5

// calibrate moisture sensor
const int AIR_ANALOG = 4095; // calibrate moisture sensor dry state
const int WATER_ANALOG = 3000; // calibrate moisture sensor wet state


void setup() {
  
  
  Serial.begin(9600); // Initialize serial and wait for port to open:
  delay(900);

  
  initProperties(); // Defined in thingProperties.h

  
  ArduinoCloud.begin(ArduinoIoTPreferredConnection); // Connect to Arduino IoT Cloud
  //Get Cloud Info/errors , 0 (only errors) up to 4
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  //Wait to get cloud connection to init the carrier
  while (ArduinoCloud.connected() != 1) {
    ArduinoCloud.update();
    delay(500);
  }
  delay(500);
  CARRIER_CASE = true; //setting the case use parameter since the box is like the case for button sensitivity
  carrier.begin();
  carrier.display.setRotation(0); //setting the display rotation
  delay(500);
  
  carrier.Relay1.close(); // starting it at low or closed
  carrier.Relay2.close(); // starting it at low or closed
  
  pinMode(LED_BUILTIN, OUTPUT);   // Set the built-in LED as an output 
  pinMode(3, OUTPUT); // Set pin 3 the screen backlight as an output
  digitalWrite(3, LOW); // setting it to low or off
  
  
  delay(500);
  
}

void loop() {
  ArduinoCloud.update();
  
  carrier.Buttons.update();


  while (!carrier.Light.colorAvailable()) {
    delay(5);
  }
  int none;
  
  // Hose Solenoid Control
  // if useSensor is true, read the sensor value and turn on/off the relay based on the threshold
  if (useSensor) {
    int raw_moisture = analogRead(moistPin); // read raw moisture value  
    // map raw moisture value to a scale of 0 to 100 from set constants
    moisture = map(raw_moisture, AIR_ANALOG, WATER_ANALOG, 0, 100);
    // the moisture relay settings
    // open the relay - hose valve when it goes below 40%
    if (moisture < 40) {
    // Turn on the relay
      carrier.Relay2.open(); //set the relay open
    }
    // turn the relay - valve off at 70% moisture
    else if (moisture >= 70) {
      // Turn off the relay
      carrier.Relay2.close();
    }   
  }
  // If useSensor is false, read the button state and turn on/off the relay based on it
  else {
    if(setRelayState == HIGH) {
    
      carrier.Relay2.open(); // Turn on the relay with the web button
    }
    else {
      carrier.Relay2.close(); // Turn off the relay with the web button
    }
  }
  
  // Fan Control
  // if useSensor1 is true, read the sensor value and turn on/off the relay based on the threshold
  if (useSensor1) {
    temperature = carrier.Env.readTemperature(FAHRENHEIT) - 10; //temp calibration
    if (temperature > 95) {
      carrier.Relay1.open(); //set the relay open
    }
    // turn the relay - valve off at 70% moisture
    else if (temperature <= 85) {
      // Turn off the relay
      carrier.Relay1.close();
    }   
  }  
  
  // If useSensor1 is false, read the button state and turn on off the relay based on it
  else {
   if(setRelay1State == HIGH) {
    
      carrier.Relay1.open(); // Turn on the relay with the web button
    }
    else {
      carrier.Relay1.close(); // Turn off the relay with the web button
    }
  }
 
    analogReadResolution(12); // set the sensors analog read resolution to 12 bit - 4095
    Serial.print(analogRead(A0)); // print to serial the raw voltage value on pin A0 - the USB voltage on the arduino
    
  int sensorValue = analogRead(A0); // set sensorValue to the voltage on pin A0
  // Convert the analog reading (which goes from 0 4095) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 4095.0);
  
  usbVolt = voltage;

  int value=analogRead (Sensor); // set the analog read of the 12v battery to int value
  vOUT = (value *3.3) / 4095.0; // set voltage out to value multiplied the board voltage of 3.3v
  vIN = vOUT / (R2/(R1 + R2)); // convert the vOUT to the actual pack voltage
  
  packVoltage = vIN; // set vIN to a cloud variable packVoltage
  
// Carrier button 0 configuration
  if (carrier.Buttons.onTouchDown(TOUCH0)) {
    carrier.display.fillScreen(ST77XX_BLACK); // background color
    carrier.display.setTextColor(ST77XX_WHITE); // text color
    carrier.display.setTextSize(4); // text size

  }
// Carrier button 1 configuration
  if (carrier.Buttons.onTouchDown(TOUCH1)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_WHITE);
    carrier.display.setTextSize(4);

    carrier.display.setCursor(30, 110);
    carrier.display.print("Voltage ");
    carrier.display.setCursor(50, 160);
    carrier.display.print(packVoltage);
    carrier.display.print("v");
  }
  
// Carrier button 2 configuration
  if (carrier.Buttons.onTouchDown(TOUCH2)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_WHITE);
    carrier.display.setTextSize(4);

    carrier.display.setCursor(30, 110);
    carrier.display.print("temp");
    carrier.display.setCursor(50, 160);
    carrier.display.print(temperature);
  }
  
// Carrier button 4 configuration
  if (carrier.Buttons.onTouchDown(TOUCH4)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_WHITE);
    carrier.display.setTextSize(4);

    carrier.display.setCursor(10, 110);
    carrier.display.print("moisture% ");
    carrier.display.setCursor(100, 160);
    carrier.display.print(moisture);
    carrier.display.print("%");
  }
  
}

/*
  Since SetRelayState is READ_WRITE variable, onSetRelayStateChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onSetRelayStateChange()  {
  // Relay state change on web button change on the dashboard
  if(setRelayState)
  {
    carrier.Relay2.open();
  }
  else
  {
    carrier.Relay2.close();
  }
}


/*
  Since SetRelay1State is READ_WRITE variable, onSetRelay1StateChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onSetRelay1StateChange()  {
  // Add your code here to act upon SetRelay1State change
  // Relay state change on web button change on the dashboard
  if(setRelay1State)
  {
    carrier.Relay1.open();
  }
  else
  {
    carrier.Relay1.close();
  }
}

/*
  Since UseSensor is READ_WRITE variable, onUseSensorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onUseSensorChange()  {
  // Add your code here to act upon UseSensor change
  if (useSensor)
  {
    
  }
}


/*
  Since UseSensor1 is READ_WRITE variable, onUseSensor1Change() is
  executed every time a new value is received from IoT Cloud.
*/
void onUseSensor1Change()  {
  // Add your code here to act upon UseSensor1 change
  if (useSensor1)
  {
  
  }
}

Most recent version

C/C++
This is an Arduino cloud based sketch, so be aware there is also a thinkProperties.h file and a Secrets Tab for your wifi.
/* 
  Sketch generated by the Arduino IoT Cloud Thing "IOT_TEST copy"
  https://create.arduino.cc/cloud/things/4e5cf9d9-ac15-4b2b-869c-f41fb8e2d140 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float packVoltage;
  float temperature;
  float usbVolt;
  int moisture;
  int wifiRssi;
  bool setRelayState;
  bool useSensor;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include <ArduinoIoTCloud.h>
#include "thingProperties.h"
#include <Arduino_MKRIoTCarrier.h>
MKRIoTCarrier carrier;

int moistPin = A0; // defining the moisture sensor variable and assigning it to pin A0

// calibrate moisture sensor
const int AIR_ANALOG = 3540; // calibrate moisture sensor dry state
const int WATER_ANALOG = 1620; // calibrate moisture sensor wet state

#define Sensor A6 // defining the voltage sensor for the 12v battery pack
float vOUT = 0.0; // setting vOUT to zero at start
float vIN = 0.0; // setting vIN to zero at start
float R1=30000.0;//30kohms resistor
float R2=7500.0;//7.5kohms resistor

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  delay(500);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
  delay(500);
  CARRIER_CASE = true; //setting the case use parameter since the box is like the case for button sensitivity
  carrier.begin();
  carrier.display.setRotation(0); //setting the display rotation
  delay(500);
  
  carrier.Relay1.close(); // starting it at low or closed
  carrier.Relay2.close(); // starting it at low or closed
  

  
  
}

void loop() {
  ArduinoCloud.update();
  delay(500);
  // Your code here 
  temperature = carrier.Env.readTemperature(FAHRENHEIT) - 10; //temp calibration
  if (temperature > 95) {
      carrier.Relay1.open(); //set the relay open
    }
    // turn the relay - fan off at 95
    else if (temperature <= 95) {
      // Turn off the relay
      carrier.Relay1.close();
    } 
  
  wifiRssi = WiFi.RSSI();
  
  // if useSensor is true, read the sensor value and turn on/off the relay based on the threshold
  if (useSensor) {
    int raw_moisture = analogRead(moistPin); // read raw moisture value  
    // map raw moisture value to a scale of 0 to 100 from set constants
    moisture = map(raw_moisture, AIR_ANALOG, WATER_ANALOG, 0, 100);
    // the moisture relay settings
    // open the relay - hose valve/pump when it goes below 60%
    if (moisture < 60) {
      
      carrier.Relay2.open(); //set the relay open
    }
    // turn the relay - pump and valve off at 80% moisture
    else if (moisture >= 80) {
      
      carrier.Relay2.close();
    }   
  }
  // If useSensor is false, read the button state and turn on/off the relay based on it
  else {
    if(setRelayState == HIGH) {
    
      carrier.Relay2.open(); //set the relay open // Turn on the relay with the web button
    }
    else {
      carrier.Relay2.close(); // Turn off the relay with the web button
    }
  }
  
  analogReadResolution(12); // set the sensors analog read resolution to 12 bit - 4095
  
  int sensorValue = analogRead(A0); // set sensorValue to the voltage on pin A0
  // Convert the analog reading (which goes from 0 4095) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 4095.0);
  
  usbVolt = voltage;
  
  int value=analogRead (Sensor); // set the analog read of the 12v battery to int value
  vOUT = (value *3.3) / 4095.0; // set voltage out to value multiplied the board voltage of 3.3v
  vIN = vOUT / (R2/(R1 + R2)); // convert the vOUT to the actual pack voltage
  
  packVoltage = vIN; // set vIN to a cloud variable packVoltage
  
  carrier.Buttons.update();


  while (!carrier.Light.colorAvailable()) {
    delay(5);
  }
  
  // Carrier button 4 configuration
  if (carrier.Buttons.onTouchDown(TOUCH4)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_WHITE);
    carrier.display.setTextSize(5);

    carrier.display.setCursor(30, 110);
    carrier.display.print("RSSI");
    carrier.display.setCursor(50, 160);
    carrier.display.print(wifiRssi);
    
  }
  
// Carrier button 3 configuration
  if (carrier.Buttons.onTouchDown(TOUCH3)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_WHITE);
    carrier.display.setTextSize(5);

    carrier.display.setCursor(30, 110);
    carrier.display.print("temp");
    carrier.display.setCursor(50, 160);
    carrier.display.print(temperature);
  }
  
  // Carrier button 2 configuration
  if (carrier.Buttons.onTouchDown(TOUCH2)) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setTextColor(ST77XX_YELLOW);
    carrier.display.setTextSize(5);

    carrier.display.setCursor(30, 110);
    carrier.display.print("BattV");
    carrier.display.setCursor(50, 160);
    carrier.display.print(packVoltage);
    carrier.display.print("v");
  } 
  
  // Carrier button 1 configuration
  if (carrier.Buttons.onTouchDown(TOUCH1)) {
    carrier.display.fillScreen(ST77XX_BLACK); // background color
    carrier.display.setTextColor(ST77XX_GREEN); // text color
    carrier.display.setTextSize(5); // text size

    carrier.display.setCursor(30, 110); // set where the cursor begins printing characters line 1
    carrier.display.print("USBv"); // print usb input voltage to the carrier screen
    carrier.display.setCursor(50, 160); // set where the cursor begins printing characters line 2
    carrier.display.print(usbVolt); // print the usb input voltage variable current value

  }
  
  // Carrier button 0 configuration
  if (carrier.Buttons.onTouchDown(TOUCH0)) {
    carrier.display.fillScreen(ST77XX_BLACK); // background color
    carrier.display.setTextColor(ST77XX_WHITE); // text color
    carrier.display.setTextSize(5); // text size

    carrier.display.setCursor(30, 110); // set where the cursor begins printing characters line 1
    carrier.display.print("Moist"); // print Moisture to the carrier screen
    carrier.display.setCursor(50, 160); // set where the cursor begins printing characters line 2
    carrier.display.print(moisture); // print the Moisture variable current value
    carrier.display.print("%");

  }
}

/*
  Since SetRelayState is READ_WRITE variable, onSetRelayStateChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onSetRelayStateChange()  {
  // Add your code here to act upon SetRelayState change
}
/*
  Since UseSensor is READ_WRITE variable, onUseSensorChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onUseSensorChange()  {
  // Add your code here to act upon UseSensor change
}

SmartGarden_1_01

SmartGarden Arduino code

smartgarden repo

smartgarden full .ino

Credits

Shawn Murphy

Shawn Murphy

3 projects • 7 followers

Comments