Rain Ye
Published

AI Guardian for Plants

The AI Guardian for Plants is designed to monitor the soil data in real time

BeginnerFull instructions provided5 hours1,012
AI Guardian for Plants

Things used in this project

Hardware components

SenseCAP K1100 - The Sensor Prototype Kit with LoRa® and AI
Seeed Studio SenseCAP K1100 - The Sensor Prototype Kit with LoRa® and AI
×1
Seeed Studio Grove - Universal 4 Pin Buckled 5cm Cable (5 PCs Pack)
Seeed Studio Grove - Universal 4 Pin Buckled 5cm Cable (5 PCs Pack)
×1
Soil Moisture & Temperature Sensor
Seeed Studio Soil Moisture & Temperature Sensor
×1
USB-A to Mini-USB Cable
USB-A to Mini-USB Cable
×1

Software apps and online services

Ubidots
Ubidots
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Tape, Double Sided
Tape, Double Sided
Scissor, Electrician
Scissor, Electrician

Story

Read more

Code

AI Guardian for Plants

C/C++
#include "TFT_eSPI.h"
#include "Seeed_FS.h" //Including SD card library
#include "RawImage.h"  //Including image processing library
#include "Seeed_Arduino_GroveAI.h"
#include "Free_Fonts.h"
#include <PubSubClient.h>
#include <rpcWiFi.h>
#include <Wire.h>

#define WIFISSID "STU-EE" // Put your WifiSSID here
#define PASSWORD "stu-ee-2022" // Put your wifi password here
#define TOKEN "BBFF-0Bgo88gCwrbEUmbEVwIQaqHrFW0tGv" // Put your Ubidots' TOKEN
#define VARIABLE_LABEL1 "soil" // Assign the variable label
#define VARIABLE_LABEL2 "num"
#define VARIABLE_LABEL3 "confidence"
#define DEVICE_LABEL "wio-terminal" // Assign the device label
#define MQTT_CLIENT_NAME "o9rp2cwhty" // MQTT client Name

const long interval = 100;
unsigned long previousMillis = 0;

char mqttBroker[] = "industrial.api.ubidots.com";

WiFiClient wifiClient;
PubSubClient client(wifiClient);

GroveAI ai(Wire);
uint8_t state = 0;
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft); // Sprite

int sensorPin = A0;
static int soilValue = 0;
static int num = 0;
static int conf = 0;
static int cont = 0;

// Space to store values to send
char str_soil[6];
char str_num[6];
char str_conf[6];
char payload[700];
char topic[150];

void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");

  // Attempt to connect
  if (client.connect(MQTT_CLIENT_NAME, TOKEN,"")) {
    Serial.println("connected");
  }
  else {
    Serial.print("failed, rc=");
    Serial.print(client.state());
    Serial.println(" try again in 2 seconds");
    // Wait 2 seconds before retrying
    delay(2000);
    }
  }
}

void VisionAI_Init()   //Vision AI 
{
  Serial.println("begin");
  if (ai.begin(ALGO_OBJECT_DETECTION, MODEL_EXT_INDEX_1)) // Object detection and pre-trained model 1
  {
    state = 1;
  }
  else
  {
    Serial.println("Algo begin failed.");
  }
}

void read_VisionAI()  //VisionAI
{
  if (state == 1)
  {
    uint32_t tick = millis();
    if (ai.invoke()) // begin invoke
    {
      while (1) // wait for invoking finished
      {
        CMD_STATE_T ret = ai.state(); 
        if (ret == CMD_STATE_IDLE)
        {
          break;
        }
        delay(20);
      }
      uint8_t len = ai.get_result_len(); // receive how many people detect
      if(len)
      {
         Serial.print("Number of people: ");

         num = len;
         Serial.print(num);

         object_detection_t data;       //get data
         for (int i = 0; i < len; i++)
         {
            ai.get_result(i, (uint8_t*)&data, sizeof(object_detection_t)); //get result
            Serial.print("confidence:");
            
            conf = data.confidence;
            Serial.print(conf);
            Serial.println();
          }
      }
     else
     {
       Serial.println("No identification");
       num = 0;
       conf = 0;
     }
   }
    else
    {
      Serial.println("Invoke Failed.");
      delay(1000);
    }
  }
}

void read_soil() //
{
  soilValue = analogRead(sensorPin);
  Serial.print("Moisture = ");
  Serial.println(soilValue);
  if (soilValue > 500) cont = 2;
  if (soilValue < 450) cont = 1;
}

void Display(int content)  //
{
  if(content == 1)drawImage<uint8_t>("sad.bmp", 0, 0);     //
  if(content == 2)drawImage<uint8_t>("happy.bmp", 0, 0);   //

  spr.createSprite(320, 100);

  spr.setFreeFont(FSSO9);
  spr.setTextColor(TFT_WHITE);
  spr.drawString("Count", 15, 10, GFXFF);
  spr.drawString("Confidence", 100, 10, GFXFF);
  spr.drawString("Soil Mois", 220, 10, GFXFF);
  
  spr.setFreeFont(FSSB24);
  spr.setTextColor(TFT_WHITE);
  spr.drawNumber(num, 15, 35, GFXFF);
  spr.drawNumber(conf, 100, 35, GFXFF);
  spr.drawNumber(soilValue, 220, 35, GFXFF);

  spr.pushSprite(0, 140);
  spr.deleteSprite();
}

void send_data()
{
  dtostrf(soilValue, 4, 0, str_soil);
  dtostrf(num, 4, 0, str_num);
  dtostrf(conf, 4, 0, str_conf);
  
  if (!client.connected()) {
    reconnect();
  }
  // Builds the topic
  sprintf(topic, "%s", ""); // Cleans the topic content
  sprintf(topic, "%s%s", "/v2.0/devices/", DEVICE_LABEL);

  //Builds the payload
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL1); // Adds the variable label
  sprintf(payload, "%s%s", payload, str_soil); // Adds the value
  sprintf(payload, "%s}", payload); // Closes the dictionary brackets

  client.publish(topic, payload);
  delay(500);

  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL2); // Adds the variable label
  sprintf(payload, "%s%s", payload, str_num); // Adds the value
  sprintf(payload, "%s}", payload); // Closes the dictionary brackets

  client.publish(topic, payload);
  delay(500);

  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL3); // Adds the variable label
  sprintf(payload, "%s%s", payload, str_conf); // Adds the value
  sprintf(payload, "%s}", payload); // Closes the dictionary brackets

  client.publish(topic, payload);
  delay(500);

  client.loop();
}

void buzzer()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    
    if(soilValue < 450 && num !=0)analogWrite(WIO_BUZZER, 128);
    else analogWrite(WIO_BUZZER, 0);
  }
  else analogWrite(WIO_BUZZER, 0);
}


void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(WIO_BUZZER, OUTPUT);
  
  //while(!Serial);
  
  //Initialise SD card
  if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI)) {
      while (1);
  }
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);

  tft.setFreeFont(FSSB12);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    tft.drawString("Connecting to WiFi...",15,100,GFXFF);
    WiFi.begin(WIFISSID, PASSWORD);
  }
  
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.begin(WIFISSID, PASSWORD);

  tft.fillScreen(TFT_BLACK);
  tft.drawString("Connected to the WiFi network",15,100,GFXFF);
  tft.fillScreen(TFT_BLACK);
  drawImage<uint8_t>("sad.bmp", 0, 0);     //

  delay(1000);
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);

  VisionAI_Init();
}

void loop() {
  Display(cont);
  read_soil();
  read_VisionAI();
  buzzer();
  send_data();
}

Credits

Rain Ye

Rain Ye

1 project • 11 followers

Comments