Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Hendra Kusumah
Published © GPL3+

TinyML Package Monitor

TinyML based Package detection for home usage

BeginnerFull instructions provided5 hours1,198
TinyML Package Monitor

Things used in this project

Hardware components

WizFi360-EVB-Pico
WIZnet WizFi360-EVB-Pico
×1
Seeed Studio grove vision AI module
×1
2x15 Pin Headers Socket 2.54mm Male & Female 4 Pair Connector
M5Stack 2x15 Pin Headers Socket 2.54mm Male & Female 4 Pair Connector
×1
Hook Up Wire Kit, 22 AWG
Hook Up Wire Kit, 22 AWG
×1

Software apps and online services

Arduino IDE
Arduino IDE
Ubidots
Ubidots

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
3D Printer (generic)
3D Printer (generic)

Story

Read more

Schematics

wiring

Code

Inference Test

Arduino
#include "Seeed_Arduino_GroveAI.h"
#include <Wire.h>
 
GroveAI ai(Wire);
uint8_t state = 0;

void setup()
{
  Wire.setSDA(0);
  Wire.setSCL(1);
  Wire.begin();
  Serial.begin(115200);
 
   Serial.println("begin");
  if (ai.begin(ALGO_OBJECT_DETECTION, MODEL_EXT_INDEX_1)) // Object detection and pre-trained model 1
  {
    Serial.print("Version: ");
    Serial.println(ai.version());
    Serial.print("ID: ");
    Serial.println( ai.id());
    Serial.print("Algo: ");
    Serial.println( ai.algo());
    Serial.print("Model: ");
    Serial.println(ai.model());
    Serial.print("Confidence: ");
    Serial.println(ai.confidence());
    state = 1;
  }
  else
  {
    Serial.println("Algo begin failed.");
  }
}
 
void loop()
{
  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)
     {
       int time1 = millis() - tick; 
       Serial.print("Time consuming: ");
       Serial.println(time1);
       Serial.print("Number of people: ");
       Serial.println(len);
       object_detection_t data;       //get data
 
       for (int i = 0; i < len; i++)
       {
          Serial.println("result:detected");
          Serial.print("Detecting and calculating: ");
          Serial.println(i+1);
          ai.get_result(i, (uint8_t*)&data, sizeof(object_detection_t)); //get result
 
          Serial.print("confidence:");
          Serial.print(data.confidence);
          Serial.println();

        }
     }
     else
     {
       Serial.println("No identification");
     }
    }
    else
    {
      delay(1000);
      Serial.println("Invoke Failed.");
    }
  }
  else
  {
    state == 0;
  }
}

Main code

Arduino
#include <Arduino.h>
#include "WizFi360.h"
#include "SoftwareSerial.h"

#include "Seeed_Arduino_GroveAI.h"
#include <Wire.h>

#define WIZFI360_EVB_PICO

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
#if defined(ARDUINO_MEGA_2560)
SoftwareSerial Serial1(6, 7); // RX, TX
#elif defined(WIZFI360_EVB_PICO)
SoftwareSerial Serial2(5, 4); // RX, TX
#endif
#endif

namespace {
  char ssid[] = "xxxxx"; // Assign your Network SSID
  char pass[] = "xxxxxxx";  // Assign your Network password
  char SERVER[] = "industrial.api.ubidots.com"; // Ubidots Server
  const char * TOKEN = "BBFF-xxxxxxxxxxxxxx"; // Assign your Ubidots TOKEN
  const char * DEVICE_LABEL = "package-monitor"; // Ubidots Device Label
  const char * USER_AGENT = "wiznet";
  const char * VERSION = "1.0";
  const int PORT = 80;
  int  status = WL_IDLE_STATUS; // the Wifi radio's status  
}

WiFiClient client;
GroveAI ai(Wire);
uint8_t state = 0;

