#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <AsyncTCP.h>
#include <ArduinoOTA.h>
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
AsyncWebServer server(80);
// EC200U communication
#define SerialMon Serial // Debug output to Serial Monitor
#define SerialAT Serial2 // Communication with EC200U
// Define RX2 and TX2 pins for Serial2
#define RX2 16 // Replace with your RX2 pin number
#define TX2 17 // Replace with your TX2 pin number
// Wi-Fi credentials
const char *ssid = ""; // Enter your Wi-Fi SSID
const char *password = ""; // Enter your Wi-Fi password
// HTTP server URL for posting data
const char *serverUrl = "https://roboclubserver.iitd.ac.in/bustracker/update-location/"; // Replace with your server URL
unsigned long lastPublishTime = 0; // Tracks the last publish time
const unsigned long publishInterval = 10000; // Publish interval (10 seconds)
WiFiClientSecure client;
void setup() {
// Initialize Serial for debugging
SerialMon.begin(115200);
// Initialize Wi-Fi
SerialMon.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
SerialMon.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// OTA Setup
ArduinoOTA
.onStart([]() {
String type = (ArduinoOTA.getCommand() == U_FLASH) ? "sketch" : "filesystem";
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
SerialMon.println("Ready");
SerialMon.print("IP address: ");
SerialMon.println(WiFi.localIP());
WebSerial.begin(&server);
WebSerial.msgCallback(recvMsg);
server.begin();
// Initialize Serial2 for EC200U communication
SerialAT.begin(115200, SERIAL_8N1, RX2, TX2);
delay(1000);
SerialMon.println("Stopping any existing GPS session...");
sendATCommand("AT+QGPSEND", "OK", 2000);
// Start GPS session
SerialMon.println("Starting GPS...");
sendATCommand("AT+QGPS=1", "OK", 2000);
delay(10000);
}
void loop() {
// Handle OTA updates
ArduinoOTA.handle();
// Publish GPS data to the server
unsigned long currentMillis = millis();
if (currentMillis - lastPublishTime >= publishInterval) {
publishData();
lastPublishTime = currentMillis;
}
}
void publishData() {
String gpsData = getGPSData();
String latitude = "N/A";
String longitude = "N/A";
if (gpsData.length() > 0) {
int comma1 = gpsData.indexOf(",");
int comma2 = gpsData.indexOf(",", comma1 + 1);
int comma3 = gpsData.indexOf(",", comma2 + 1);
if (comma1 != -1 && comma2 != -1) {
latitude = gpsData.substring(comma1 + 1, comma2);
longitude = gpsData.substring(comma2 + 1, comma3);
}
}
// Construct the HTTP payload
String payload = String("{") +
"\"device_name\":\"Bus755\"," +
"\"latitude\":" + String(latitude, 6) + "," +
"\"longitude\":" + String(longitude, 6) +
"}";
// Send the data to the HTTP server
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// Generate a unique parameter (e.g., timestamp or random value) to bypass caching
String uniqueUrl = String(serverUrl) + "?timestamp=" + String(millis());
// Use WiFiClientSecure for insecure SSL connections
http.begin(client, uniqueUrl); // Pass the insecure WiFiClientSecure client
// Add root certificate for SSL verification
http.setInsecure(); // Use this for insecure SSL
http.addHeader("Content-Type", "application/json");
http.addHeader("Api-Key", "b52e4585927fbb463db365dae83ac70f17122519");
// Add custom headers to prevent caching
http.addHeader("Cache-Control", "no-cache");
http.addHeader("Pragma", "no-cache");
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
SerialMon.println("Data sent successfully: " + payload);
SerialMon.println("Server response: " + http.getString());
} else {
SerialMon.println("Error in sending data: " + String(httpResponseCode));
}
http.end();
} else {
SerialMon.println("Wi-Fi not connected, unable to send data.");
}
}
void sendATCommand(String command, String response, int timeout) {
String receivedData;
SerialAT.println(command); // Send the AT command
long int time = millis();
while ((time + timeout) > millis()) {
while (SerialAT.available()) {
char c = SerialAT.read(); // Read the response from the module
receivedData += c;
}
}
if (receivedData.indexOf(response) != -1) {
SerialMon.println("Received: " + receivedData); // If the response is as expected
WebSerial.println("Received: " + receivedData);
} else {
SerialMon.println("Error");
WebSerial.println("Error");
}
}
void recvMsg(uint8_t *data, size_t len) {
WebSerial.println("Received Data...");
String d = "";
for (int i = 0; i < len; i++) {
d += char(data[i]);
}
WebSerial.println(d);
}
String getGPSData() {
SerialAT.println("AT+QGPSLOC=2\r\n");
String gpsResponse;
long int time = millis();
while ((time + 2000) > millis()) {
while (SerialAT.available()) {
char c = SerialAT.read();
gpsResponse += c;
}
}
int startIndex = gpsResponse.indexOf("+QGPSLOC: ");
if (startIndex != -1) {
int endIndex = gpsResponse.indexOf("\r\n", startIndex);
if (endIndex != -1) {
String location = gpsResponse.substring(startIndex + 10, endIndex);
SerialMon.println("GPS Data: " + location);
WebSerial.println("GPS Data: " + location);
return location;
}
}
SerialMon.println("Invalid GPS response: " + gpsResponse);
WebSerial.println("Invalid GPS response: " + gpsResponse);
return "";
}