Complete Architecture Documentation for Lemion Engineering Team | System Version 4.8.5
The Lemion Weather Station is an end-to-end IoT monitoring solution designed to collect ambient environmental parameters (Temperature, Humidity, Barometric Pressure) using an ESP32 hardware microcontroller and BMP280 sensor module, transmit measurements securely over HTTPS REST APIs to a MySQL database, and present real-time/historical telemetry via a futuristic Sci-Fi Web Dashboard featuring interactive 3D Obsidian node graphs and browser-based Web Serial firmware flashing.
| Layer | Technology Stack | Description |
|---|---|---|
| HARDWARE | ESP32 WROOM-32, BMP280, I2C LCD 1602, Rotary Selector Switch | Collects temperature & pressure; outputs locally to I2C LCD; sends JSON payload to HTTPS server every 60s. |
| BACKEND API | PHP 8.3 (PDO, Asia/Bangkok GMT+7), MySQL InnoDB | Handles secure data ingestion, querying latest status, and date-filtered historical telemetry retrieval. |
| FRONTEND HUD | HTML5, Vanilla CSS, High-Contrast ApexCharts, Three.js, ESP Web Tools | Futuristic Sci-Fi HUD, ApexCharts line graph, Date Picker query, Three.js 3D Obsidian Node Network, Web Serial Flasher. |
/home/u639131817/domains/108ido.com/public_html/lemion
/home/u639131817/domains/108ido.com/public_html/lemion/
├── index.html # Main Web HUD Dashboard (HTML5)
├── style.css # Sci-Fi HUD Design Tokens & 3D Styling (CSS3)
├── app.js # Application Engine, High-Contrast ApexCharts & Three.js (JS ES6)
├── manifest.json # ESP Web Tools Web Flasher Manifest
├── firmware.bin # Compiled ESP32 Firmware Binary (For Web Flashing)
├── project_handover.html # Full Technical Handover Documentation
└── api/
├── config.php # Global Database & API Auth Credentials (Asia/Bangkok GMT+7)
├── db.php # PDO MySQL Connection Singleton (SET time_zone = '+07:00')
├── upload.php # Ingestion Endpoint for ESP32 POST Data (GMT+7 Timestamps)
├── latest.php # Endpoint returning most recent telemetry reading
├── history.php # Endpoint for range queries & specific date filtering
├── seed.php # Database Seeder (Generates realistic history)
└── setup.php # Database Schema Initializer (Creates table)
hosting_deployStaticWebsite.108ido.com port 21 using Hostinger cPanel FTP credentials and upload all files into public_html/lemion/.index.html, increment the version query parameter (e.g. app.js?v=20260725_v8) to ensure clients bypass local caching.| Parameter | Configuration Value |
|---|---|
| Database Host | localhost |
| Database Name | u639131817_108ido |
| Database Username | u639131817_108ido |
| Database Password | Sukpitak@153 |
| API Secret Key | lemion-secret-api-key-2026 |
| Timezone Configuration | Asia/Bangkok (GMT+7) |
lemion_weather
CREATE TABLE IF NOT EXISTS `lemion_weather` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`temperature` FLOAT NOT NULL,
`humidity` FLOAT NOT NULL,
`pressure` FLOAT NOT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
POST /api/upload.phpCalled by ESP32 microcontroller every 60 seconds to upload sensor readings.
Request Headers: Content-Type: application/json
// Request Body JSON Payload
{
"api_key": "lemion-secret-api-key-2026",
"temperature": 28.5,
"humidity": 65.0,
"pressure": 1009.4
}
GET /api/latest.php
// Response JSON (Times returned in Asia/Bangkok GMT+7)
{
"status": "success",
"data": {
"id": 2639,
"temperature": 27.2,
"humidity": 69.0,
"pressure": 1013.4,
"created_at": "2026-07-25 18:42:07"
}
}
GET /api/history.phprange=7d|30d|all - Returns telemetry records within the requested relative range.date=YYYY-MM-DD - Returns all 24-hour records for a specific date along with daily summary averages.The microcontroller source file is located at c:\esp32\esp32_weather.ino (or c:\esp32\esp32_weather\esp32_weather.ino).
| Device | VCC | GND | SDA / Signal | SCL |
|---|---|---|---|---|
| ESP32 Board | 3.3V / 5V | GND | GPIO 21 | GPIO 22 |
| BMP280 Sensor | 3.3V | GND | GPIO 21 | GPIO 22 |
| I2C LCD 1602 | 5V | GND | GPIO 21 | GPIO 22 |
| Rotary Selector Switch Pin A | 3.3V (Pullup) | GND | GPIO 13 (INPUT_PULLUP) | - |
| Rotary Selector Switch Pin B | 3.3V (Pullup) | GND | GPIO 14 (INPUT_PULLUP) | - |
.ino into firmware.bin
# Using arduino-cli (Command Line):
arduino-cli compile --fqbn esp32:esp32:esp32 "c:\esp32\esp32_weather" --output-dir "c:\esp32\build"
# Using Arduino IDE 2.x:
1. Open esp32_weather.ino in Arduino IDE.
2. Select Board: Tools -> Board -> ESP32 Arduino -> ESP32 Dev Module.
3. Click Sketch -> Export Compiled Binary (Ctrl + Alt + S).
The dashboard incorporates ESP Web Tools to allow technicians to flash updated ESP32 firmware directly over a USB cable inside Google Chrome or Microsoft Edge without taking the board out of its enclosure or installing local compilers.
WEB FIRMWARE FLASHER.CONNECT & FLASH FIRMWARE in the popup modal.CP2102 on COM5) and click Connect -> Install.Can the ESP32 microcontroller send data to the backend database every 5 seconds? Technically, the ESP32 code can be set to sendInterval = 5000;. However, doing HTTPS POST requests directly to MySQL every 5 seconds on shared web hosting (Hostinger) introduces severe operational limitations and architectural bottlenecks.
| Interval Rate | Readings / Min | Readings / Day | Readings / Month | Estimated Annual Storage |
|---|---|---|---|---|
| 60 Seconds (Recommended) | 1 row | 1,440 rows | 43,200 rows | ~20 MB / year |
| 30 Seconds | 2 rows | 2,880 rows | 86,400 rows | ~40 MB / year |
| 5 Seconds (High Frequency) | 12 rows | 17,280 rows | 518,400 rows | ~300 MB - 500 MB / year |
HTTP 403 Forbidden or 429 Too Many Requests.To enable the front panel Rotary Selector Switch on the enclosure box to switch LCD 1602 display screens (e.g. turning Left displays Temp/Humidity, turning Right displays Pressure/Wi-Fi Status), follow this implementation specification:
GND.GPIO 13.GPIO 14.
// Define Pin Assignment for Rotary Switch
#define SWITCH_PIN_LEFT 13
#define SWITCH_PIN_RIGHT 14
void setup() {
pinMode(SWITCH_PIN_LEFT, INPUT_PULLUP);
pinMode(SWITCH_PIN_RIGHT, INPUT_PULLUP);
}
void updateLCDDisplay() {
bool isLeftPressed = (digitalRead(SWITCH_PIN_LEFT) == LOW);
bool isRightPressed = (digitalRead(SWITCH_PIN_RIGHT) == LOW);
lcd.clear();
if (isLeftPressed) {
// Mode 1: Display Temperature & Humidity
lcd.setCursor(0, 0);
lcd.print("TEMP: "); lcd.print(tempC, 1); lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("HUM : "); lcd.print(humidity, 1); lcd.print(" %");
} else if (isRightPressed) {
// Mode 2: Display Barometric Pressure & System Status
lcd.setCursor(0, 0);
lcd.print("PRES: "); lcd.print(pressure, 1); lcd.print("hPa");
lcd.setCursor(0, 1);
lcd.print("SYS : ONLINE/WiFi");
} else {
// Default Mode: Auto-cycle or Summary
lcd.setCursor(0, 0);
lcd.print("LEMION SYS READY");
lcd.setCursor(0, 1);
lcd.print("SELECT MODE... ");
}
}
To eliminate the need to plug in a USB cable when updating ESP32 firmware in the future, integrate ArduinoOTA or AsyncElegantOTA into the C++ codebase:
#include <WiFi.h>
#include <ArduinoOTA.h>
void setupOTA() {
ArduinoOTA.setHostname("lemion-weather-station");
ArduinoOTA.setPassword("lemion-ota-pass-2026");
ArduinoOTA.onStart([]() { Serial.println("Start OTA Updating..."); });
ArduinoOTA.onEnd([]() { Serial.println("\nEnd OTA Update."); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle(); // Must be called frequently in loop()
// ... rest of sensor reading and sending code ...
}
Tools -> Port -> Select lemion-weather-station at 192.168.x.x (Network Port) -> Click Upload. The firmware updates wirelessly over Wi-Fi in seconds!
date_default_timezone_set('Asia/Bangkok') and MySQL SET time_zone = '+07:00' to resolve the 7-hour offset issue.#ffaa00, #00ffaa, #00e5ff) and enhanced dropShadow glow.arduino-cli upload.lemion_project_handover_full.zip ready for Lemion team transfer.