Projects
Vehicle Circuit

Overview

The Vehicle circuit will be placed on the vehicle on to which the order items are loaded at the Seller location. It will have a load sensor that will capture the weight of the items loaded. It will also have temperature and humidity sensors that will continuously capture the transport conditions data. All data will be sent to the Database and the Smart Contract.

Components

NOTES:

  • The typical current is usage is <= half the max current required for all components.
  • All circuits require two 3.7v 18650 Li-ion batteries as power supply.
Component NamePurpose
ESP32 WroomProcessor
SIM800L GSM moduleTo send data to the IoT platform via GPRS
DHT11To capture the temperature and humidity
SW-420To capture the vibrations
HX711The ADC required by the Load sensor
1kg Load cellTo capture the load/weight
LM2596 Buck converterTo convert supply voltage to component voltage
LEDsTo indicate various states

Circuit Diagram

web3_vehicle_circuit

Assembly

NOTE: Any switch can be added in all the circuits between the +ve terminal of the battery and IN+ terminal of the buck converter

SIM800L GSM with ESP32

ESP32 PinSIM800L GSM Pin
RX2TX
TX2RX

SIM800L GSM with LM2596 Buck converter

LM2596 PinSIM800L GSM Pin
OUT+VCC
OUT-GND

DHT11/22 with ESP32

ESP32 PinDHT11/22 Pin
3v33V3
D15D0
GNDGND

SW420 with ESP32

ESP32 PinSW420 Pin
3v33V3
D25D0
GNDGND

HX711 with ESP32

ESP32 PinHX711 Pin
3v33V3
D4SCK
RX2DT
GNDGND

HX711 with Load cell

HX711 PinLoad cell Pin
E+RED
E-BLACK
A-WHITE
A+GREEN

ESP32 with LED

ESP32 PinLoad Indicator LED Pin
12Anode (+)
GNDCathod (-)

2X18650 Power Supply with LM2596 Buck converter

18650 PinLM2596 Pin
+(ve)IN+
-(ve)IN-

ESP32 with LM2596 Buck converter

ESP32 PinLM2596 Pin
VinOUT+
GNDOUT-

Code

This code sends data to the AWS IoT platform which requires certificates and keys. These need to be generated for each account and cannot be reused. Instructions for getting these will be made available to subscribers.

/*
  Project: On vehicle Microcontroller
  Project Description:
  This sketch sends readings read from various sensors to AWS MQTT broker
  This sketch involves DHT11 and HX711 Load sensors.
 
  Author: STEMVentor Educonsulting
 
  This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs.
  This code is for educational purposes only and is not for production use.
*/
 
// LIBRARIES
// all the libraries (5) needed to connect and publish to AWS MQTT:-
// includes all the credentials like certificates , wifi passwords , IoT endpoint and thing name
#include "Secrets.h"
// enbales ESP32  to connect to wifi
#include <WiFiClientSecure.h> // enbales ESP32  to connect to wifi
#include <WiFi.h>
// MQTT library which helps publishing and subscribing to topics
#include <PubSubClient.h>
// JSON library to format the message being published
#include <ArduinoJson.h>
 
// to get real time in UNIX format
#include <NTPClient.h>
 
// to read values from the DHT11/22 sensor
#include <DHT.h>
 
// Libraries to communicate and read values from Load sensor via HX711 ADC
// for I2C communication
#include <Wire.h>
// to read values from the HX711 load sensor
#include <HX711.h>
 
// PIN DEFINITIONS
#define DHTPIN 15        // Digital pin connected to the DHT sensor
#define LOADCELL_DOUT 16 // load cell
#define LOADCELL_SCK 4
#define VIBRATION_PIN 25
#define LOAD_INDICATOR_LED 12
#define ON_BOARD_LED 2
 
// Define the type of DHT being used , DHT11 or DHT22.
#define DHTTYPE DHT22 // DHT 22 (AM2302)
 
// Define the topic to which the data should be published
#define AWS_IOT_PUBLISH_TOPIC "esp32/pub/dhruv/web3/test5"
 
// GLOBAL VARIABLES
int humidity;    // to store humidity
int temperature; // to store temperature
int vibration;   // to store vibration
int load;        // to store loaded quantity
 
// to store the serialised JSON to be published
char Transport_Conditions[1000];
char Loaded_Quantity[500];
 
