Sunday, 22 December 2013

Modbus TCP VB6 Winsock

Visual Basic 6 (VB6 atau VB Classic) memang sudah tua. Microsoft sudah mengeluarkan software programming yang jauh lebih canggih. Terakhir adalah Microsoft Visual Studio 2013. VB6 sudah tidak di-support lagi oleh mereka. Tapi ternyata masih banyak yang menggunakan VB6, baik untuk sekedar belajar pemrograman, atau untuk bekerja membuat aplikasi.
Visual Basic 6 (VB6 or VB classic) is old, Microsoft has release more advance programming software, the last is Microsoft Visual Studio 2013. Microsoft do not support VB6 now. But, there are a lot of people whom still using VB6 for programming, for learn or work.


Berikut ini adalah tutorial bagaimana membuat aplikasi Modbus TCP client dengan VB6.
The following tutorial describe hoe to make VB6 application communicate with Modbus TCP. 

1. Buka VB6.
open VB6.
 
2. Buat project baru, Standard EXE.
Create new project, Standard EXE
 

3. Buatlah beberapa objek berikut pada Form:
Add objects on form like this:
 

- txtIP : textbox untuk input IP address dari device Modbus TCP. "127.0.0.1" adalah IP komputer lokal, kita akan pakai ini karena kita akan pakai Modbus Simulator.
txtIP: textbox for input IP address of device Modbus TCP. "127.0.0.1" is local computer, we will use this because we will use Modbus Simulator.  

- tombol: cmdConnect, cmdDisconnect, cmdRead, cmdWrite
buttons: cmdConnect, cmdDisconnect, cmdRead, and cmdWrite 
- txtStartReg : textbox untuk input alamat pertama dari register Modbus yang akan dibaca/ditulis.
txtStartReg: textbox for input the first register address of Modbus whic will be read/write. 
 - txtLengthReg : textbox untuk input jumlah register yang akan dibaca/ditulis. Pada tutorial ini kami batasi 20, sesuai dengan jumlah textbox untuk datanya, silahkan diedit sendiri apabila kurang.
txtLengthReg: textbox for input the length of registers which will be read/write. In this tutorial the length is limited until 20 as much as textbox for register data. You can change this if need more.  
- txtReg() : textbox yang berindeks, dari 0 sampai 19, berfungsi untuk menampilkan nilai dari register.
txtReg(): indexed textbox, from 0 to 19, for displaying value of registers.  
- komponen Winsock1 : komponen untuk koneksi ke device Modbus TCP. Isi properties RemotePort dengan nilai 502. Jika komponen Winsock pada toolbox tidak ada, klik kanan pada area toolbox lalu klik Components. Carilah komponen Microsoft Winsock Control.
Winsock component: for connect to Modbus TCP device. Set RemotePort property with 502. If the component is not on toolbox, right-click on toolbox area then click Components. Find Microsoft Winsock Control. 
- TimerTO : timer untuk Time Out pembacaan atau penulisan ke Modbus, pada contoh ini kita set properties Interval -nya dengan 1000 (1 detik).
TimerTO: timer for reading or writing Time Out, in this sample we set Interval property to 1000 (1 second). 
- lblStatus : label untuk status dari proses.
lblStatus: label for displaying state of process.

4. Tulis script berikut pada jendela Code:
Write the following script to Code window:

'/// begining of script ///

Dim MbusQuery(11) As Byte
Dim MbusByteArray(255) As Byte
Dim MbusResponse As String
Dim ModbusTimeOut As Integer
Dim MbusRead As Boolean
Dim MbusWrite As Boolean
Dim ModbusWait As Boolean

Private Sub cmdConnect_Click()
Me.MousePointer = vbHourglass
Winsock1.RemoteHost = txtIP.Text
Winsock1.Connect

Dim StartTime
StartTime = Timer

Do While ((Timer < StartTime + 2) And (Winsock1.State <> 7))
    DoEvents
Loop
If (Winsock1.State = 7) Then
   lblStatus.Caption = "Connected"
   lblStatus.BackColor = vbGreen
   cmdConnect.Enabled = False
   cmdDisconnect.Enabled = True
Else
   lblStatus.Caption = "Can't connect to " + txtIP.Text
   lblStatus.BackColor = vbYellow
End If
Me.MousePointer = vbDefault
End Sub

