Perekam Modbus RTU Dengan ESP32

Rangkaian ESP32 , MAX485 dan level converter di breadboard

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
Rangkaian ESP32 dengan RS485

Penjelasan cara kerja rangkaian

Komponen utama sistem adalah sebagai berikut

  • MAX485 berfungsi untuk mengubah level tegangan RS-485 menjadi TTL 5 volt.
  • Level converter berfungsi mengubah tegangan TTL 5 volt dari MAX485 menjadi TTL dengan tegangan 3 volt.
  • Mikrokontroler ESP32 berfungsi merekam data serial dan mengirimnya menggunakan kabel USB ke komputer.
  • Komputer untuk merekam data serial dari ESP32
  • Power supply 5 volt untuk MAX485
Pin pada MAX485
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
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

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.