ESP32 รับค่า XY-02 modbus 2 ตัวผ่าน MAX485 ตัวเดียว

รบกวนสอบถามครับ คือผมพยายามจะใช้ ESP32 รับค่า XY-02 modbus 2 ตัวผ่าน MAX485 ตัวเดียว โดยผมเอา sensor ต่อขนานกันเข้าตัว MAX485 ปัญหาที่พบคือค่ามันอ่านได้บ้างไม่ได้สลับกัน บางครั้งอ่านตัวที่ 1 ได้ บางครั้งอ่านตัวที่ 2 ได้ แต่ส่วนใหญ่จะอ่านไม่ค่อยได้เลย ไม่แน่ใจว่ามันเป็นข้อจำกัดส่วนไหนไหมครับ หรือท่านใดมี idea รบกวนแชร์หน่อยครับ

#include <SoftwareSerial.h>
#include <ModbusMaster.h>

SoftwareSerial mySerial(19, 21); // RX, TX

#define MAX485_DE      22
#define MAX485_RE_NEG  23

ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup()
{
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
  Serial.println("start init serial 0");
  Serial.begin(9600);
  
  while (!Serial) {
    Serial.println("loop for init serial 0"); 
  }
  Serial.println("start init software serial");
  mySerial.begin(9600);
  while (!mySerial) {
    Serial.println("loop for init software serial");
  }

  node.begin(1, mySerial);  
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

}

void loop()
{
  uint8_t result;
  uint16_t data[2];

  Serial.println("get data 1");
  result = node.readInputRegisters(1, 2);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("Temp: ");
    Serial.println(node.getResponseBuffer(0)/10.0f);
    Serial.print("Humi: ");
    Serial.println(node.getResponseBuffer(1)/10.0f);
    Serial.println();
  
  }

  node.begin(3, mySerial);  
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
   
  Serial.println("get data 2");
  result = node.readInputRegisters(1, 2);
  if (result == node.ku8MBSuccess)
  {
    Serial.print("Temp: ");
    Serial.println(node.getResponseBuffer(0)/10.0f);
    Serial.print("Humi: ");
    Serial.println(node.getResponseBuffer(1)/10.0f);
    Serial.println();
  }
  delay(1000);
}

ภาพต่อลักษณะประมาณนี้ครับ แต่เปลี่ยนเข้า MAX485 ไป ESP32

1 Likes

อาจจะเกิดจากหลายสาเหตุครับ

1.การตั้งค่า ID ของเซ็นเซอร์:

  • ตรวจสอบว่า ID ของเซ็นเซอร์ทั้งสองไม่ซ้ำกัน ตัวอย่างเช่น:
    • เซ็นเซอร์ตัวแรกใช้ ID = 1
    • เซ็นเซอร์ตัวที่สองใช้ ID = 3
node.begin(1, mySerial); // อ่านจากเซ็นเซอร์ ID 1
node.begin(3, mySerial); // อ่านจากเซ็นเซอร์ ID 3

หาก ID ซ้ำกันจะทำให้เกิดการชนกันของข้อมูล

2. ปัญหาจาก RS-485 Bus Termination:

  • การต่อ termination resistor (120 Ω) ที่ปลายทั้งสองของสายบัส RS-485 จะช่วยลดสัญญาณสะท้อนและปรับปรุงเสถียรภาพของการสื่อสาร
  • แนะนำให้ใส่ ตัวต้านทาน 120 Ω ระหว่างขา A และ B ของบัส RS-485

3. ปัญหาจาก Pull-up และ Pull-down Resistors:

  • RS-485 ต้องการ pull-up และ pull-down resistors (ประมาณ 10 kΩ) เพื่อป้องกันสัญญาณรบกวน
  • ต่อ pull-up ที่ขา A และ pull-down ที่ขา B

ลองดูโค้ตนี้

#include <SoftwareSerial.h>
#include <ModbusMaster.h>

SoftwareSerial mySerial(19, 21); // RX, TX

#define MAX485_DE      22
#define MAX485_RE_NEG  23

ModbusMaster node;

void preTransmission() {
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
  delay(5); // เพิ่ม delay หลังจากเปิดใช้งานโหมดส่ง
}

void postTransmission() {
  delay(5); // เพิ่ม delay ก่อนกลับไปโหมดรับ
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup() {
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
  
  Serial.begin(9600);
  mySerial.begin(4800); // ลด baud rate เพื่อเพิ่มความเสถียร

  node.begin(1, mySerial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;

  // อ่านจากเซ็นเซอร์ ID 1
  node.begin(1, mySerial);
  result = node.readInputRegisters(1, 2);
  if (result == node.ku8MBSuccess) {
    Serial.print("Sensor 1 Temp: ");
    Serial.println(node.getResponseBuffer(0) / 10.0f);
    Serial.print("Sensor 1 Humi: ");
    Serial.println(node.getResponseBuffer(1) / 10.0f);
  }
  delay(50); // เพิ่ม delay ระหว่างการอ่าน

  // อ่านจากเซ็นเซอร์ ID 3
  node.begin(3, mySerial);
  result = node.readInputRegisters(1, 2);
  if (result == node.ku8MBSuccess) {
    Serial.print("Sensor 2 Temp: ");
    Serial.println(node.getResponseBuffer(0) / 10.0f);
    Serial.print("Sensor 2 Humi: ");
    Serial.println(node.getResponseBuffer(1) / 10.0f);
  }
  delay(1000);
}