Private Sub cmdDisconnect_Click()
Me.MousePointer = vbHourglass
If (Winsock1.State <> sckClosed) Then
    Winsock1.Close
End If

Dim StartTime
StartTime = Timer

Do While ((Timer < StartTime + 2) And (Winsock1.State <> sckClosed))
    DoEvents
Loop
If (Winsock1.State = sckClosed) Then
    lblStatus.Caption = "Disconnected"
    lblStatus.BackColor = vbRed
    cmdConnect.Enabled = True
   cmdDisconnect.Enabled = False
Else
    lblStatus.Caption = "Error disconnect!"
    lblStatus.BackColor = vbYellow
End If
Me.MousePointer = vbDefault
End Sub

Private Sub cmdRead_Click()
'cek if length is more than 20
If Val(txtLengthReg.Text) > 20 Then
    MsgBox "Can not read more than 20 registers!"
    Exit Sub
End If

Dim StartLow As Byte
Dim StartHigh As Byte
Dim LengthLow As Byte
Dim LengthHigh As Byte
If (Winsock1.State = 7) Then
    StartLow = Val(txtStartReg.Text) Mod 256
    StartHigh = Val(txtStartReg.Text) \ 256
    LengthLow = Val(txtLengthReg.Text) Mod 256
    LengthHigh = Val(txtLengthReg.Text) \ 256
    MbusQuery(0) = 0
    MbusQuery(1) = 0
    MbusQuery(2) = 0
    MbusQuery(3) = 0
    MbusQuery(4) = 0
    MbusQuery(5) = 6
    MbusQuery(6) = 1
    MbusQuery(7) = 3
    MbusQuery(8) = StartHigh
    MbusQuery(9) = StartLow
    MbusQuery(10) = LengthHigh
    MbusQuery(11) = LengthLow
    MbusRead = True
    MbusWrite = False
    Winsock1.SendData MbusQuery
    ModbusWait = True
    ModbusTimeOut = 0
    TimerTO.Enabled = True
Else
    MsgBox ("Device not connected via TCP/IP!")
End If
End Sub

Private Sub cmdWrite_Click()
Dim MbusWriteCommand As String
Dim StartLow As Byte
Dim StartHigh As Byte
Dim ByteLow As Byte
Dim ByteHigh As Byte
Dim i As Integer
If (Winsock1.State = 7) Then
    StartLow = Val(txtStartReg.Text) Mod 256
    StartHigh = Val(txtStartReg.Text) \ 256
    LengthLow = Val(txtLengthReg.Text) Mod 256
    LengthHigh = Val(txtLengthReg.Text) \ 256
       
    MbusWriteQuery = Chr(0) + Chr(0) + Chr(0) + Chr(0) + Chr(0) + Chr(7 + 2 * Val(txtLengthReg.Text)) + Chr(1) + Chr(16) + Chr(StartHigh) + Chr(StartLow) + Chr(0) + Chr(Val(txtLengthReg.Text)) + Chr(2 * Val(txtLengthReg.Text))
    For i = 0 To Val(txtLengthReg.Text) - 1
        ByteLow = Val(txtReg(i).Text) Mod 256
        ByteHigh = Val(txtReg(i).Text) \ 256
        MbusWriteQuery = MbusWriteQuery + Chr(ByteHigh) + Chr(ByteLow)
    Next i
    MbusRead = False
    MbusWrite = True
    Winsock1.SendData MbusWriteQuery
    ModbusWait = True
    ModbusTimeOut = 0
    TimerTO.Enabled = True
Else
    MsgBox ("Device not connected via TCP/IP!")
End If
End Sub

Private Sub TimerTO_Timer()
ModbusTimeOut = ModbusTimeOut + 1
If ModbusTimeOut > 2 Then
    ModbusWait = False
    ModbusTimeOut = 0
    lblStatus.Caption = "Modbus Time Out!"
    lblStatus.BackColor = vbYellow
    TimerTO.Enabled = False
End If
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bData As Byte
Dim j As Byte
For i = 1 To bytesTotal
    Winsock1.GetData bData
    MbusByteArray(i) = bData
Next
j = 0
If MbusRead Then
    For i = 10 To MbusByteArray(9) + 9 Step 2
        txtReg(j).Text = (MbusByteArray(i) * 256) + MbusByteArray(i + 1)
        j = j + 1
    Next i
    lblStatus.Caption = "Registers read"
    lblStatus.BackColor = vbGreen
    For k = j To 19
        txtReg(k).Text = ""
    Next k
    ModbusWait = False
    ModbusTimeOut = 0
    TimerTO.Enabled = False
