Việc thiết kế một giao diện Web Server cho PLC (Programmable logic controller) đối với các kỹ sư chuyên ngành điện – tự động hóa là một công việc không hề dễ dàng. Theo như mình tìm hiểu, hiện tại đa số các hãng PLC có thương hiệu lớn trên thế giới đều hỗ trợ giao diện Web Server. Tuy nhiên, để thiết kế giao diện Web Server cho PLC không những đòi hỏi bạn phải giỏi về lập trình PLC, kết nối truyền thông PLC và Web Server mà còn đòi hỏi bạn có một trình độ nhất định về html, css, javascript chưa kể đến yếu tố thẩm mỹ, kỹ năng xử lý hình ảnh, vân vân và mây mây.
Mình là một kỹ sư chuyên ngành tự động hóa, trước mình đã làm Web Server cho PLC S7-1200 của Siemens (bạn có thể xem thêm bài viết bên trên để hiểu rõ hơn). Thực sự để hoàn thành dự án này lần đầu tiên mình đã cần thêm sự giúp sức của hai bạn nữa, một bạn chuyên về công nghệ thông tin, một bạn chuyên về lập trình web; còn hiện tại thì mình có thể làm full rồi. Mục đích mình chia sẻ bài viết này cho các bạn là gì? Hiện tại, mình đã tìm ra phương án thay thế tối ưu cho các dự án cần thiết kế Web Server sử dụng PLC. Chúng ta cùng tìm hiểu chi tiết thông qua bài chia sẻ phía dưới nhé!
Video hướng dẫn thiết kế giao diện Web Server cho PLC
#1. Demo trước kết quả
- Giao diện Web Server trên máy tính (PC)
- Giao diện HMI trên máy tính (PC)
- Giao diện Web Server trên điện thoại
- Giao diện HMI trên điện thoại
#2. Hướng dẫn thiết kế giao diện Web Server
- Phần mềm sử dụng – UniLogic
- Cấu hình phần cứng và truyền thông
- Cấu hình địa chỉ IP cho Web Server
- Khởi tạo trang Web Server
- Thiết lập các tham số cần thiết cho trang Web
- Phân quyền người dùng cho trang Web
- Sử dụng thư viện đồ họa có sẵn và thêm các thư viện đồ họa bên ngoài lên Web Server
- Cách gán tag (biến) cho đối tượng đồ họa có thể hoạt động trên Web
- Tạo nhiều trang web con cho một Web Server
- Thiết kế giao diện HMI (thử nghiệm khả năng đồng bộ hóa giữa giao diện HMI & Web Server)
- Chạy mô phỏng tính năng Web Server vừa tạo
#3. Sao chép từ giao diện HMI sang giao diện Web
Bài toán đặt ra
Lập trình điều khiển hai máy bơm công nghiệp sử dụng PLC. Thiết kế giao diện giám sát và vận hành cục bộ trên màn hình HMI, trên máy tính và điện thoại qua VNC. Thiết kế giao diện giám sát và điều khiển từ xa qua Web Server (có thể sử dụng các thiết bị như điện thoại thông minh, máy tính bảng, máy tính PC,.. hỗ trợ trình duyệt web và có kết nối Internet để truy cập ngẫu nhiên).
Khai báo địa chỉ
- Tank1_Switch: công tắc bật máy bơm nhất
- Tank1_Level: giá trị mô phỏng mực nước bồn chứa thứ nhất
- Tank1_Warning: cảnh báo vượt quá mức nước quy định của bồn chứa thứ nhất
- Tank2_Switch: công tắc bật máy bơm hai
- Tank2_Level: giá trị mô phỏng mực nước bồn chứa thứ hai
- Tank2_Warning: cảnh báo vượt quá mức nước quy định của bồn chứa thứ hai
- Pump1_test: nút nhấn test mô phỏng áp lực nước cho máy bơm thứ nhất
- Pump2_test: nút nhấn test mô phỏng áp lực nước cho máy bơm thứ hai
- Pump1_Start: nút nhấn bật/tắt mô phỏng đồng hồ đo áp lực nước máy bơm thứ nhất
- Pump2_Start: nút nhấn bật/tắt mô phỏng đồng hồ đo áp lực nước máy bơm thứ hai
- Water_Flow: giá trị mô phỏng đo lưu lượng nước đầu vào
- Pump2_Pressure: giá trị mô phỏng áp lực nước bơm thứ hai
- Pump1_Pressure: giá trị mô phỏng áp lực nước bơm thứ 1
- Blink: mô phỏng đèn báo hệ thống đang hoạt động
Viết chương trình LAD cho PLC
Mô phỏng mức nước thay đổi trong bình khi bơm hoạt động
- Khi bật công tắc Tank1_Switch thì mức nước Tank1 sẽ tăng lên (đếm tăng giá trị Tank1_Level)
- Khi bật công tắc Tank2_Switch thì mức nước Tank2 sẽ tăng lên (đếm tăng giá trị Tank2_Level)
- Khi giá trị Tank1_Level vượt qua ngưỡng 1000 thì sẽ tự động đặt lại (reset) giá trị của Tank1_Level
- Khi giá trị Tank2_Level vượt qua ngưỡng 1000 thì sẽ tự động đặt lại (reset) giá trị của Tank2_Level
- Khi giá trị Tank1_Level vượt qua ngưỡng 5000 thì sẽ Tank1 sẽ cảnh báo (Tank1_Warning hoạt động)
- Khi giá trị Tank2_Level vượt qua ngưỡng 5000 thì sẽ Tank2 sẽ cảnh báo (Tank2_Warning hoạt động)
Mô phỏng tín hiệu đo lường cho đồng hồ đo áp lực nước
- Khi Pump1_test = 1 thì Pump1_Pressure = 60 đồng thời gán giá trị đếm Pump1_test_Time
- Khi Timer đếm đạt ngưỡng đã đặt trong Pump1_test_Time thì sẽ gán giá trị 0 cho Pump1_Pressure và reset Pump1_test = 0
- Khi Pump2_test = 1 thì Pump2_Pressure = 60 đồng thời gán giá trị đếm Pump2_test_Time
- Khi Timer đếm đạt ngưỡng đã đặt trong Pump2_test_Time thì sẽ gán giá trị 0 cho Pump2_Pressure và reset Pump2_test = 0
- Khi nhấn nút Pump1_Start = 1 thì
- Giá trị đếm Pump1_Pressure sẽ tăng => nếu giá trị Pump1_Pressure vượt ngưỡng 80 thì sẽ tự động gán giá trị 60 cho Pump1_Pressure
- Giá trị đếm của Water_Flow sẽ tăng => nếu giá trị Water_Flow vượt ngưỡng 900 thì sẽ tự động gán giá trị 800 cho Water_Flow
- Khi nhấn nút Pump2_Start = 1 thì giá trị đếm Pump2_Pressure sẽ tăng => nếu giá trị Pump2_Pressure vượt ngưỡng 80 thì sẽ tự động gán giá trị 60 cho Pump2_Pressure
- Khi Pump1_Start = 0 thì Pump1_Pressure = 0
- Khi Pump2_Start = 0 thì Pump2_Pressure = 0
- Chú thích: chữ cái “P” trong biểu tượng của “Frequency.Frequ…” có ý nghĩa là lấy sườn lên. Tương tự, nếu là chữ cái “N” tức là lấy sườn xuống.
Viết chương trình ST cho PLC
Dưới đây là chương trình PLC của bài toán trên được viết theo ngôn ngữ lập trình ST cho PLC.
BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_op4056F476); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.TSecond, _op_op0DDC18BD); /* 3. Inc */ ARITHMETIC_INC(RLO1, _op_op3C5E18D6); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_op699E4084); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.TSecond, _op_opC64DF96E); /* 3. Inc */ ARITHMETIC_INC(RLO1, _op_op403F3D0D); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Greater Than */ IF_GT(RLO1, _op_op3C5E18D6, 1000); /* 2. Reset Numeric */ RESERT_NUMERIC(RLO1, (&_op_op3C5E18D6), 1); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Greater Than */ IF_GT(RLO1, _op_op403F3D0D, 1000); /* 2. Reset Numeric */ RESERT_NUMERIC(RLO1, (&_op_op403F3D0D), 1); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Greater Than */ IF_GT(RLO1, _op_op3C5E18D6, 5000); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.Second, _op_op7D1E12F1); /* 3. Toggle Coil */ TOGGLE(RLO1, _op_opE49CABFD); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Greater Than */ IF_GT(RLO1, _op_op403F3D0D, 5000); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.Second, _op_op40952BE9); /* 3. Toggle Coil */ TOGGLE(RLO1, _op_op0E1A769F); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_opA8740C27); /* 2. Store */ STORE(RLO1, 60, _op_opE0D14A15); /* 3. Timer TON */ TIMER_ON_DELAY(RLO1, _op_op932F4FFF); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_op932F4FFF.m_done); /* 2. Store */ STORE(RLO1, 0, _op_opE0D14A15); /* 3. Reset Coil */ RESET(RLO1, _op_opA8740C27); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_opDFEADED7); /* 2. Store */ STORE(RLO1, 60, _op_op706F37FF); /* 3. Timer TON */ TIMER_ON_DELAY(RLO1, _op_opAA57E2BF); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_opAA57E2BF.m_done); /* 2. Store */ STORE(RLO1, 0, _op_op706F37FF); /* 3. Reset Coil */ RESET(RLO1, _op_opDFEADED7); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1, RLO2, RLO3; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_opAF1C2D67); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.TSecond, _op_opD5C63FFF); END_BLOCK /* 3. Junction */ RLO2 = RLO3 = RLO1; BEGIN_BLOCK /* 4. Inc */ ARITHMETIC_INC(RLO2, _op_opE0D14A15); /* 5. Greater Than */ IF_GT(RLO2, _op_opE0D14A15, 80); /* 6. Store */ STORE(RLO2, 60, _op_opE0D14A15); END_BLOCK BEGIN_BLOCK /* 7. Inc */ ARITHMETIC_INC(RLO3, _op_op238E98C7); /* 8. Greater Than */ IF_GT(RLO3, _op_op238E98C7, 900); /* 9. Store */ STORE(RLO3, 800, _op_op238E98C7); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Direct Contact */ ACC_AND(RLO1, _op_opD37D08BC); /* 2. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.TSecond, _op_op0ECC6585); /* 3. Inc */ ARITHMETIC_INC(RLO1, _op_op706F37FF); /* 4. Greater Than */ IF_GT(RLO1, _op_op706F37FF, 80); /* 5. Store */ STORE(RLO1, 60, _op_op706F37FF); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Negative Transition Contact */ WHEN_FALL(RLO1, _op_opAF1C2D67, _op_op35558991); /* 2. Reset Numeric */ RESERT_NUMERIC(RLO1, (&_op_opE0D14A15), 1); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Negative Transition Contact */ WHEN_FALL(RLO1, _op_opD37D08BC, _op_opDA54C70F); /* 2. Reset Numeric */ RESERT_NUMERIC(RLO1, (&_op_op706F37FF), 1); END_BLOCK /* End Junction */ END_RUNG BEGIN_RUNG register int RLO1; /* BusBar Inited RLOs */ RLO1 = RLO; /* BusBar */ BEGIN_BLOCK /* 1. Positive Transition Contact */ WHEN_RISE(RLO1, _op_op5146AD76.Second, _op_op4DFCAE7A); /* 2. Toggle Coil */ TOGGLE(RLO1, _op_op8C8A66D1); END_BLOCK /* End Junction */ END_RUNG
Giao diện HMI vận hành & giám sát máy bơm công nghiệp
Giao diện Web Server vận hành & giám sát máy bơm công nghiệp từ xa
Trên đây, MESIDAS GROUP đã chia sẻ cho các cách để có thể thiết kế một giao diện HMI hay một giao diện Web Server vô cùng ấn tượng dành cho PLC; hỗ trợ giám sát & vận hành trên nhiều nền tảng từ PC đến điện thoại, vô cùng trực quan và dễ dàng sử dụng. Hy vọng rằng, với những chia sẻ phía trên sẽ giúp ích được cho các bạn đang tìm hiểu, nghiên cứu, học tập hay làm việc với giao diện Web Server của PLC. Xin cảm ơn!