GPS Module (NEO-6M)
RX ➔ GPIO 17
TX ➔ GPIO 16
VCC ➔ 3.3V / 5V
Crash Sensor (MPU-6050)
SDA ➔ GPIO 21
SCL ➔ GPIO 22
VCC ➔ 3.3V
WiFi Connection
2.4GHz WiFi / Hotspot
Direct HTTPS REST
Firestore Cloud
Telemetry Stream
5s GPS Updates
Instant G-Shock Alert
Sub-second Trigger
Arduino IDE Source Code:
// =========================================================================
// IGHS Gateway Firmware: Arduino Nano (LiDAR) ➔ NodeMCU / ESP8266 / ESP32 ➔ Website
// Target Location: RUET Campus, Rajshahi (24.3636, 88.6283)
// =========================================================================
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <SoftwareSerial.h>
SoftwareSerial nanoSerial(D2, D3); // RX = D2, TX = D3 (from Arduino Nano)
#elif defined(ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <HardwareSerial.h>
HardwareSerial nanoSerial(2); // ESP32: RX = GPIO16, TX = GPIO17
#endif
#include <ArduinoJson.h>
const char* ssid = "iPhone (2)";
const char* password = "ratul12345";
const char* firestoreBase = "https://firestore.googleapis.com/v1/projects/ighs-9a0f1/databases/(default)/documents/";
int currentDistance = 100;
String currentStatus = "SAFE";
bool dangerReported = false;
void setup() {
Serial.begin(9600);
#if defined(ESP8266)
nanoSerial.begin(9600);
#elif defined(ESP32)
nanoSerial.begin(9600, SERIAL_8N1, 16, 17);
#endif
pinMode(2, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println("\n[ONLINE] Connected to Hotspot!");
sendTelemetryToWebsite(24.3636, 88.6283, currentDistance, "SAFE");
}
void loop() {
if (nanoSerial.available() > 0) {
String data = nanoSerial.readStringUntil('\n');
data.trim();
if (data.startsWith("D:")) {
int comma = data.indexOf(',');
if (comma > 0) {
currentDistance = data.substring(2, comma).toInt();
currentStatus = data.substring(comma + 1);
currentStatus.trim();
if ((currentStatus.equalsIgnoreCase("DANGER") || currentDistance < 20) && !dangerReported) {
triggerDangerAlert(24.3636, 88.6283, currentDistance);
dangerReported = true;
}
if (currentStatus.equalsIgnoreCase("SAFE") && currentDistance >= 25 && dangerReported) {
dangerReported = false;
sendTelemetryToWebsite(24.3636, 88.6283, currentDistance, "SAFE");
}
}
}
}
static unsigned long lastSend = 0;
if (millis() - lastSend >= 3000) {
lastSend = millis();
sendTelemetryToWebsite(24.3636, 88.6283, currentDistance, dangerReported ? "DANGER" : "SAFE");
}
}
void sendTelemetryToWebsite(double lat, double lng, int distance, String status) {
if (WiFi.status() != WL_CONNECTED) return;
WiFiClientSecure client; client.setInsecure();
HTTPClient http;
http.begin(client, String(firestoreBase) + "vehicles/esp32-ruet-01");
http.addHeader("Content-Type", "application/json");
String json = "{\"fields\":{\"vehicleName\":{\"stringValue\":\"Test Vehicle\"},\"lat\":{\"doubleValue\":" + String(lat, 5) + "},\"lng\":{\"doubleValue\":" + String(lng, 5) + "},\"distance\":{\"integerValue\":" + String(distance) + "},\"status\":{\"stringValue\":\"" + status + "\"}}}";
http.PATCH(json);
http.end();
}
void triggerDangerAlert(double lat, double lng, int distance) {
if (WiFi.status() != WL_CONNECTED) return;
WiFiClientSecure client; client.setInsecure();
HTTPClient http;
http.begin(client, String(firestoreBase) + "accidents");
http.addHeader("Content-Type", "application/json");
String json = "{\"fields\":{\"vehicleId\":{\"stringValue\":\"esp32-ruet-01\"},\"vehicleName\":{\"stringValue\":\"Test Vehicle\"},\"lat\":{\"doubleValue\":" + String(lat, 5) + "},\"lng\":{\"doubleValue\":" + String(lng, 5) + "},\"distance\":{\"integerValue\":" + String(distance) + "},\"severity\":{\"stringValue\":\"CRITICAL (Obstacle < " + String(distance) + " cm)\"},\"smsSent\":{\"booleanValue\":true}}}";
http.POST(json);
http.end();
sendTelemetryToWebsite(lat, lng, distance, "DANGER");
}