ElseIf MbusWrite Then
    If (MbusByteArray(8) = 16) And (MbusByteArray(12) = Val(txtLengthReg.Text)) Then
        lblStatus.Caption = "Registers written"
        lblStatus.BackColor = vbGreen
        ModbusWait = False
        ModbusTimeOut = 0
        TimerTO.Enabled = False
    Else
        lblStatus.Caption = "Error writting registers"
        lblStatus.BackColor = vbYellow
    End If
End If
End Sub

'/// end of script ///




5. Jalankan program.
Run the program.
6. Buka Modbus Simulator (Mod RSSim, baca artikelnya disini)
Open Modbus Simulator (Mod RSSim, read the article here)
7. Tekan tombol Connect.
click on Connect button.
8. Setelah berhasil konek (tertulis di lable status: "Connected"), tentukan Start Address yang akan dibaca, kita coba dengan 0, dan Length -nya 20.
After successfully connected (showed in label status: "Connected"), set Start Address which will be read, we try with 0, and the Length is 20.
9. Tekan tombol Read. Jika pembacaan berhasil maka nilai register akan ditampilkan pada textbox txtReg() dan lable status tertulis "Registers read".
Click on Read button. If this works, the values of Holding registers will displayed on textbox txtReg() and the label status shows "Registers read".
 
10. Cobalah mengganti nilai pada txtReg(), misal txtReg(0) kita isi nilai 1 dan txtReg(1) kita isi dengan 2.
Try to change the value in txtReg(), in example txtReg(0) we set to 1 and txtReg(1) set to 2.
12. Tekan tombol Write. Jika penulisan berhasil maka tertulis di label status "Registers written", dan nilai di Modbus Simulator akan berubah.
Click on Write button. If this works, the label status shows "Registers written", and the valus on Modbus Simulator will change.
 

Catatan: setelah sekitar 2 menit, jika tidak terjadi Read atau Write ke Modbus, maka secara otomatis device Modbus akan mematikan koneksi. Jika ini terjadi, lakukan Disconnect lalu Connect lagi.
Note: after 2 minutes, if no Read or Write request to Modbus, the connection will automatically down. if this happen, do Disconnect and the Connect again.

Silahkan download source projek ini disini.
The source code of this project can be downloaded here.

Sekian tutorial dari kami. Semoga bermanfaat dan selamat mencoba..

======================

Update 24 Februari 2014
Modbus TCP VB6 Winsock Version 2

Berikut adalah pengembangan dari projek Modbus TCP VB6 Winsock. Pada veri ini ada beberapa penambahan dan perubahan:
1. Fitur Monitoring Realtime. dengan fitur ini, data yang ditampilkan akan update otomatis setiap 1 detik.
2. Pembacaan Coil Outputs dan Digital Inputs.
3. Maksimal data yang ditampilkan hanya 16 data, agar pas untuk pembacaan Coils dan Inputs.
4. Untuk Digital Inputs tidak bisa dilakukan Write.

Tampilannya seperti ini:

Silahkan download source projek Modbus TCP VB6 Winsock versi 2 ini disini.

Semoga bermanfaat.

