Files
DriverVault/Car Agent Device/LILYGO TTGO T-SIM7600/1.cpp
T
tajniak81andClaude Opus 4.8 318e9c1670 Add Car Agent Device firmware (LILYGO TTGO T-SIM7600, ESP32/SIM7600)
ESP32 + SIM7600 cellular firmware for the in-car agent device: WiFi/AP
provisioning with a web admin page, GPRS/LTE connectivity, and IMEI-based
identification. The hardcoded default WiFi password has been replaced with a
YOUR-WIFI-PASSWORD placeholder so no real credential enters git history.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 21:07:45 +02:00

408 lines
14 KiB
C++

/*
FILE: ATdebug_WiFi_AP_WebAdmin.ino
AUTHOR: Kaibin (Modified by OpenAI)
PURPOSE: Test functionality with WiFi, AP, and Web Admin Panel
*/
#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1
// See all AT commands, if wanted
#define DUMP_AT_COMMANDS
// set GSM PIN, if any
#define GSM_PIN ""
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 30 /* Time ESP32 will go to sleep (in seconds) */
#define UART_BAUD 115200
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_PWRKEY 4
#define MODEM_DTR 32
#define MODEM_RI 33
#define MODEM_FLIGHT 25
#define MODEM_STATUS 34
#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS 13
#define LED_PIN 12
// Your GPRS credentials, if any
const char apn[] = "YOUR-APN"; //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";
// Default WiFi credentials
const char* defaultSSID = "AP_1_IOT"; // Replace with your WiFi SSID
const char* defaultPassword = "YOUR-WIFI-PASSWORD"; // Replace with your WiFi password
// Default Access Point credentials
const char* defaultAPSSID = "ESP32-AP";
const char* defaultAPPassword = "12345678";
#include <TinyGsmClient.h>
#include <TinyGPS++.h>
#include <SPI.h>
#include <SD.h>
#include <FS.h>
#include <FFat.h>
#include <Ticker.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPWebFileManager.h>
#include <ESPAsyncWebServer.h>
#include <Preferences.h>
#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
AsyncWebServer server(80);
ESPWebFileManager fileManager;
Preferences preferences;
TinyGPSPlus gps;
int counter, lastIndex, numberOfPieces = 24;
String pieces[24], input;
bool reply = false;
void modem_on() {
/*
The indicator light of the board can be controlled
*/
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
/*
MODEM_PWRKEY IO:4 The power-on signal of the modulator must be given to it,
otherwise the modulator will not reply when the command is sent
*/
pinMode(MODEM_PWRKEY, OUTPUT);
digitalWrite(MODEM_PWRKEY, HIGH);
delay(300); //Need delay
digitalWrite(MODEM_PWRKEY, LOW);
/*
MODEM_FLIGHT IO:25 Modulator flight mode control,
need to enable modulator, this pin must be set to high
*/
pinMode(MODEM_FLIGHT, OUTPUT);
digitalWrite(MODEM_FLIGHT, HIGH);
int i = 40;
Serial.print(F("\r\n# Startup #\r\n"));
Serial.print(F("# Sending \"AT\" to Modem. Waiting for Response\r\n# "));
while (i) {
SerialAT.println(F("AT"));
// Show the User: we are doing something.
Serial.print(F("."));
delay(500);
// Did the Modem send something?
if (SerialAT.available()) {
String r = SerialAT.readString();
Serial.print("\r\n# Response:\r\n" + r);
if ( r.indexOf("OK") >= 0 ) {
reply = true;
break;
} else {
Serial.print(F("\r\n# "));
}
}
// Did the User try to send something? Maybe he did not receive the first messages yet. Inform the User what is happening
if (Serial.available() && !reply) {
Serial.read();
Serial.print(F("\r\n# Modem is not yet online."));
Serial.print(F("\r\n# Sending \"AT\" to Modem. Waiting for Response\r\n# "));
}
// On the 5th try: Inform the User what is happening
if (i == 35) {
Serial.print(F("\r\n# Modem did not yet answer. Probably Power loss?\r\n"));
Serial.print(F("# Sending \"AT\" to Modem. Waiting for Response\r\n# "));
}
delay(500);
i--;
}
Serial.println(F("#\r\n"));
}
void connectToWiFi() {
// Read saved WiFi credentials
preferences.begin("wifi", true);
String ssid = preferences.getString("ssid", "");
String password = preferences.getString("password", "");
preferences.end();
if (ssid != "") {
// Connect to WiFi with saved credentials
WiFi.begin(ssid.c_str(), password.c_str());
Serial.printf("Connecting to WiFi SSID: %s\n", ssid.c_str());
} else {
// Use default credentials if no saved credentials are found
WiFi.begin(defaultSSID, defaultPassword);
Serial.println("No saved WiFi credentials found, using default credentials");
Serial.printf("Connecting to WiFi SSID: %s\n", defaultSSID);
}
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nFailed to connect to WiFi");
}
}
void setupAccessPoint() {
// Read saved AP credentials
preferences.begin("ap", true);
String apSSID = preferences.getString("apSSID", defaultAPSSID);
String apPassword = preferences.getString("apPassword", defaultAPPassword);
preferences.end();
Serial.println("Setting up Access Point...");
bool result = WiFi.softAP(apSSID.c_str(), apPassword.c_str());
if (result) {
Serial.println("Access Point started successfully!");
Serial.print("AP IP Address: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("Failed to start Access Point.");
}
}
void setupWebServer() {
// Serve HTML file
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
// Read saved WiFi credentials
preferences.begin("wifi", true);
String ssid = preferences.getString("ssid", defaultSSID);
String password = preferences.getString("password", defaultPassword);
preferences.end();
// Read saved AP credentials
preferences.begin("ap", true);
String apSSID = preferences.getString("apSSID", defaultAPSSID);
String apPassword = preferences.getString("apPassword", defaultAPPassword);
preferences.end();
// Get IP addresses
String wifiIP = WiFi.isConnected() ? WiFi.localIP().toString() : "Not connected";
String apIP = WiFi.softAPIP().toString();
// Get MAC addresses
String wifiMAC = WiFi.macAddress();
String apMAC = WiFi.softAPmacAddress();
// Get GPS data
String latitude = gps.location.isValid() ? String(gps.location.lat(), 6) : "N/A";
String longitude = gps.location.isValid() ? String(gps.location.lng(), 6) : "N/A";
String altitude = gps.altitude.isValid() ? String(gps.altitude.meters()) : "N/A";
String speed = gps.speed.isValid() ? String(gps.speed.kmph()) : "N/A";
String satellites = gps.satellites.isValid() ? String(gps.satellites.value()) : "N/A";
// Read the HTML file from the filesystem
File file = FFat.open("/web_admin.html", "r");
if (!file) {
request->send(500, "text/plain", "Failed to open web_admin.html");
return;
}
// Read the file content into a string
String html = file.readString();
file.close();
// Replace placeholders with actual values
html.replace("{{WiFiSSID}}", ssid);
html.replace("{{WiFiPassword}}", password);
html.replace("{{WiFiIP}}", wifiIP);
html.replace("{{WiFiMAC}}", wifiMAC);
html.replace("{{APSSID}}", apSSID);
html.replace("{{APPassword}}", apPassword);
html.replace("{{APIP}}", apIP);
html.replace("{{APMAC}}", apMAC);
html.replace("{{Latitude}}", latitude);
html.replace("{{Longitude}}", longitude);
html.replace("{{Altitude}}", altitude);
html.replace("{{Speed}}", speed);
html.replace("{{Satellites}}", satellites);
// Send the modified HTML content
request->send(200, "text/html", html);
});
// Handle WiFi configuration form submission
server.on("/setWiFi", HTTP_POST, [](AsyncWebServerRequest *request) {
String ssid = request->getParam("ssid", true)->value();
String password = request->getParam("password", true)->value();
// Save the credentials to a secure location
preferences.begin("wifi", false);
preferences.putString("ssid", ssid);
preferences.putString("password", password);
preferences.end();
Serial.printf("New WiFi SSID: %s, Password: %s\n", ssid.c_str(), password.c_str());
// Restart WiFi with new credentials
WiFi.disconnect();
WiFi.begin(ssid.c_str(), password.c_str());
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nFailed to connect to WiFi");
}
// Send a response with a popup alert
String response = "<html><body><script>alert('WiFi credentials updated successfully.'); window.location.href = '/';</script></body></html>";
request->send(200, "text/html", response);
});
// Handle Access Point configuration form submission
server.on("/setAP", HTTP_POST, [](AsyncWebServerRequest *request) {
String apSSID = request->getParam("apSSID", true)->value();
String apPassword = request->getParam("apPassword", true)->value();
// Save the credentials to a secure location
preferences.begin("ap", false);
preferences.putString("apSSID", apSSID);
preferences.putString("apPassword", apPassword);
preferences.end();
Serial.printf("New AP SSID: %s, Password: %s\n", apSSID.c_str(), apPassword.c_str());
// Restart Access Point with new credentials
WiFi.softAPdisconnect(true);
bool result = WiFi.softAP(apSSID.c_str(), apPassword.c_str());
if (result) {
Serial.println("Access Point started successfully!");
Serial.print("AP IP Address: ");
Serial.println(WiFi.softAPIP());
} else {
Serial.println("Failed to start Access Point.");
}
// Send a response with a popup alert
String response = "<html><body><script>alert('Access Point credentials updated successfully.'); window.location.href = '/';</script></body></html>";
request->send(200, "text/html", response);
});
// Start server
server.begin();
Serial.println("Web server started.");
}
void fatfs () {
if (!FFat.begin(true)) { // Format on fail: 'true' forces formatting if mounting fails
Serial.println("Failed to initialize eMMC storage (FFat). Trying to format...");
if (!FFat.format()) {
Serial.println("FFat format failed. Check partition table and storage.");
return; // Halt setup if FFat fails
}
if (!FFat.begin()) {
Serial.println("Failed to mount FFat after formatting.");
return;
}
}
Serial.println("FFat initialized successfully.");
}
void setup() {
Serial.begin(115200); // Set console baud rate
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(100);
fatfs ();
modem_on();
connectToWiFi();
setupAccessPoint();
setupWebServer();
if (reply) {
Serial.println(F("***********************************************************"));
Serial.println(F(" You can now send AT commands"));
Serial.println(F(" Enter \"AT\" (without quotes), and you should see \"OK\""));
Serial.println(F(" If it doesn't work, select \"Both NL & CR\" in Serial Monitor"));
Serial.println(F(" DISCLAIMER: Entering AT commands without knowing what they do"));
Serial.println(F(" can have undesired consiquinces..."));
Serial.println(F("***********************************************************\n"));
// Uncomment to read received SMS
//SerialAT.println("AT+CMGL=\"ALL\"");
} else {
Serial.println(F("***********************************************************"));
Serial.println(F(" Failed to connect to the modem! Check the baud and try again."));
Serial.println(F("***********************************************************\n"));
}
// Initialize FATFS (Change to other types as needed, Valid types: FS_SD_CARD, FS_SPIFFS, FS_LITTLEFS, FS_FATFS )
if (!fileManager.initFileSystem(ESPWebFileManager::FS_FATFS, true)) {
DEBUG_SERIAL.println("Failed to initialize file system");
}
fileManager.setServer(&server);
server.begin();
DEBUG_SERIAL.println("Web server started");
}
void loop() {
if (SerialAT.available()) {
Serial.write(SerialAT.read());
}
if (Serial.available()) {
SerialAT.write(Serial.read());
}
// Read data from the GPS module
while (SerialAT.available() > 0) {
gps.encode(SerialAT.read());
}
// Print GPS data to the serial monitor
if (gps.location.isUpdated()) {
Serial.print("Latitude: ");
Serial.println(gps.location.lat(), 6);
Serial.print("Longitude: ");
Serial.println(gps.location.lng(), 6);
Serial.print("Altitude: ");
Serial.println(gps.altitude.meters());
Serial.print("Speed: ");
Serial.println(gps.speed.kmph());
Serial.print("Satellites: ");
Serial.println(gps.satellites.value());
}
delay(1000);
}