#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085.h>
#include <math.h>
#include <LiquidCrystal.h>
#include <WiFi.h>
#include <ThingSpeak.h>
// =======================
// 📡 Wi-Fi Credentials (Optional - remove if not using ThingSpeak)
// =======================
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// =======================
// 📊 ThingSpeak Settings (Optional)
// =======================
unsigned long channelID = YOUR_CHANNEL_ID;
const char* apiKey = "YOUR_WRITE_API_KEY";
WiFiClient client;
// =======================
// 🔌 Pin Definitions (ESP32 for Wokwi)
// =======================
// HC-SR04 Ultrasonic
#define TRIG 33
#define ECHO 32
// Vibration Sensor (Potentiometer)
#define VIB 36
// Buzzer
#define BUZZER 17
// LCD Pins
#define LCD_RS 26
#define LCD_E 27
#define LCD_D4 18
#define LCD_D5 19
#define LCD_D6 23
#define LCD_D7 25
// Initialize LCD
LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
// =======================
// 🌡️ BMP180 Sensor
// =======================
Adafruit_BMP085 bmp;
// =======================
// 📍 GPS Simulation Variables
// =======================
float latitude = 52.629567;
float longitude = 4.885383;
// =======================
// 📊 Sensor Variables
// =======================
int vibrationValue;
long duration;
float distance;
int16_t AcX, AcY, AcZ;
float angleX, angleY;
float temperature, pressure, altitude;
// =======================
// ⏱️ Timing
// =======================
unsigned long lastUploadTime = 0;
const unsigned long uploadInterval = 15000;
// =======================
// 🚨 Danger flag
// =======================
bool danger = false;
// =======================
// 🟢 SETUP
// =======================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("");
Serial.println("=== SMART TANK TRUCK MONITORING SYSTEM ===");
Serial.println("ESP32 Starting...");
// Initialize pins
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(BUZZER, OUTPUT);
// Initialize LCD
lcd.begin(16, 2);
lcd.print("System Init...");
delay(2000);
lcd.clear();
// Initialize I2C
Wire.begin();
// Wake up MPU6050 (address 0x68)
Wire.beginTransmission(0x68);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.println("MPU6050 initialized");
// Initialize BMP180 using Adafruit library
if (!bmp.begin()) {
lcd.clear();
lcd.print("BMP180 ERROR!");
Serial.println("BMP180 ERROR - Check wiring");
while (1) {
delay(1000);
}
}
Serial.println("BMP180 initialized");
// Optional: Connect to Wi-Fi (remove if not using ThingSpeak)
lcd.clear();
lcd.print("System Ready!");
delay(1500);
lcd.clear();
// Initialize ThingSpeak (optional)
// ThingSpeak.begin(client);
}
// =======================
// 🔵 READ ULTRASONIC DISTANCE
// =======================
float readUltrasonic() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
duration = pulseIn(ECHO, HIGH, 30000);
if (duration == 0) {
return 999;
}
return duration * 0.034 / 2;
}
// =======================
// 🟣 READ MPU6050 (Tilt Angles)
// =======================
void readMPU6050() {
Wire.beginTransmission(0x68);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(0x68, 6, true);
AcX = Wire.read() << 8 | Wire.read();
AcY = Wire.read() << 8 | Wire.read();
AcZ = Wire.read() << 8 | Wire.read();
angleX = atan(AcY / sqrt(pow(AcX, 2) + pow(AcZ, 2))) * 180 / PI;
angleY = atan(-AcX / sqrt(pow(AcY, 2) + pow(AcZ, 2))) * 180 / PI;
}
// =======================
// 🟡 READ BMP180 (Using Adafruit Library - WORKS IN WOKWI!)
// =======================
void readBMP180() {
temperature = bmp.readTemperature(); // Changes when you move BMP180 slider
pressure = bmp.readPressure(); // Changes when you move BMP180 slider
altitude = bmp.readAltitude(); // Calculated from pressure
}
// =======================
// 🟢 UPDATE GPS SIMULATION
// =======================
void updateGPS() {
latitude += 0.00001;
longitude += 0.00001;
}
// =======================
// 🧠 DECISION LOGIC (Adjusted for ESP32 12-bit ADC)
// =======================
void evaluateDanger() {
danger = false;
if (distance < 50) {
danger = true;
Serial.println("⚠️ DANGER: Collision imminent!");
}
// ESP32 ADC is 12-bit (0-4095). 2800 ≈ 68% of max (same as 700 on 10-bit)
if (vibrationValue > 2800) {
danger = true;
Serial.println("⚠️ DANGER: High vibration detected!");
}
if (abs(angleX) > 30 || abs(angleY) > 30) {
danger = true;
Serial.println("⚠️ DANGER: Rollover risk! Tilt angle >30°");
}
if (pressure < 60000) {
danger = true;
Serial.println("⚠️ DANGER: Low pressure detected!");
}
}
// =======================
// 🔊 CONTROL BUZZER
// =======================
void controlBuzzer() {
if (danger) {
tone(BUZZER, 1000);
} else {
noTone(BUZZER);
}
}
// =======================
// 📟 UPDATE LCD DISPLAY
// =======================
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("D:");
lcd.print((int)distance);
lcd.print("cm T:");
lcd.print((int)temperature);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("P:");
lcd.print((int)(pressure / 100));
lcd.print("hPa ALT:");
lcd.print((int)altitude);
lcd.print("m");
}
// =======================
// 📤 UPLOAD TO THINGSPEAK (Optional)
// =======================
void uploadToThingSpeak() {
// Uncomment if using ThingSpeak
/*
ThingSpeak.setField(1, distance);
ThingSpeak.setField(2, vibrationValue);
ThingSpeak.setField(3, angleX);
ThingSpeak.setField(4, angleY);
ThingSpeak.setField(5, temperature);
ThingSpeak.setField(6, pressure / 100);
ThingSpeak.setField(7, altitude);
ThingSpeak.setField(8, danger ? 1 : 0);
ThingSpeak.writeFields(channelID, apiKey);
*/
}
// =======================
// 🖨️ SERIAL DEBUG OUTPUT
// =======================
void serialDebug() {
Serial.print("DIST:");
Serial.print(distance);
Serial.print(",VIB:");
Serial.print(vibrationValue);
Serial.print(",AX:");
Serial.print(angleX);
Serial.print(",AY:");
Serial.print(angleY);
Serial.print(",TEMP:");
Serial.print(temperature);
Serial.print(",PRES:");
Serial.print(pressure);
Serial.print(",ALT:");
Serial.print(altitude);
Serial.print(",LAT:");
Serial.print(latitude, 6);
Serial.print(",LON:");
Serial.print(longitude, 6);
Serial.print(",ALERT:");
Serial.print(danger ? "YES" : "NO");
Serial.println();
}
// =======================
// 🔄 MAIN LOOP
// =======================
void loop() {
distance = readUltrasonic();
vibrationValue = analogRead(VIB);
readMPU6050();
readBMP180(); // Now reads actual BMP180 values from Wokwi!
updateGPS();
evaluateDanger();
controlBuzzer();
updateLCD();
serialDebug();
// Optional ThingSpeak upload
// if (millis() - lastUploadTime >= uploadInterval) {
// uploadToThingSpeak();
// lastUploadTime = millis();
// }
delay(200);
}Loading
bmp180
bmp180