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

Sensor Ketinggian Air Dengan Tekanan

 

Sensor ketinggian air (water level sensor) yang menggunakan tekanan air untuk mengetahui ketinggian air. Prinsip fisika yang dipakai adalah hidrostatika, di mana tekanan dalam suatu wadah berisi cairan sebanding dengan kedalaman dan massa jenis cairan tersebut.

 

 

Sensor tekanan air
Sensor tekanan air

Berikut ini contoh pinout sensor ketinggian air yang sudah dilengkapi dengan antar muka RS-485

 

Sensor ini sudah dilengkapi dengan kompensasi tekanan udara. Caranya adalah dengan adanya selang udara kecil di dalam kabel penghubung ke sensor tersebut. Dengan demikian maka dapat diketahui perbedaan tekanan di dalam air dan tekanan udara di luar tangki. Dari perbedaan tekanan tersebut dapat dihitung ketinggian air pada tangki atau wadah air.

 

Mengirim Data Sensor Jarak Jauh

Pada sistem mikroprosesor seperti Arduino, kadang-kadang diperlukan sensor analog yang jaraknya cukup jauh dari perangkat pengendali, sehingga perlu teknik khusus untuk pengiriman data dari sensor analog tersebut. Pada jarak yang jauh, sinyal analog mudah sekali mengalami gangguan, terutama masuknya sinyal lain (noise) dan redaman dari kabel, sehingga sinyal dari sensor yang sampai ke mikroprosesor sudah tidak sama dengan sinyal aslinya.

Untuk mengatasi permasalahan tersebut, ada beberapa solusi sebagai berikut:

  • Menggunakan pengiriman data digital, jadi sinyal dari sensor yang analog, diubah dulu menjadi digital dengan sebuah mikrokontroler, kemudian baru data digital ini dikirim dengan kabel. Supaya lebih kuat, kabel yang panjang dapat menggunakan protokol RS-232 atau RS-485. Sinyal TTL biasa (5 volt maupun 3.3 volt) rentan jika dipakai untuk mengirim data digital jarak jauh. Protokol serial RS-232 dapat dipakai mengirim data sampai puluhan meter, sedangkan protokol serial RS-485 dapat dipakai mengirim data sampai ratusan meter.
  • Menggunakan Current Loop 4-20 mA
  • Menggunakan VCO (Voltage Controlled Oscillator). Prinsipnya adalah tegangan diubah ke frekuensi, baru sinyal frekuensi ini yang dikirim.
  • Menggunakan radio, seperti Wifi, LoraWAN dan sebagainya

Berikut ini contoh sistem pengiriman data sensor jarak jauh menggunakan pengiriman data digital dengan komunikasi serial dan sinyal RS485:

Pengiriman data sensor jarak jauh dengan RS-485

Cara kerja adalah sebagai berikut:

  • Sensor menghasilkan tegangan analog.
  • Tegangan analog diubah menjadi digital dengan menggunakan ADC pada mikrokontroler Arduino 1. Perlu diperhatikan juga apakah sinyal dari sensor analog sudah cukup besar untuk dapat dibaca oleh ADC. Jika kurang, maka perlu diperkuat dulu dengan amplifier. Jika frekuensi agak tinggi, mungkin diperlukan juga rangkaian sample & hold sebelum masuk ke ADC.
  • Data digital dikirim dengan menggunakan protokol serial melalui port serial pada Arduino 1. Level tegangannya adalah TTL sesuai dengan tegangan kerja Arduino 1. Sinyal ini sudah digital, namun belum cukup kuat untuk dikirim pada jarak jauh.
  • Sinyal serial TTL diubah menjadi RS-485 dengan menggunakan IC konverter TTL – RS-485
  • Sinyal dalam format RS485 dikirimkan dengan kabel, yang dapat dibuat agak panjang. Supaya sinyalnya bagus, mesti menggunakan kabel twisted pair, misalnya kabel yang digunakan pada kabel ethernet LAN (Local Area Network). Pada kabel LAN ada 4 pasang kabel yang sudah dipuntir (twisted). Pada pengiriman data 1 arah, cukup digunakan 1 pasang saja.
  • Sinyal RS-485 diubah menjadi TTL dengan IC konverter RS-485 ke TTL.
  • Sinyal serial dalam level TTL dimasukkan ke dalam port serial pada Arduino 2. Sinyal ini dapat langsung dibaca oleh software di Arduino 2.

Contoh hardware dan software untuk menyambungkan RS-485 antara lain dapat dibaca di https://arduino-info.wikispaces.com/SoftwareSerialRS485Example.

Rangkaian percobaan Arduino dan RS485

Rangkaian percobaan Arduino dan RS485

Pada contoh rangkaian di atas, kabel RS485 yang dipakai pendek saja , hanya beberapa cm. Menurut spesifikasinya , RS485 dapat dipakai sampai beberapa ratus meter, tergantung kecepatan data yang dipakai. Makin cepat datanya, makin pendek jaraknya.

Referensi

Tips Pengiriman Data Serial

Pengiriman data secara serial itu susah-susah gampang, terutama kalau pengiriman data tersebut mesti melalui daerah yang banyak noisenya.

