anw07
(AnuwaT)
1
สวัสดีครับ ตอนนี้ผมใช้ ESP32 อ่านค่าจาก GPS NEO-M8N แสดงผลบนหน้าจอ 16*2 อยู่ครับ
ค่าที่่แสดงตอนนี้ มีค่า LAT LONG และ COG ผมต้องการให้ค่า 3 อย่างนี้
ส่งไปยังอุปกรณ์ HMI ผ่าน MODBUS RS485 ผมต้องเขียนโค้ดยังไงครับ ต้องให้ตัว ESP เป็น Slave ใช่ไหมครับ
พึ่งได้ทดลองทำ Modbus ครับ ตอนนี้พึ่งซื้อ MAX485 TO TTL ที่มี RE DE กับ ตัวที่ไม่มี RE DE ครับ
ขอบคุณครับ
Remy_Martin
(Permpol Thanapunnamas)
2
สวัสดีครับ! จากที่คุณต้องการให้ ESP32 อ่านค่าจาก GPS NEO-M8N แล้วส่งค่า LAT, LONG, และ COG ไปยังอุปกรณ์ HMI ผ่าน Modbus RS485 คุณต้องกำหนดให้ ESP32 เป็น Slave ในเครือข่าย Modbus RTU ครับ
อุปกรณ์ที่ต้องใช้:
- ESP32
- โมดูล GPS NEO-M8N
- โมดูล MAX485 to TTL (ตัวที่มี RE/DE จะควบคุมการส่ง/รับได้ง่ายกว่า)
- อุปกรณ์ HMI ที่รองรับ Modbus RTU (RS485)
การตั้งค่าอุปกรณ์:
- ESP32 ต้องทำหน้าที่เป็น Modbus Slave
- HMI ทำหน้าที่เป็น Modbus Master
- ใช้ RS485 เป็นโปรโตคอลสื่อสาร
- ใช้ไลบรารี ModbusRTU ของ ESP32
วิธีเชื่อมต่อ MAX485 กับ ESP32
MAX485 |
ESP32 |
VCC |
3.3V หรือ 5V |
GND |
GND |
RO (Receive Out) |
RX (GPIO16 ตัวอย่าง) |
DI (Data In) |
TX (GPIO17 ตัวอย่าง) |
RE (Receive Enable) |
GPIO4 (ตั้งค่า LOW เพื่อรับข้อมูล) |
DE (Driver Enable) |
GPIO4 (ตั้งค่า HIGH เพื่อส่งข้อมูล) |
A |
ไปที่ A ของ HMI |
B |
ไปที่ B ของ HMI |
หมายเหตุ:
- ขา RE/DE ต้องเชื่อมด้วยกันและใช้ GPIO ควบคุมการรับ/ส่ง
- ปกติ RE = LOW (รับข้อมูล) และ DE = HIGH (ส่งข้อมูล)
ตัวอย่างโค้ด ESP32 เป็น Modbus RTU Slave (ใช้ไลบรารี ModbusRTU.h
)
ติดตั้งไลบรารี ModbusRTU
ก่อน โดยไปที่ Arduino IDE → Library Manager และค้นหา ModbusRTU
จาก emelianov
แล้วติดตั้ง
#include <ModbusRTU.h>
#include <HardwareSerial.h>
// กำหนดขา RX, TX และขาที่ใช้ควบคุม MAX485
#define RXD2 16
#define TXD2 17
#define RE_DE 4 // ใช้ขานี้ควบคุมโหมดส่ง/รับ
HardwareSerial rs485(2); // ใช้ Serial2
ModbusRTU modbus; // สร้างออบเจกต์ Modbus
// ตัวแปรเก็บค่าจาก GPS
float latitude = 13.7563; // ตัวอย่างค่าจาก GPS
float longitude = 100.5018;
float cog = 123.45; // ค่า COG
// ฟังก์ชันให้ Master อ่านค่าจาก Register
bool ReadRegisters(Modbus::ResultCode event, uint16_t transactionId, void* data) {
return true; // ใช้เมื่อ Master ต้องการอ่านค่า ไม่มีการเปลี่ยนแปลงค่า
}
void setup() {
Serial.begin(115200); // เปิด Serial Monitor
rs485.begin(9600, SERIAL_8N1, RXD2, TXD2); // เริ่มต้น RS485
modbus.begin(&rs485, RE_DE); // เริ่ม Modbus RTU และใช้ RE_DE ควบคุมโหมด
modbus.slave(1); // กำหนด ESP32 เป็น Slave ID = 1
// กำหนดค่าลงใน Holding Registers (เริ่มจากที่อยู่ 0)
modbus.addHreg(0, (uint16_t)(latitude * 10000)); // คูณ 10000 เพื่อแปลง float เป็น int
modbus.addHreg(1, (uint16_t)(longitude * 10000));
modbus.addHreg(2, (uint16_t)(cog * 10)); // คูณ 10 เพื่อเพิ่มความละเอียดของ COG
}
void loop() {
modbus.task(); // ดำเนินการ Modbus
// อัปเดตค่าจาก GPS (จำลองค่าตัวอย่าง)
modbus.Hreg(0, (uint16_t)(latitude * 10000));
modbus.Hreg(1, (uint16_t)(longitude * 10000));
modbus.Hreg(2, (uint16_t)(cog * 10));
delay(1000);
}
วิธีตั้งค่า HMI ให้รับค่าจาก ESP32
ใน HMI คุณต้อง:
- ตั้งค่า Communication Protocol → Modbus RTU
- ตั้งค่า Baudrate → 9600
- ตั้งค่า Device ID → 1
- ตั้งค่า Register Address ตามที่กำหนดใน ESP32:
- ที่อยู่ 0 → Latitude (เก็บเป็น Int คูณ 10000)
- ที่อยู่ 1 → Longitude (เก็บเป็น Int คูณ 10000)
- ที่อยู่ 2 → COG (เก็บเป็น Int คูณ 10)
- ใช้ Data Type เป็น Unsigned INT16
อธิบายโค้ด:
- ใช้ไลบรารี
ModbusRTU
ควบคุม Modbus RTU
- ใช้
modbus.slave(1);
เพื่อกำหนดให้ ESP32 เป็น Slave ID = 1
- ใช้
modbus.addHreg()
เพื่อกำหนด Holding Register สำหรับค่า GPS
- ใช้
modbus.Hreg()
อัปเดตค่าที่อ่านได้จาก GPS ไปยัง Modbus Register
- ใช้ GPIO4 (
RE_DE
) ควบคุมทิศทางของ MAX485 (ส่งหรือรับ)
Remy_Martin
(Permpol Thanapunnamas)
3
ถ่ายรูปการต่อมาดูด้วยยิ่งดีครับ