Site icon Elektrologi

Perekam Modbus RTU Dengan ESP32

Pada pengembangan sistem dengan komunikasi Modbus RTU dengan RS485, kadang-kadang kita perlu memonitor pertukaran data di kabel RS-485 untuk memantau apakah komunikasi data berjalan dengan benar. Pada artikel ini diuraikan secara ringkas pembuatan perangkat untuk memantau dan merekam trafik data di komunikasi RS-485 tersebut.

 

Berikut ini skema rangkaiannya secara sederhana

Rangkaian ESP32 dengan RS485

Penjelasan cara kerja rangkaian

Komponen utama sistem adalah sebagai berikut

Pin pada MAX485

Berikut ini foto rangkaian dengan breadboard

Alat untuk merekam sinyal Modbus RTU di RS485 dengan mikrokontroler ESP32

Rangkaian ESP32 , MAX485 dan level converter di breadboard

 

#esp32-freertos-rs485-analyzer
/**
   analisis data RS485
*/
#define LED_BUILTIN 22

#define RXD1 17
#define TXD1 5
#define RXD2 18
#define TXD2 23


void setup() {
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);

  Serial.println("Serial Txd 0 is on pin: " + String(TX));
  Serial.println("Serial Rxd 0 is on pin: " + String(RX));

  Serial.println("Serial Txd 1 is on pin: " + String(TXD1));
  Serial.println("Serial Rxd 1 is on pin: " + String(RXD1));

  Serial.println("Serial Txd 2 is on pin: " + String(TXD2));
  Serial.println("Serial Rxd 2 is on pin: " + String(RXD2));

  pinMode(LED_BUILTIN, OUTPUT);


  if (1)
    xTaskCreate(
      TaskBlinker, /* Task function. */
      "TaskBlinker", /* String with name of task. */
      1000, /* Stack size in bytes. */
      NULL, /* Parameter passed as input of the task */
      1, /* Priority of the task. */
      NULL); /* Task handle. */
  xTaskCreate(
    TaskSerial1, /* Task function. */
    "TaskSerial1", /* String with name of task. */
    2000, /* Stack size in bytes. */
    NULL, /* Parameter passed as input of the task */
    1, /* Priority of the task. */
    NULL); /* Task handle. */
}


// the loop function runs over and over again forever

void loop() {
  delay(10000);
}


void TaskBlinker(void *parameter) {
  int counter = 0;
  TickType_t xLastWakeTime;
  const TickType_t xPeriod = 500      ;
  xLastWakeTime = xTaskGetTickCount();
  //  dht.begin(); // aktifkan sensor DHT22
  while (1) {
    digitalWrite(LED_BUILTIN, HIGH);
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
    digitalWrite(LED_BUILTIN, LOW);
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
//    Serial.print("Counter:");
//    Serial.println(counter);
    counter++;
  }
}

#define BUFFER_MAX 200

void TaskSerial1(void *parameter) {
  int interframe_timer_max = 0;
  int interframe_timer = 0; // untuk mengukur waktu antar frame
  char buffer_data[BUFFER_MAX];
  int buffer_idx = 0;
  TickType_t xLastWakeTime;
  const TickType_t xPeriod = 1      ;
  xLastWakeTime = xTaskGetTickCount();
  while (1) {
    int incomingByte;
    if (Serial1.available() > 0) {
      interframe_timer = 0;
    } else {
      interframe_timer++;
    }
    while (Serial1.available() > 0) {
      // read the incoming byte:
      incomingByte = Serial1.read();
      buffer_data[buffer_idx] = incomingByte ;
      buffer_idx++;
      if (buffer_idx > BUFFER_MAX) {
        buffer_idx = BUFFER_MAX;  // buffer overflow protection
      }
    }
    //Serial.print(incomingByte, HEX);
    //Serial.print(" ");
    if (interframe_timer > interframe_timer_max) {
      interframe_timer_max = interframe_timer;
      Serial.print("interframe_max ");
      Serial.println(interframe_timer_max);
    }
    if (interframe_timer > 6 && buffer_idx > 0) {
      // cetak semua data di buffer
      for (int i = 0; i < buffer_idx; i++) {
        Serial.print(buffer_data[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
      buffer_idx = 0; // empty buffer
    }
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
  }
}

Referensi

Exit mobile version