Sumber permasalahan pengiriman data serial antara lain:

  • Noise yang masuk ke kabel data secara kapasitif maupun induktif
  • Perbedaan tegangan ground antara pengirim dan penerima, menyebabkan terjadinya ground loop. Perbedaan ini dapat terjadi karena memang sudah bawaan, karena ada perangkat tertentu, karena petir, dan juga karena ada induksi medan magnet ke dalam kabel komunikasi.

Berikut ini mekanisme ground loop. Medan magnet B (hijau) dari luar sistem menyebabkan arus noise I (merah). Arus noise ini akan menjadi sinyal tambahan bagi C2, sehingga sinyal yang diterima C2 tidak sama dengan sinyal dari C1, melainkan sudah ditambah dengan noise

 

Ground loop

Ground loop terjadi karena ada beda potensial antara ground di pengirim dan ground di penerima.

Masalah ground loop
Masalah ground loop

 

Berikut beberapa solusi:

#1 Menggunakan kabel fiber optik, karena kabel fiber optik tidak terganggu oleh radiasi gelombang radio, dan juga tidak terpengaruh perbedaan tegangan ground antara pengirim maupun penerima

#2 Menggunakan kabel coaxial, karena kabel koaksial kebal terhadap gangguan radiasi. Dengan catatan kabel yang digunakan berkualitas baik, seperti misalnya menggunakan kabel koaksial yang menggunakan shield berupa tabung logam. Contoh di artikel https://elektrologi.iptek.web.id/perbandingan-kabel-50-ohm-coaxial-di-pasaran/

#3 Menggunakan pengiriman sinyal secara differensial, misalnya dengan protokol RS-485 dengan kabel twisted pair . Ada yang tanpa pelindung unshielded twisted pair (UTP), dan ada juga yang lebih baik shielded twister pair (STP). Kabel jenis ini umum dipakai untuk kabel ethernet, sehingga mudah dicari di pasaran. Sinyal pada kabel ini dikirim secara differensial, salah satu protokol yang umum dipakai adalah RS-422/RS-485, yang komponennya mudah dicari di pasaran.

#4 Menggunakan kabel triaxial, kabel ini mirip dengan coaxial, hanya saja menggunakan 2 lapis shield. Sulit dicari di pasaran Indonesia karena jarang yang pakai dan cukup mahal, serta konektornya khusus.

#5 Menggunakan filter analog untuk menghilangkan sinyal noise yang tidak diinginkan. Namun teknik ini hanya dapat dilakukan jika frekuensi noise berbeda dengan frekuensi sinyal kerja yang diinginkan.

Solusi ground loop dengan coaxial dan optocouplerMisalkan kecepatan transfer 2 Mbps dengan baseband tanpa modulasi, maka menurut teorema Nyquist minimal bandwidth yang diperlukan adalah 4 MHz, jadi sinyal dari 0Hz sampai 4Hz harus dapat lewat, jadi filter harus di atas 4 MHz. Masalah timbul jika ternyata noise yang terjadi ada di frekuensi 0 ~ 4 MHz. Hal ini dapat dicek menggunakan osiloskop, dengan mengamati bentuk sinyal yang timbul, apakah masih dalam rentang 0 ~ 4 MHz.

Filter low pass 4.5 MHz
Filter low pass 4.5 MHz

Jika frekuensi noise ada di 0 ~ 4 MHz, maka filter low pass 4.5 MHz tidak bermanfaat mengurangi noise.

 

#6 Menggunakan optocoupler untuk memotong ground loop. Sinyal dari optocoupler dikirim dengan kabel coaxial supaya tidak terganggu noise. Pada contoh di bawah ini, optocoupler dipasang di sisi pengirim, namun dapat juga dipasang di sisi penerima.

 

Solusi ground loop dengan coaxial dan optocoupler

Berikut ini teknik yang lebih kompleks, gabungan RS-485 , shielded cable dan optocoupler, seperti dijelaskan di dokumen The RS-485 Design Guide

Isolation transceiver
Isolation transceiver

#7 Memperkuat tegangan sinyal yang dikirim, dengan harapan memperbaiki Signal to Noise ratio (S/N)

#8 Memperkuat arus sinyal yang dikirim dengan mengurangi impedansi output supaya noise tidak mudah masuk.

#9 Menggunakan terminasi untuk menghindari pemantulan sinyal. Terminasi terutama diperlukan jika panjang kabel sudah lebih atau mendekati panjang gelombang pada frekuensi kerja sinyal.

#10 Menggunakan kabel yang redaman lebih kecil, sehingga sinyal yang sampai di penerima masih cukup kuat. Cuma kabel yang redaman kecil ini secara fisik lebih besar dan lebih mahal harganya.

Solusi di atas adalah solusi-solusi dari layer hardware, selain itu dapat juga dilakukan pengolahan sinyal digital.

#10 Menggunakan teknik error detection, seperti parity bit, checksum, cyclic redundancy check (CRC). Teknik ini dapat mendeteksi kesalahan, namun tidak dapat memperbaiki sinyal yang rusak.

#11 Menggunakan teknik error correction, seperti Reed Solomon, Viterbi

Referensi