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 Name | Purpose |
---|---|
ESP32 Wroom | Processor |
SIM800L GSM module | To send data to the IoT platform via GPRS |
DHT11 | To capture the temperature and humidity |
SW-420 | To capture the vibrations |
HX711 | The ADC required by the Load sensor |
1kg Load cell | To capture the load/weight |
LM2596 Buck converter | To convert supply voltage to component voltage |
LEDs | To indicate various states |
Circuit Diagram
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 Pin | SIM800L GSM Pin |
---|---|
RX2 | TX |
TX2 | RX |
SIM800L GSM with LM2596 Buck converter
LM2596 Pin | SIM800L GSM Pin |
---|---|
OUT+ | VCC |
OUT- | GND |
DHT11/22 with ESP32
ESP32 Pin | DHT11/22 Pin |
---|---|
3v3 | 3V3 |
D15 | D0 |
GND | GND |
SW420 with ESP32
ESP32 Pin | SW420 Pin |
---|---|
3v3 | 3V3 |
D25 | D0 |
GND | GND |
HX711 with ESP32
ESP32 Pin | HX711 Pin |
---|---|
3v3 | 3V3 |
D4 | SCK |
RX2 | DT |
GND | GND |
HX711 with Load cell
HX711 Pin | Load cell Pin |
---|---|
E+ | RED |
E- | BLACK |
A- | WHITE |
A+ | GREEN |
ESP32 with LED
ESP32 Pin | Load Indicator LED Pin |
---|---|
12 | Anode (+) |
GND | Cathod (-) |
2X18650 Power Supply with LM2596 Buck converter
18650 Pin | LM2596 Pin |
---|---|
+(ve) | IN+ |
-(ve) | IN- |
ESP32 with LM2596 Buck converter
ESP32 Pin | LM2596 Pin |
---|---|
Vin | OUT+ |
GND | OUT- |
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
}
}