MODBUS là một protocol phổ biến bậc nhất được sử dụng hiện nay cho nhiều mục đích. MODBUS do Modicon (hiện nay thuộc Schneider Electric) phát triển năm 1979, là một phương tiện truyền thông với nhiều thiết bị thông qua một cặp dây xoắn đơn. Ban đầu, nó hoạt động trên RS232, nhưng sau đó nó sử dụng cho cả RS485 để đạt tốc độ cao hơn, khoảng cách dài hơn, và mạng đa điểm (multi-drop). MODBUS đã nhanh chóng trở thành tiêu chuẩn thông dụng trong ngành tự động hóa, và Modicon đã cho ra mắt công chúng như một protocol miễn phí.

Ngày nay, MODBUS-IDA (www.MODBUS.org) , tổ chức sử dụng và cung cấp MODBUS lớn nhất tiếp tục hỗ trợ protocol MODBUS trên toàn cầu.

PROTOCOL hay giao thức truyền thông là những quy định trong việc truyền thông tin giữa các thiết bị trong hệ thống công nghiệp

MODBUS than chiếu theo hệ OSI nó nằm ở lớp thứ 7 lớp ứng dụng và tùy theo loại modbus thì ở các lớp dưới nó dùng những phương thức khác nhau

Bài này Tôi xin viết chủ yếu về ModBus RTU  và  ASCII căn bản nó là giống nhau ở khung Frame data . Nhưng khác nhau ở các bit truyền trên đường truyền

RTU:   frame Data

MODBUS

ASCII: Frame Data

MODBUS1

Các chế độ modbus

01 READ COIL STATUS

02 READ INPUT STATUS
03 READ HOLDING REGISTERS
04 READ INPUT REGISTERS
05 WRITE SINGLE COIL
06 WRITE SINGLE REGISTER
15 WRITE MULTIPLE COILS
16 WRITE MULTIPLE REGISTERS

địa chỉ :0000-9999 một thiết bị master có thể đọc và ghi địa chỉ này

địa chỉ :1000-19999 digital Input

địa chỉ :3000-39999 analog  Input

địa chỉ :4000-49999 analog  output

Để mô phỏng được modbus có thể test với phần mền hoặc phần cứng,

Phần mền hmi weintek

ARDUINO UNO

đầu tiên các bạn tải phần mền  hmi weintek

sau đó làm ví dụ đơn giản

m

Button START và STOP cài đặt như sau

a

Thanh ghi hiển thị :

d

như vậy song phần HMI

cắm arduino sau đó vào mục tool->chạy online

cài đặt chọn cổng comport edit->system pamameter

TRên chương trình ARDUINO

Master là HMI còn salve

chương trình arduino

#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
modbusDevice regBank;
modbusSlave slave;

#define RS485TxEnablePin 2
#define RS485Baud 9600
#define RS485Format SERIAL_8N1 // SERIAL_8E1
#define RS232Enable 3
#define RS232Baud 9600
#define RS232Format SERIAL_8N1

#define LED1 11
#define LED2 12
#define LED 13
byte x1,x2;
unsigned int cnt;

void setup()
{
//Assign the modbus device ID.
regBank.setId(1);

/*
modbus registers follow the following format
00001-09999 Digital Outputs, A master device can read and write to these registers
10001-19999 Digital Inputs, A master device can only read the values from these registers
30001-39999 Analog Inputs, A master device can only read the values from these registers
40001-49999 Analog Outputs, A master device can read and write to these registers

Analog values are 16 bit unsigned words stored with a range of 0-32767
Digital values are stored as bytes, a zero value is OFF and any nonzer value is ON

*/

//Add Analog Input registers to the register bank
regBank.add(30001);
regBank.add(30002);
regBank.add(1);
regBank.add(2);
//Add Analog Output registers to the register bank
// regBank.add(30001);
// regBank.add(40002);
slave._device = &regBank;

slave.setBaud(&Serial,RS485Baud,RS485Format,RS485TxEnablePin);
// slave.setBaud(&Serial,RS232Baud,RS232Format,RS232Enable);
// slave.setBaud(9600);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED, OUTPUT);
}

void loop()
{
//Serial1.println(100);
// delay(200);
x1=regBank.get(1);
x2=regBank.get(2);
if(x1==0xFF)
{
digitalWrite(LED,x1); // Serial.println(x1); // print as an ASCII-encoded decimal Serial.println(analogValue); // print as an ASCII-encoded decimal
x1=0;
}
if(x2==0xFF)
{
digitalWrite(LED,0); // Serial.println(x2); // print as an ASCII-encoded decimal Serial.println(analogValue); // print as an ASCII-encoded decimal
x2=0;
}

// delay(200);
// digitalWrite(LED, 0);
// delay(200);
// digitalWrite(LED1, regBank.get(40001));
// digitalWrite(LED2, regBank.get(40002));
cnt++;
if(cnt>=65535) cnt=0;
regBank.set(30001, (word) cnt); //from 0 – 1023
regBank.set(30002, (word) cnt); //from 0 – 1023
//regBank.set(30002, (word) analogRead(A1)); //from 0 – 1023
slave.run();
}

Giải thích 1 chút  :

giá trị ghi đọc lên thanh ghi sẽ hiển thị giá trị cnt thanh ghi 30001 và 30002

Mọi thắc mắc liên hệ Linhkienagv.com

Phone :0977948846

 

 

 

 

Bình luận

Bình luận