void setup() {
  Wire.setSDA(0);
  Wire.setSCL(1);
  Wire.begin();
  Serial.begin(115200);
  Serial2.begin(115200);
  
  delay(6000);
  Serial.print("Starting...");
  Serial.println("WiFi initiallize");
  WiFi.init(&Serial2);
  
  if (WiFi.status() == 0) { 
    Serial.println("Failed to configure WiFi");
    // don't continue
    while(true)
    ;
  }
  //attempt to connect to WiFi network
  while (status != WL_CONNECTED) {
    Serial.print("[WiFi] Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    //Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
    Serial.println("Connected!");
  }
  
  delay(1000);
   if (ai.begin(ALGO_OBJECT_DETECTION, MODEL_EXT_INDEX_1)) // Object detection and pre-trained model 1
  {
    Serial.print("Version: ");
    Serial.println(ai.version());
    Serial.print("ID: ");
    Serial.println( ai.id());
    Serial.print("Algo: ");
    Serial.println( ai.algo());
    Serial.print("Model: ");
    Serial.println(ai.model());
    Serial.print("Confidence: ");
    Serial.println(ai.confidence());
    state = 1;
  }
  else
  {
    Serial.println("Algo begin failed.");
  }
}

void loop() {
  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)
     {
       int time1 = millis() - tick; 
       Serial.print("Time consuming: ");
       Serial.println(time1);
       Serial.print("Number of package: ");
       Serial.println(len);
       object_detection_t data;       //get data
 
       for (int i = 0; i < len; i++)
       {
          Serial.println("result:detected");
          Serial.print("Detecting and calculating: ");
          Serial.println(i+1);
          ai.get_result(i, (uint8_t*)&data, sizeof(object_detection_t)); //get result
 
          Serial.print("confidence:");
          Serial.print(data.confidence);
          Serial.println();
          //Serial.print("detected object:");
          //Serial.print(animalclass[data.target]);
          //Serial.println();
        }
          Serial.println("Sending sensor value...");
          sendValue("confidence", data.confidence);
          sendValue("total_package", len);
     }
     else
     {
       Serial.println("No identification");
     }
    }
    else
    {
      delay(1000);
      Serial.println("Invoke Failed.");
    }
  }
  else
  {
    state == 0;
  }
  //int sensor_value = 15;

  delay(1000);
}

void sendValue(const char * variable_label, int value) {
  
  /* Build the body to be POST */
  char* body = (char *) malloc(sizeof(char) * 100);
  sprintf(body, "{\"%s\":%d}", variable_label, value);

  /* Builds the HTTP request to be POST */
  char* data = (char *) malloc(sizeof(char) * 300);
  sprintf(data, "POST /api/v1.6/devices/%s", DEVICE_LABEL);
  sprintf(data, "%s HTTP/1.1\r\n", data);
  sprintf(data, "%sHost: industrial.api.ubidots.com\r\n", data);
  sprintf(data, "%sUser-Agent: %s/%s\r\n", data, USER_AGENT, VERSION);
  sprintf(data, "%sX-Auth-Token: %s\r\n", data, TOKEN);
  sprintf(data, "%sConnection: close\r\n", data);
  sprintf(data, "%sContent-Type: application/json\r\n", data);
  sprintf(data, "%sContent-Length: %d\r\n\r\n", data, dataLen(body)); 
  sprintf(data, "%s%s\r\n\r\n", data, body);

  if (client.connect(SERVER, PORT)) {
    client.print(data);
  } else {
    Serial.println("connection failed");
  }
  
  while (!client.available());
    //Serial1.println("Reading..");
  while (client.available()) {
    char c = client.read();
    Serial.print(c); // Response Monitoring
  }
  client.flush();
  client.stop();
  free(body);
  free(data);
}

int dataLen(char* variable) {
  uint8_t dataLen = 0;
  for (int i = 0; i <= 250; i++) {
    if (variable[i] != '\0') {
      dataLen++;
    } else {
      break;
    }
  }
  return dataLen;
}

Credits

Hendra Kusumah

Hendra Kusumah

30 projects • 129 followers
Love hacking and making new things from IoT to robotics

Comments