Md. Khairul Alam
Published © MIT

Solar Power Irrigation Schedular for Precision Farming

Monitor soil moisture accurately in real-time, anytime from anywhere, for optimal irrigation scheduling.

IntermediateFull instructions providedOver 1 day896
Solar Power Irrigation Schedular for Precision Farming

Things used in this project

Hardware components

Seeed Studio XIAO SAMD21 (Pre-Soldered) - Seeeduino XIAO
Seeed Studio XIAO SAMD21 (Pre-Soldered) - Seeeduino XIAO
×1
SenseCAP K1100 - The Sensor Prototype Kit with LoRa® and AI
Seeed Studio SenseCAP K1100 - The Sensor Prototype Kit with LoRa® and AI
×1
Lipo Rider v1.3
Seeed Studio Lipo Rider v1.3
×1
Seeeduino XIAO Expansion board
Seeed Studio Seeeduino XIAO Expansion board
×1
Seeed Studio Small Solar Panel 55x70mm 0.5W
×1
Li-Ion Battery 100mAh
Li-Ion Battery 100mAh
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires

Story

Read more

Custom parts and enclosures

3D Case - Top

You need to enable support for perfectly printing this part

3D Case - Middle

3D Case - Bottom

Schematics

Schematic- soil moisture sensor unit

Designed in EasyEDA

PCB Layout - Soil Moisture Sensor Unit

PCB layout for toner transfer method

Code

Code for Seeed XIAO

Arduino
Sleep mode is enabled in the code for power saving.
#include <Arduino.h>
#include <RTCZero.h>

RTCZero rtc;

int counter = 0;

const byte seconds = 0;
const byte minutes = 00;
const byte hours = 00;
const byte day = 17;
const byte month = 9;
const byte year = 22;

bool matched = false;
 
static char recv_buf[512];
static bool is_exist = true;
static bool is_join = false;

 
static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...)
{
    int ch;
    int num = 0;
    int index = 0;
    int startMillis = 0;
    va_list args;
    memset(recv_buf, 0, sizeof(recv_buf));
    va_start(args, p_cmd);
    Serial.printf(p_cmd, args);
    va_end(args);
    delay(200);
    startMillis = millis();
 
    if (p_ack == NULL)
    {
        return 0;
    }
 
    do
    {
        while (Serial.available() > 0)
        {
            ch = Serial.read();
            recv_buf[index++] = ch;
            delay(2);
        }
 
        if (strstr(recv_buf, p_ack) != NULL)
        {
            return 1;
        }
 
    } while (millis() - startMillis < timeout_ms);
    return 0;
}

 
void setup(void)
{
    pinMode(2, OUTPUT);
    Serial.begin(9600);
 
    if (at_send_check_response("+AT: OK", 100, "AT\r\n"))
    {
        is_exist = true;
        at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
        at_send_check_response("+MODE: LWOTAA", 1000, "AT+MODE=LWOTAA\r\n");
        at_send_check_response("+DR: EU868", 1000, "AT+DR=EU868\r\n");
        at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,0-2\r\n");
        at_send_check_response("+KEY: APPKEY", 1000, "AT+KEY=APPKEY,\"2B7E151628AED2A6ABF7158809CF4F3C\"\r\n");
        at_send_check_response("+CLASS: C", 1000, "AT+CLASS=A\r\n");
        at_send_check_response("+PORT: 8", 1000, "AT+PORT=8\r\n");
        delay(200);
        is_join = true;
    }
    else
    {
        is_exist = false;
    }

    rtc.begin(); //Start RTC library, this is where the clock source is initialized
  
    rtc.setTime(hours, minutes, seconds); 
    rtc.setDate(day, month, year); 

    rtc.setAlarmTime(00, 00, 10); //set alarm time to go off in 10 seconds
  
    //following two lines enable alarm, comment both out if you want to do external interrupt
    rtc.enableAlarm(rtc.MATCH_HHMMSS); //set alarm
    rtc.attachInterrupt(alarmMatch); //creates an interrupt that wakes the SAMD21
    digitalWrite(LED_BUILTIN, HIGH); //turn LED off
    //puts SAMD21 to sleep
    rtc.standbyMode();  
}

 
void loop(void)
{  
   if (matched) {
    matched = false; 
    digitalWrite(2, HIGH); //enable soil sensor
    int soil_value = 0;
    for(int i=0; i<10;i++){
      soil_value += analogRead(A1);
      delay(10);
      }
    soil_value = soil_value/10;
    digitalWrite(2, LOW); //disable soil sensor
    if (is_exist)
    {
        int ret = 0;
        if (is_join)
        {
 
            ret = at_send_check_response("+JOIN: Network joined", 12000, "AT+JOIN\r\n");
            if (ret)
            {
                is_join = false;
            }
            else
            {
                at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
                Serial.print("JOIN failed!\r\n\r\n");
                delay(5000);
            }
        }
        else
        {
            char cmd[128];
            sprintf(cmd, "AT+CMSGHEX=\"%04X\"\r\n", soil_value);
            ret = at_send_check_response("Done", 5000, cmd);
            if (ret)
            {
                ;//recv_prase(recv_buf);
            }
            else
            {
                ;
            }
            delay(5000);
        }
    }
    else
    {
        delay(1000);
    }

   
  }
  int alarmMinutes = rtc.getMinutes();
  int alarmHours = rtc.getHours();
  alarmHours += 1;   //wake every 1 hour
    if (alarmHours >= 23) {
       alarmHours = 0;
    }

  rtc.setAlarmTime(alarmHours, alarmMinutes, rtc.getSeconds());
  rtc.standbyMode();    // Sleep until next alarm match
}


void alarmMatch() {
  matched = true;
}

Credits

Md. Khairul Alam

Md. Khairul Alam

64 projects • 569 followers
Developer, Maker & Hardware Hacker. Currently working as a faculty at the University of Asia Pacific, Dhaka, Bangladesh.

Comments