// device IDs
const int Temperature_and_Humidity_sensor_id = 22;
const int vibration_sensor_id = 23;
const int Weight_sensor_id = 21;
const int microcontroller_id = 2;
 
// Timing variables
unsigned long lastUpdateTime = 0; // Tracks the last update time
// the time interval in which the the microcontroller will send the transport conditions
const unsigned long updateInterval = 5000; // 5 seconds interval
 
// boolean check variable
bool loadSent = false; // to store if the loading quantity has been sent succesfully
 
/* INITIALIZE OBJECTS
 * Libraries usually follow an object-oriented approach that requires
 * an instance of the class to call its methods.
 */
DHT dht(DHTPIN, DHTTYPE);                        // DHT object
HX711 scale;                                     // load cell object
WiFiClientSecure net;                            // wifi client
PubSubClient client(net);                        // MQTT client
WiFiUDP ntpUDP;                                  // UDP client
NTPClient timeClient(ntpUDP, "id.pool.ntp.org"); // NTPC client
 
// setup functions for AWS , Wifi , DHT11 , NTPC , SW420 and HX711
// function to setup wifi
void Wifi_setup()
{
 
  WiFi.mode(WIFI_STA);                  // station mode , where the device connects to an external wifi network
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // gets the ssid and password from the secrets.h file
 
  Serial.println("Connecting to Wi-Fi");
 
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
}
// function to setup AWS
void AWS_setup()
{
 
  // Configure WiFiClientSecure to use the AWS IoT device credentials
  net.setCACert(AWS_CERT_CA);
  net.setCertificate(AWS_CERT_CRT);
  net.setPrivateKey(AWS_CERT_PRIVATE);
 
  // Connect to the MQTT broker on the AWS endpoint we defined earlier
  client.setServer(AWS_IOT_ENDPOINT, 8883);
 
  // Create a message handler
  // client.setCallback(messageHandler);
 
  Serial.println("Connecting to AWS IoT");
 
  while (!client.connected())
  {
    Serial.print(".");
    if (client.connect(THINGNAME))
    {
      Serial.println("Connected to AWS IoT");
      // subscribe over here
    }
    else
    {
      Serial.println("AWS IoT Connection Failed! Retrying...");
      int errorCode = client.state();
      Serial.print("Error code: ");
      Serial.println(errorCode);
      delay(1000);
    }
  }
}
// function to setup NTPC to get real time value
void NTPC_setup()
{
  timeClient.begin();
  timeClient.setTimeOffset(0);
}
 
// function to setup temperature and humidity sensor
void DHT11_setup()
{
  dht.begin();
}
 
// function to setup HX711 ADC to read values from load sensor
void HX711_setup()
{
  Wire.begin();
  scale.begin(LOADCELL_DOUT, LOADCELL_SCK);
  scale.set_scale();
  scale.tare(); // Tare the scale (set it to zero)
}
 
// function to setup vibration sensor
void SW420_setup()
{
  pinMode(VIBRATION_PIN, INPUT);
}
 
// function to setup indicator LED
void LEDSetup()
{
  pinMode(LOAD_INDICATOR_LED, OUTPUT);
  pinMode(ON_BOARD_LED, OUTPUT);
  digitalWrite(LOAD_INDICATOR_LED, LOW);
  digitalWrite(ON_BOARD_LED, LOW);
}
 
// function to read temperature and humidity from DHT sensor
void readDHT()
{
  humidity = dht.readHumidity();
  temperature = dht.readTemperature();
  // print the values
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print(("%  Temperature: "));
  Serial.print(temperature);
  Serial.println("°C ");
}
 
// function to read value from vibration sensor
void readSW420()
{
  vibration = digitalRead(VIBRATION_PIN);
  if (vibration == 1)
  {
    Serial.println("Vibration: High");
  }
  else
  {
    Serial.println("Vibration: Low");
  }
}
 
// function to read load value from the HX711 sensor
void readHX711()
{
  load = scale.get_units(5); // in kg
  load = (load / 420);       // 420 is the calibration factor (needs to be measured separately)
  load = load * 1000;        // convert to grams
  Serial.print("Loaded quantity: ");
  Serial.print(load);
  Serial.println(" g");
}
 
