เนื้อหาในบทความ
ภาพรวมโปรเจกต์
ในยุคที่เทคโนโลยี IoT ก้าวหน้าไปอย่างรวดเร็ว การติดตามและเฝ้าระวังพาหนะ (Vehicle Tracking) กลายเป็นเรื่องสำคัญทั้งสำหรับบุคคลและธุรกิจ โปรเจกต์นี้จะแนะนำวิธีสร้างระบบติดตามรถยนต์แบบเรียลไทม์ด้วย ESP32 ที่เชื่อมต่อกับเครือข่าย 4G LTE พร้อมระบบ GPS และส่งข้อมูลผ่าน MQTT Protocol ไปยัง Web Dashboard ที่คุณสามารถเฝ้าระวังได้ทันที
ทำไมต้องใช้ 4G LTE?
- ความครอบคลุม: เชื่อมต่อได้ทุกที่ที่มีสัญญาณ 4G
- ความเร็วสูง: ส่งข้อมูลได้รวดเร็วและเสถียร
- ติดตามได้ต่อเนื่อง: ไม่ต้องกังวลเรื่อง WiFi range
- เหมาะกับรถยนต์: สามารถติดตามได้แม้ขณะขับขี่
ฟีเจอร์หลักของระบบ
- ติดตามตำแหน่ง GPS แบบ Real-time
- แสดงความเร็วและทิศทางการเคลื่อนที่
- บันทึกประวัติการเดินทาง (Trip History)
- แจ้งเตือนเมื่อรถออกนอกพื้นที่กำหนด (Geofencing)
- ดูข้อมูลได้ผ่าน Web Dashboard ทุกที่
อุปกรณ์ที่ต้องใช้
Hardware Components
| อุปกรณ์ | รายละเอียด | ราคาโดยประมาณ |
|---|---|---|
| ESP32 Development Board | ESP32-WROOM หรือ ESP32-S3 | ~฿200 |
| 4G LTE Module | SIM7600 หรือ A7670E | ~฿800-1,200 |
| GPS Module | NEO-6M หรือ NEO-8M | ~฿200-300 |
| SIM Card (4G) | เฉพาะข้อมูล (Data Only) | ~฿100-300/เดือน |
| Power Supply | 5V 2A Adapter + รางถ่าน | ~฿150 |
| Jumper Wires & Breadboard | Male-to-Female wires | ~฿50 |
💡 เคล็ดลับ: เลือก 4G Module ที่รองรับความถี่เดียวกับที่ใช้ในประเทศไทย (เช่น AIS, DTAC, True) เพื่อให้แน่ใจว่าจะเชื่อมต่อได้
การเชื่อมต่อวงจร
การเชื่อมต่อ GPS Module (NEO-6M)
| VCC | → | ESP32 3.3V |
| GND | → | ESP32 GND |
| TX | → | ESP32 GPIO 16 (RX2) |
| RX | → | ESP32 GPIO 17 (TX2) |
การเชื่อมต่อ 4G LTE Module (SIM7600)
| VCC | → | ESP32 5V (หรือแหล่งจ่ายภายนอก) |
| GND | → | ESP32 GND |
| TXD | → | ESP32 GPIO 4 (RX1) |
| RXD | → | ESP32 GPIO 2 (TX1) |
⚠️ คำเตือน: 4G Module ใช้กระแสไฟสูง (ถึง 2A เมื่อส่งข้อมูล) แนะนำให้ใช้แหล่งจ่ายไฟภายนอกแยกจาก ESP32 เพื่อป้องกันการรีเซ็ต
การติดตั้งซอฟต์แวร์
Arduino IDE Libraries
ติดตั้ง Libraries ที่จำเป็ผ่าน Arduino IDE Library Manager:
- TinyGSM - สำหรับ 4G Module
- PubSubClient - สำหรับ MQTT
- TinyGPSPlus - สำหรับ GPS
- ArduinoJson - สำหรับ JSON Format
MQTT Broker
คุณสามารถใช้ MQTT Broker ฟรี เช่น:
- HiveMQ Cloud:
broker.hivemq.com(Port 1883) - EMQX Cloud:
broker.emqx.io(Port 1883) - Local Server: Mosquitto บน Raspberry Pi/PC
โค้ด ESP32
นี่คือโค้ดที่สมบูรณ์สำหรับ ESP32 Vehicle Tracker:
/*
* ESP32 4G LTE GPS Vehicle Tracker
* ส่งข้อมูล GPS ผ่าน MQTT ไปยัง Dashboard
*
* Hardware: ESP32 + SIM7600 (4G) + NEO-6M (GPS)
* Author: CynoIoT
* Date: March 2026
*/
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <TinyGPS++.h>
// ==================== การตั้งค่า PIN ====================
// 4G Module (SIM7600)
#define SerialAT Serial1
#define PIN_DTR 25
#define PIN_TX 4
#define PIN_RX 2
// GPS Module (NEO-6M)
#define SerialGPS Serial2
#define GPS_RX 16
#define GPS_TX 17
// LED Status
#define LED_PIN 2
// ==================== การตั้งค่า MQTT ====================
const char* broker = "broker.hivemq.com"; // MQTT Broker
const int mqtt_port = 1883;
const char* topic = "cynoiot/vehicle/tracker"; // Topic หลัก
// Device ID (เปลี่ยนเป็น ID ของคุณ)
const char* device_id = "VEHICLE_001";
// ==================== การตั้งค่า APN ====================
// แก้ไขตาม SIM Card ที่ใช้
const char* apn = "internet"; // AIS: internet, DTAC: www.dtac.co.th
const char* user = "";
const char* pass = "";
// ==================== Objects ====================
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqtt(client);
TinyGPSPlus gps;
// ==================== ตัวแปร ====================
unsigned long lastMsg = 0;
const long interval = 5000; // ส่งข้อมูลทุก 5 วินาที
void setup() {
Serial.begin(115200);
Serial.println(F("\n🚗 ESP32 Vehicle Tracker Starting..."));
// ตั้งค่า LED
pinMode(LED_PIN, OUTPUT);
blinkLED(3);
// เริ่มต้น GPS
SerialGPS.begin(9600, SERIAL_8N1, GPS_RX, GPS_TX);
Serial.println(F("✅ GPS Module initialized"));
// เริ่มต้น 4G Module
SerialAT.begin(115200, SERIAL_8N1, PIN_RX, PIN_TX);
Serial.println(F("📡 Initializing 4G Module..."));
delay(3000);
// รีเซ็ต Module
if (!modem.restart()) {
Serial.println(F("❌ Failed to restart modem"));
return;
}
// เชื่อมต่อเครือข่าย
Serial.println(F("🔌 Waiting for network..."));
if (!modem.waitForNetwork()) {
Serial.println(F("❌ Network failed"));
return;
}
if (!modem.gprsConnect(apn, user, pass)) {
Serial.println(F("❌ GPRS failed"));
return;
}
Serial.println(F("✅ Connected to 4G Network!"));
Serial.print(F("📶 Signal: "));
Serial.println(modem.getSignalQuality());
// ตั้งค่า MQTT
mqtt.setServer(broker, mqtt_port);
}
void loop() {
// อ่านข้อมูล GPS
while (SerialGPS.available() > 0) {
gps.encode(SerialGPS.read());
}
// ส่งข้อมูลทุก interval
unsigned long now = millis();
if (now - lastMsg >= interval) {
lastMsg = now;
if (gps.location.isValid()) {
sendData();
} else {
Serial.println(F("⏳ Waiting for GPS fix..."));
}
}
// รักษาการเชื่อมต่อ MQTT
if (!mqtt.connected()) {
reconnectMQTT();
}
mqtt.loop();
}
void sendData() {
// สร้าง JSON Payload
String payload = "{";
payload += "\"device_id\":\"" + String(device_id) + "\",";
payload += "\"latitude\":" + String(gps.location.lat(), 6) + ",";
payload += "\"longitude\":" + String(gps.location.lng(), 6) + ",";
payload += "\"altitude\":" + String(gps.altitude.meters()) + ",";
payload += "\"speed\":" + String(gps.speed.kmph()) + ",";
payload += "\"heading\":" + String(gps.course.deg()) + ",";
payload += "\"satellites\":" + String(gps.satellites.value()) + ",";
payload += "\"timestamp\":" + String(now);
payload += "}";
// ส่งผ่าน MQTT
Serial.print(F("📤 Sending: "));
Serial.println(payload);
if (mqtt.publish(topic, payload.c_str())) {
Serial.println(F("✅ Data sent successfully"));
blinkLED(1);
} else {
Serial.println(F("❌ Failed to send data"));
}
}
void reconnectMQTT() {
while (!mqtt.connected()) {
Serial.print(F("🔗 Connecting to MQTT..."));
// สร้าง Client ID แบบสุ่ม
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (mqtt.connect(clientId.c_str())) {
Serial.println(F("✅ Connected"));
mqtt.publish(topic, "connected"); // แจ้งสถานะ
} else {
Serial.print(F("❌ Failed, rc="));
Serial.print(mqtt.state());
Serial.println(F(" retrying in 5 seconds"));
delay(5000);
}
}
}
void blinkLED(int times) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
delay(100);
}
}📝 คำอธิบายโค้ด
- • อ่านข้อมูล GPS ทุก 5 วินาที
- • ส่งข้อมูลเป็น JSON Format ผ่าน MQTT
- • เชื่อมต่อ MQTT ใหม่อัตโนมัติถ้าหลุด
- • LED กระพริบเพื่อแสดงสถานะ
สร้าง Web Dashboard
สร้าง HTML Dashboard แบบง่ายเพื่อดูตำแหน่งรถ:
<!DOCTYPE html>
<html>
<head>
<title>Vehicle Tracker Dashboard</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"></script>
<style>
#map { height: 600px; }
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
.info { background: white; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
</style>
</head>
<body>
<h1>🚗 Vehicle Tracker</h1>
<div class="info">
<strong>สถานะ:</strong> <span id="status">Connecting...</span><br>
<strong>Latitude:</strong> <span id="lat">-</span><br>
<strong>Longitude:</strong> <span id="lng">-</span><br>
<strong>Speed:</strong> <span id="speed">-</span> km/h
</div>
<div id="map"></div>
<script>
// เริ่มต้นแผนที่
var map = L.map('map').setView([13.7563, 100.5018], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
}).addTo(map);
// Marker สำหรับรถ
var marker = L.marker([13.7563, 100.5018]).addTo(map);
// เชื่อมต่อ MQTT
var client = new Paho.MQTT.Client("broker.hivemq.com", 8000, "webclient");
client.onConnectionLost = function(response) {
document.getElementById('status').innerText = "Disconnected";
};
client.onMessageArrived = function(message) {
var data = JSON.parse(message.payloadString);
// อัปเดตข้อมูล
document.getElementById('status').innerText = "Connected";
document.getElementById('lat').innerText = data.latitude;
document.getElementById('lng').innerText = data.longitude;
document.getElementById('speed').innerText = data.speed;
// ย้าย Marker ไปตำแหน่งใหม่
var newLatLng = new L.LatLng(data.latitude, data.longitude);
marker.setLatLng(newLatLng);
map.setView(newLatLng, 16);
};
// เชื่อมต่อ
client.connect({
onSuccess: function() {
document.getElementById('status').innerText = "Connected";
client.subscribe("cynoiot/vehicle/tracker");
}
});
</script>
</body>
</html> บันทึกไฟล์นี้เป็น index.html แล้วเปิดใน Browser
การทดสอบระบบ
ขั้นตอนการทดสอบ
- ต่อวงจรตาม Diagram ข้างต้น
- อัปโหลดโค้ดไปยัง ESP32
- เปิด Serial Monitor (Baud 115200)
- รอสัญญาณ GPS (นำ GPS ไปโล่งทางบก)
- ตรวจสอบว่าเชื่อมต่อ 4G ได้
- เปิด Dashboard ใน Browser
- ขับรถไปรอบๆ แล้วดูว่าตำแหน่งเคลื่อนที่หรือไม่
✅ สถานะที่ควรเห็นใน Serial Monitor
✅ GPS Module initialized
📡 Initializing 4G Module...
✅ Connected to 4G Network!
📶 Signal: 25
🔗 Connecting to MQTT...✅ Connected
📤 Sending: {"latitude":13.756300,"longitude":100.501800,...}
✅ Data sent successfully
แก้ปัญหาที่พบบ่อย
ปัญหา: GPS ไม่ได้สัญญาณ
อาการ: แสดง "Waiting for GPS fix..." ตลอดเวลา
สาเหตุ: อยู่ในอาคาร หรือไม่มีท้องฟ้าเปิด
วิธีแก้: นำอุปกรณ์ไปโล่งทางบก รอ 5-10 นาทีเพื่อให้ GPS Lock
ปัญหา: 4G เชื่อมต่อไม่ได้
อาการ: แสดง "GPRS failed"
สาเหตุ: APN ผิด, SIM ไม่มีข้อมูล, สัญญาณอ่อน
วิธีแก้: ตรวจสอบ APN, เติมเงิน Internet Package, ย้ายไปที่สัญญาณแรง
ปัญหา: ESP32 รีเซ็ตเอง
อาการ: ทำงานสักพักแล้วรีเซ็ต
สาเหตุ: ไฟไม่เพียงพอเมื่อ 4G ส่งข้อมูล
วิธีแก้: ใช้แหล่งจ่ายไฟ 5V 2A แยก หรือใช้แบตเตอรี่ขนาดใหญ่
ปัญหา: Dashboard ไม่แสดงข้อมูล
อาการ: แผนที่เปิดได้แต่ไม่เห็นตำแหน่ง
สาเหตุ: MQTT Topic ไม่ตรงกัน
วิธีแก้: ตรวจสอบว่า Topic ในโค้ด ESP32 ตรงกับ Dashboard
สรุป
ในบทความนี้ เราได้เรียนรู้วิธีสร้างระบบติดตามพาหนะด้วย ESP32, 4G LTE, GPS และ MQTT ตั้งแต่การเลือกอุปกรณ์ การต่อวงจร การเขียนโค้ด ไปจนถึงการสร้าง Dashboard สำหรับเฝ้าระวังแบบเรียลไทม์
สิ่งที่ได้เรียนรู้
- การเชื่อมต่อ 4G LTE Module กับ ESP32
- การอ่านข้อมูล GPS ด้วย TinyGPS++
- การส่งข้อมูลผ่าน MQTT Protocol
- การสร้าง Web Dashboard แบบ Real-time
ไอเดียต่อยอด
- เพิ่มระบบ Geofencing (แจ้งเตือนเมื่อรถออกนอกพื้นที่)
- บันทึกประวัติการเดินทางลง Database
- เพิ่มเซ็นเซอร์วัดอุณหภูมิห้องเครื่อง
- แจ้งเตือนผ่าน Line หรือ Telegram เมื่อเกิดเหตุ
- สร้างระบบแสดงผลแบบ Mobile App
🎯 ถัดไป: ลองปรับปรุงโค้ดให้ใช้งานร่วมกับ CynoIoT Platform เพื่อเก็บข้อมูลและแสดงผลได้สวยงามยิ่งขึ้น!