Membaca dan Menulis Data ke Memori D PLC Omron Menggunakan Python (FINS UDP Protocol)

🧾 1. Judul
Membaca dan Menulis Data ke Memori D PLC Omron Menggunakan Python (FINS UDP)
🎯 2. Tujuan
- Mahasiswa mampu memahami komunikasi protokol FINS UDP pada PLC Omron.
- Mahasiswa mampu membuat program Python untuk membaca dan menulis ke area memori D PLC Omron.
📚 3. Dasar Teori
FINS (Factory Interface Network Service) adalah protokol komunikasi milik Omron yang memungkinkan perangkat lunak eksternal seperti Python terhubung ke PLC.
FINS mendukung komunikasi UDP/TCP, dengan format komunikasi khusus.
Struktur memori PLC Omron:
- D0000–D9999: Data Memory (D)
- Tiap alamat D memiliki panjang 16-bit (2 byte)
Protokol UDP digunakan untuk komunikasi ringan dan cepat, biasanya tanpa koneksi langsung (connectionless).
🧰 4. Alat dan Bahan
No | Alat / Bahan | Keterangan |
1 | PLC Omron (mis. CP1L/CP1E) | Telah dikonfigurasi alamat IP |
2 | Kabel Ethernet + Switch | Untuk koneksi ke PC |
3 | PC dengan Python Terinstal | Python 3.x dan modul socket |
4 | Software CX-Programmer | Untuk memonitor data PLC |
🧩 5. Konfigurasi Awal
- IP PLC Omron: 192.168.250.1
- IP PC (Python): 192.168.250.2
- Memori D Target: D101 (alamat hex: 0065)
- Pastikan fungsi FINS diaktifkan (via CX-Programmer atau switch PLC)
🧪 6. Langkah Praktikum
🔧 A. Membaca Nilai dari D101 import socket PLC_IP = '192.168.250.1' PLC_PORT = 9600 PC_NODE = 0x0A # Sesuaikan dengan IP PC terakhir PLC_NODE = 0x01 # Biasanya 1 untuk Omron PLC def fins_read_dword(address): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) # Format FINS command untuk membaca 1 word dari D-memory cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, # Header PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, # Node 0x01, 0x01, # Command code: Memory Area Read 0x82, # Memory area code for D (address >> 8) & 0xFF, address & 0xFF, # Address 0x00, 0x00, 0x01 # Bit offset + count (1 word) ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() # Nilai word berada di byte 14 dan 15 (MSB LSB) value = data[14] << 8 | data[15] return value # Contoh pemanggilan val = fins_read_dword(0x0065) # D101 print("Isi D101:", val)
🔧 B. Menulis Nilai ke D101
def fins_write_dword(address, value): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, 0x01, 0x02, # Command code: Memory Area Write 0x82, (address >> 8) & 0xFF, address & 0xFF, 0x00, 0x00, 0x01, (value >> 8) & 0xFF, value & 0xFF ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() return data[11] == 0x00 and data[12] == 0x00 # success if code == 0x0000 # Contoh menulis nilai 123 ke D101 ok = fins_write_dword(0x0065, 123) print("Tulis ke D101 berhasil" if ok else "Gagal menulis")
✅ 7. Hasil yang Diharapkan
- Setelah menjalankan program baca, nilai dari D101 terbaca di terminal Python.
- Setelah menjalankan program tulis, nilai D101 berubah sesuai nilai yang dikirimkan (dicek via CX-Programmer).
📌 8. Tugas
- Ubah kode agar membaca dan menulis ke alamat D200.
- Tambahkan input dari user untuk mengisi nilai yang ingin ditulis ke D200.
- Uji komunikasi dengan 3 nilai berbeda.
📷 9. Dokumentasi
- Screenshot hasil pembacaan D101 dari Python.
- Screenshot CX-Programmer menunjukkan perubahan nilai di D101.
🧠 10. Catatan Tambahan
- Jika menggunakan Raspberry Pi atau Linux, pastikan port UDP tidak diblokir firewall.
- Jika nilai tidak berubah, pastikan PLC tidak dalam mode “RUN (protected)”.
💻 Versi GUI Python (Tkinter)
🎯 Tujuan:
- Menyediakan antarmuka grafis untuk memudahkan operator membaca dan menulis data ke memori D PLC Omron.
🧱 Struktur Program GUI:
import tkinter as tk from tkinter import messagebox import socket PLC_IP = '192.168.250.1' PLC_PORT = 9600 PC_NODE = 0x0A PLC_NODE = 0x01 def fins_read_dword(address): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, 0x01, 0x01, 0x82, (address >> 8) & 0xFF, address & 0xFF, 0x00, 0x00, 0x01 ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() return data[14] << 8 | data[15] def fins_write_dword(address, value): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, 0x01, 0x02, 0x82, (address >> 8) & 0xFF, address & 0xFF, 0x00, 0x00, 0x01, (value >> 8) & 0xFF, value & 0xFF ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() return data[11] == 0x00 and data[12] == 0x00 def read_d(): try: addr = int(entry_addr.get()) val = fins_read_dword(addr) result_label.config(text=f"Nilai D{addr}: {val}") except Exception as e: messagebox.showerror("Error", str(e)) def write_d(): try: addr = int(entry_addr.get()) val = int(entry_value.get()) success = fins_write_dword(addr, val) if success: messagebox.showinfo("Sukses", f"Berhasil tulis D{addr} = {val}") else: messagebox.showerror("Gagal", "Gagal menulis data") except Exception as e: messagebox.showerror("Error", str(e)) root = tk.Tk() root.title("FINS Omron GUI") tk.Label(root, text="Alamat D (mis. 101)").pack() entry_addr = tk.Entry(root) entry_addr.pack() tk.Label(root, text="Nilai").pack() entry_value = tk.Entry(root) entry_value.pack() tk.Button(root, text="Baca D", command=read_d).pack(pady=5) tk.Button(root, text="Tulis D", command=write_d).pack(pady=5) result_label = tk.Label(root, text="Nilai akan muncul di sini") result_label.pack() root.mainloop()
🌐 Versi Node-RED + MQTT + Python (Bridge)
🧩 Arsitektur:
- Python sebagai jembatan ke PLC (menggunakan fins_udp)
- MQTT Broker (contoh: Mosquitto)
- Node-RED untuk visualisasi + kontrol data
📦 A. Instalasi Library MQTT
pip install paho-mqtt
🔁 B. Python MQTT Bridge ke PLC Omron
import paho.mqtt.client as mqtt import socket import json PLC_IP = '192.168.250.1' PLC_PORT = 9600 PC_NODE = 0x0A PLC_NODE = 0x01 MQTT_BROKER = "localhost" TOPIC_SUB = "omron/write" TOPIC_PUB = "omron/read" def fins_read_dword(address): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, 0x01, 0x01, 0x82, (address >> 8) & 0xFF, address & 0xFF, 0x00, 0x00, 0x01 ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() return data[14] << 8 | data[15] def fins_write_dword(address, value): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) cmd = bytearray([ 0x80, 0x00, 0x02, 0x00, PLC_NODE, 0x00, 0x00, PC_NODE, 0x00, 0x00, 0x01, 0x02, 0x82, (address >> 8) & 0xFF, address & 0xFF, 0x00, 0x00, 0x01, (value >> 8) & 0xFF, value & 0xFF ]) s.sendto(cmd, (PLC_IP, PLC_PORT)) data, _ = s.recvfrom(1024) s.close() return data[11] == 0x00 and data[12] == 0x00 def on_connect(client, userdata, flags, rc): print("Connected with result code", rc) client.subscribe(TOPIC_SUB) def on_message(client, userdata, msg): try: data = json.loads(msg.payload.decode()) addr = int(data['addr']) if 'value' in data: fins_write_dword(addr, int(data['value'])) else: val = fins_read_dword(addr) client.publish(TOPIC_PUB, json.dumps({"addr": addr, "value": val})) except Exception as e: print("Error:", e) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect(MQTT_BROKER, 1883, 60) client.loop_forever()
🧠 Contoh Payload MQTT untuk Menulis dari Node-RED:
{
“addr”: 101,
“value”: 123
}
📥 Contoh Payload MQTT yang diterima saat Membaca:
{
“addr”: 101,
“value”: 123
}
📌 Node-RED Flow:
- Inject (payload addr only) → MQTT publish ke omron/write
- Jika hanya kirim {“addr”: 101} → maka script akan membalas ke omron/read
- Gunakan mqtt in node untuk menangkap dan tampilkan value dari D101
🎓 Belajar PLC dari Dasar hingga Mahir bersama instruktur berpengalaman. Cocok untuk mahasiswa, teknisi, dan profesional industri.
👉 Ikuti Kursus PLC di Bisaioti.com