// function to form JSON of transport conditions to publish
void JSON_formatter_TC() // TC stands for transport conditions
{
  JsonDocument doc;
 
  doc["timestamp"] = timeClient.getEpochTime();
  delay(300);
  doc["microcontroller_id"] = microcontroller_id;
 
  JsonArray sensor_data = doc["sensor_data"].to<JsonArray>();
 
  JsonObject sensor_data_0 = sensor_data.add<JsonObject>();
  sensor_data_0["sensor_id"] = Temperature_and_Humidity_sensor_id;
 
  JsonObject sensor_data_0_parameters = sensor_data_0["parameters"].to<JsonObject>();
  sensor_data_0_parameters["temperature"] = temperature;
  sensor_data_0_parameters["humidity"] = humidity;
 
  JsonObject sensor_data_2 = sensor_data.add<JsonObject>();
  sensor_data_2["sensor_id"] = vibration_sensor_id;
  sensor_data_2["parameters"]["vibration"] = vibration;
 
  doc.shrinkToFit(); // compresses the size of the JSON
  serializeJson(doc, Transport_Conditions);
}
 
// function to form JSON of Loaded quantity to publish
void JSON_formatter_LQ() // LQ stands for Loaded Quantity
{
  JsonDocument doc;
 
  doc["timestamp"] = timeClient.getEpochTime();
  delay(300);
  doc["microcontroller_id"] = microcontroller_id;
 
  JsonArray sensor_data = doc["sensor_data"].to<JsonArray>();
 
  JsonObject sensor_data_0 = sensor_data.add<JsonObject>();
  sensor_data_0["sensor_id"] = Weight_sensor_id;
 
  JsonObject sensor_data_0_parameters = sensor_data_0["parameters"].to<JsonObject>();
  sensor_data_0_parameters["weight"] = load;
 
  doc.shrinkToFit(); // compresses the size of the JSON
  serializeJson(doc, Loaded_Quantity);
}
 
// function to check wifi connection
void checkWIFI()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Wi-Fi not connected, reconnecting...");
    Wifi_setup();
  }
}
 
// function to check AWS connection
void checkAWS()
{
  if (!client.connected())
  {
    Serial.println("AWS IoT not connected, reconnecting...");
    AWS_setup();
  }
}
 
// function to publish message to MQTT topic
void publishMessage(char message[1000])
{
  bool publish_check = false; // variable to indicate if MQTT publsih has happened succesfully or no
  int publish_counter = 0;    // variable to store number of times MQTT publish has been tried
  while (publish_check == false)
  {
    if (!client.publish(AWS_IOT_PUBLISH_TOPIC, message))
    {
      Serial.println("Failed to publish message 1");
      Serial.println("Checking connection with AWS IoT...");
      checkAWS();
      delay(1000);
      if (publish_counter > 3) // if publish is not successfull for 3 times then restart the ESP.
      {
        Serial.println("Restarting the ESP");
        ESP.restart();
      }
    }
    else
    {
      Serial.println("Message published successfully");
      publish_check = true;
    }
    publish_counter++;
  }
}
 
// Main setup function
void setup()
{
  Serial.begin(115200);
  LEDSetup();
  Wifi_setup();
  AWS_setup();
  DHT11_setup();
  HX711_setup();
  NTPC_setup();
  Serial.println("setup done succesfully");
  digitalWrite(ON_BOARD_LED, HIGH);
  delay(2000);
}
 
// Main Loop Function
void loop()
{
  // check wifi connection before every loop starts
  checkWIFI();
 
  // To measuer the loaded quantity only once at the start
  readHX711(); // reads load value from HX711
 
  if (load >= 100)
  {
    digitalWrite(LOAD_INDICATOR_LED, HIGH);
    if (loadSent == false)
    {
      JSON_formatter_LQ();             // forms the JSON
      publishMessage(Loaded_Quantity); // publishes the loaded quantity to the topic
      loadSent = true;
    }
  }
 
  else
  {
    digitalWrite(LOAD_INDICATOR_LED, LOW);
  }
 
  unsigned long currentTime = millis(); // checks if 5 seconds have passed by since the last update
  if (currentTime - lastUpdateTime >= updateInterval)
  {
    timeClient.update();
    readDHT();                            // reads temperature and humidity
    readSW420();                          // reads the vibration value from the SW420 sensor
    JSON_formatter_TC();                  // formats into desired JSON structure
    publishMessage(Transport_Conditions); // publishes to MQTT topic
  }
}