33 komentar:

  1. kolomnya kok holding aja pak??? yang coil status gak ada???

    ReplyDelete
    Replies
    1. karena itu sample yang simple saja. bisa saja ditambah register yg lain.

      Delete
  2. rtu saya bisa konek ke softwarenya pak hadi, tetapi gak update ya datanya??? saya harus klik Read untuk melihat data dari RTU secara realtime

    ReplyDelete
    Replies
    1. iya, datanya akan update saat klik tombol Read saja. kalau mau realtime, silahkan tambahkan objek Timer, misal setiap 1 detik sekali melakukan pembacaan register.

      Delete
  3. caranya gmn pak?? nambah objek timer dan nambah colom Coil Status?? di software bapak kan Holding register saja....
    saya newbie pak, di sisi software.... cuma mengerti di sisi hardware aja... hehehhe

    trims

    ReplyDelete
    Replies
    1. sebentar ya, versi tambahannya nanti kami upload, insya Allah. coming soon.. :)

      Delete
    2. Postingan sudah diupdate. silahkan unduh versi terbaru dari projek ini pada link yang tertera. Semoga bermanfaat.

      Delete
  4. datanya masih belom bisa update secara rreal time pak, msih harus tekan Read, barusan saya coba......colom coil status kok gak ada y pak???

    ReplyDelete
    Replies
    1. maaf, ternyata kami belum membuat file EXE dari versi 2 nya. kalau buka projeknya sih sudah benar, namun belum dibuat EXE nya, terlewat. Link sudah diperbarui ke file RAR yang sudah ada EXE terbaru, silahkan diunduh. Terima kasih.

      Delete
  5. Maaf, projek Modbus TCP VB6 Winsock versi 2 ternyata ada bugs/kesalahan, tidak bisa Write ke Coil Outputs. Namun saat ini sudah diperbaiki dan link download sudah diarahkan ke projek terbaru.
    Terima kasih.

    ReplyDelete
  6. oke mas hadi.......... softwarenya sukses... koneksi dengan RTU arduino saya

    dtunggu ... untuk perkembangan software selanjutnya

    puaks.blogspot.com

    ReplyDelete
  7. Wah mas FUAD si jago dari surabaya... gmana kabar apd sana?

    ReplyDelete
  8. Alhamdulillah baik......ini bapak siapa y

    ReplyDelete
  9. sangat menginspirasi...jazakallahukhoir

    ReplyDelete
  10. terima kasih, sangat membantu saya dalam project yang saya sedang jalani. semoga kebaikan selalu bersama anda

    ReplyDelete
    Replies
    1. apakah ada referensi utk membaca input register dari PLC? karena dengan program ini, utk read register yg dibaca adalah holding register

      Delete
    2. Saya sarankan sebaiknya Mas pakai projek yg sudah dibuat dg VB.net, penjelasannya disini:
      http://hadiscada.blogspot.co.id/2013/07/modbus-tcp-sample-vb.html

      disitu sudah ada fitur untuk baca Input Register.
      Atau Mas bisa juga, lihat source codenya pas bagian baca Input Register kemudian dicopy ke projek VB6 ini.

      Demikian dan terima kasih.

      Delete
  11. Mas saya sangat berterimakasih sekali mas... Sy cari2 eh ketemunya artikel disini bagus... Trims trims sangat bermanfaat....

    ReplyDelete
  12. Semoga bs jadi amal jariyah amiinn

    ReplyDelete
  13. mas untuk membaca data type real dari modbus bagaimana ya?

    ReplyDelete
    Replies
    1. itu ada script nya mas, REAL/Float kan pake 4 register, jd perlu script utk gabungin nilainya.

      Delete
  14. Mas, untuk value dari TextReg nya bisa di baca di script gak ya? trimksh

    ReplyDelete
  15. Mas kalau buat baca lebih dari 1 slave scriptnya gmn mas?

    ReplyDelete
    Replies
    1. tinggal di-duplikasi saja.
      tp ini projek lama, saya rekomendasikan projek terbaru dengan VB dot net, silahkan baca di artikel2 terbaru blog ini.

      Delete
  16. maaf pak mau nanya kalau data yang di inginkan floating atau pecahan gimna pak caranya mohon bantuanya

    ReplyDelete
    Replies
    1. harus baca dengan format/tipe data Float, di projek ini belum ada script nya, silahkan lihat di projek2 terbaru.
      Terima kasih.

      Delete
  17. Untuk mengambil angka tertentu dari sebuah PLC konsep dasarnya spt apa Pak? Di manual yang saya miliki structurnya spt ini :
    Address(byte) Function Code (Byte) data (n byte) dan CRC (2 bytes). Model komunikasinya modbus TCP/IP. Ketika saya menggunakan aplikasi yang Bapak buat, terus koneksi ke IP addressnya sudah berhasil. Namun di aplikasi tsb kan kita diminta untuk memasukkan unit,start address dan size. Lalu pertanyaannya adalah bagaimana cara saya menentukan unit,start address dan size tsb Pak? Karena saya masih bingung ketika membaca manual dari PLC tsb.

    ReplyDelete
  18. Kalau membaca input register angkanya lebih dari 5 digit bagaimana.? Misal isi input register adalah " 245789". Klw dg program yg diatas hasilnya over flow.

    ReplyDelete

 
Copyright © . HadiSCADA - Posts · Comments
Theme Template by BTDesigner · Powered by Blogger