實(shí)驗(yàn)?zāi)康?
JAVA應(yīng)用程序通過(guò)MODBUS協(xié)議RTU模式讀寫設(shè)備
?
實(shí)驗(yàn)器材
西門子?s7-200?226cn?PLC?的CPU一臺(tái);s7-200?編程電纜一條,這條電纜亦充當(dāng)MODBUS的串行口上的連接線。編程電纜是USB接口的,由于此編程電纜的驅(qū)動(dòng)程序安裝后即模擬了一個(gè)虛擬的串行口COM3,因此可以借助此電纜充當(dāng)實(shí)際的物理連接線路
?
開發(fā)環(huán)境
Jdk1.6?update?25;?STEP?7-MicroWIN?4.0;西門子S7-200的MODBUS庫(kù)
?
實(shí)驗(yàn)?zāi)繕?biāo)
讀PLC的輸入過(guò)程映像寄存器;寫PLC的V存儲(chǔ)區(qū)
?
JAVA應(yīng)用程序第三方開發(fā)包下載頁(yè)面 http://sourceforge.net/projects/modbus4j/files/modbus4j/
?
Java串行口編程開發(fā)包?RXTXcomm.jar
?
環(huán)境搭建
PLC充當(dāng)從站,占用通訊口port0;JAVA應(yīng)用程序充當(dāng)主站,發(fā)起讀寫的請(qǐng)求并等待PLC的響應(yīng)。示例程序里寫十六進(jìn)制數(shù)值31(即二進(jìn)制?00110001)到保持寄存器上,
PLC的Q1顯示的結(jié)果是:
Q1.0?亮
Q1.1?滅
Q1.2?滅
Q1.3?滅
Q1.4?亮
Q1.5?亮
Q1.6?滅
Q1.7?滅
?
PLC從站的編程目標(biāo):MODBUS協(xié)議上的保持寄存器里的一個(gè)字節(jié)輸出到Q,以便通過(guò)PLC上的指示燈觀察。
?
PLC上的梯形圖
?
說(shuō)明:
IB0上的值決定是否啟用MODBUS
通訊波特率9600
從站地址是5
I和Q的最大訪問(wèn)個(gè)數(shù)是128
模擬量輸入最大訪問(wèn)個(gè)數(shù)是32
保持寄存器可訪問(wèn)1000個(gè)字
VB1上的字節(jié)輸出到Q1.0?...?Q1.7
?
?
?
JAVA應(yīng)用程序
import?com.serotonin.io.serial.*;
import?com.serotonin.modbus4j.*;
import?com.serotonin.modbus4j.exception.*;
import?com.serotonin.modbus4j.msg.*;
import?java.util.*;
final?class?HardneedlTest?{
????//MODBUS網(wǎng)絡(luò)上從站地址
????private?final?static?int?SLAVE_ADDRESS=5;
?
????//串行口波特率
????private?final?static?int?BAUD_RATE?=?9600;
????
????public?static?void?main(String[]?args)?throws?Exception?{
????????SerialParameters?serialParameters?=?new?SerialParameters();
?
????????//設(shè)定MODBUS通訊的串行口
????????serialParameters.setCommPortId("COM3");
?
????????//設(shè)定成無(wú)奇偶校驗(yàn)
????????serialParameters.setParity(0);
?
????????//設(shè)定成數(shù)據(jù)位是8位
????????serialParameters.setDataBits(8);
?
????????//設(shè)定為1個(gè)停止位
????????serialParameters.setStopBits(1);
?
????????serialParameters.setPortOwnerName("Numb?nuts");
?
????????//串行口上的波特率
????????serialParameters.setBaudRate(BAUD_RATE);
?
????????ModbusFactory?modbusFactory?=?new?ModbusFactory();
????????ModbusMaster?master?=?modbusFactory.createRtuMaster(serialParameters);
????????try?{
????????????master.init();
????????????readDiscreteInputTest(master,SLAVE_ADDRESS,0,8);
????????????writeRegistersTest(master,SLAVE_ADDRESS,?0,?new?short[]{0x31,0xb,0xc,0xd,0xe,0x9,?0x8,?0x7,?0x6}?);
????????????readHoldingRegistersTest(master,SLAVE_ADDRESS,0,8);
????????}
????????finally?{
????????????master.destroy();
????????}
????}
?
????/**
?????*?讀開關(guān)量型的輸入信號(hào)
?????*?@param?master?主站
?????*?@param?slaveId?從站地址
?????*?@param?start?起始偏移量
?????*?@param?len?待讀的開關(guān)量的個(gè)數(shù)
?????*/
????private?static?void?readDiscreteInputTest(ModbusMaster?master,?int?slaveId,?int?start,?int?len)?{
????????try?{
????????????ReadDiscreteInputsRequest?request?=?new?ReadDiscreteInputsRequest(slaveId,?start,?len);
????????????ReadDiscreteInputsResponse?response?=?(ReadDiscreteInputsResponse)?master.send(request);
?
????????????if?(response.isException())
????????????????System.out.println("Exception?response:?message="?+?response.getExceptionMessage());
????????????else
????????????????System.out.println(Arrays.toString(response.getBooleanData()));
????????}
????????catch?(ModbusTransportException?e)?{
????????????e.printStackTrace();
????????}
????}
?
????/**
?????*?讀保持寄存器上的內(nèi)容
?????*?@param?master?主站
?????*?@param?slaveId?從站地址
?????*?@param?start?起始地址的偏移量
?????*?@param?len?待讀寄存器的個(gè)數(shù)
?????*/
????private?static?void?readHoldingRegistersTest(ModbusMaster?master,?int?slaveId,?int?start,?int?len)?{
????????try?{
????????????ReadHoldingRegistersRequest?request?=?new?ReadHoldingRegistersRequest(slaveId,?start,?len);
????????????ReadHoldingRegistersResponse?response?=?(ReadHoldingRegistersResponse)?master.send(request);
?
????????????if?(response.isException())
????????????????System.out.println("Exception?response:?message="?+?response.getExceptionMessage());
????????????else
????????????????System.out.println(Arrays.toString(response.getShortData()));
????????}
????????catch?(ModbusTransportException?e)?{
????????????e.printStackTrace();
????????}
????}
?
????/**
?????*?批量寫數(shù)據(jù)到保持寄存器
?????*?@param?master?主站
?????*?@param?slaveId?從站地址
?????*?@param?start?起始地址的偏移量
?????*?@param?values?待寫數(shù)據(jù)
?????*/
????public?static?void?writeRegistersTest(ModbusMaster?master,?int?slaveId,?int?start,?short[]?values)?{
????????try?{
????????????WriteRegistersRequest?request?=?new?WriteRegistersRequest(slaveId,?start,?values);
????????????WriteRegistersResponse?response?=?(WriteRegistersResponse)?master.send(request);
?
????????????if?(response.isException())
????????????????System.out.println("Exception?response:?message="?+?response.getExceptionMessage());
????????????else
????????????????System.out.println("Success");
????????}
????????catch?(ModbusTransportException?e)?{
????????????e.printStackTrace();
????????}
????}
}
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
