我正试图用pyModbusTCP将两台pcs连接在一起。当我在本地使用本地主机运行客户机和服务器时,它工作得很好。
当我尝试在单独的PC上运行它们时,客户端需要一段时间才能“连接”,然后将寄存器读入“无”。我已经为服务器设置了一个静态IP地址为192.254.100.101,并且可以在另一台PC上使用终端来平分它。我在客户端也有一个静态IP地址,为192.254.100.102。
客户代码:
from pyModbusTCP.client import ModbusClient
import time
client = ModbusClient(host="192.254.100.101", port=502, debug = True)
print("Opening client")
client.open()
print("Client open")
try:
while True:
value = client.read_holding_registers(0)
print(f"Register 0: {value}")
time.sleep(1)
except:
print("Shutdown")服务器代码:
from pyModbusTCP.server import ModbusServer, DataBank
import time
server = ModbusServer(host= "192.254.100.101", port = 502, no_block=True)
server.start()
try:
print("Starting server...")
server.start()
print("Server is online")
val = [0]
while True:
val0 = input("Val: ")
val = [int(val0)]
print(val)
DataBank.set_words(0, val)
time.sleep(0.5)
except:
print("Shutdown server")
server.stop()发布于 2022-09-04 05:05:44
.i.e:
您有一个Raspberry pi,静态IP地址为"192.254.100.101“,一些设备连接到它,然后当您向它发送请求时,您也将声明从id号,这里您请求一个数据寄存器。
现在,在服务器应用程序中,您将使用发送方数据包IP地址返回答案。
使用Wireshark和您的本地网络来理解。
java语言中使用Modbus4J的代码
public class MasterTest {
public static void main(String[] args) throws Exception {
// String host = "localhost";
String host = "192.168.1.105";
// String host = "YOUR-DEVICE-IP-THAT-IS-CONNECTED-TO-NETWORK";
IpParameters ipParameters = new IpParameters();
ipParameters.setHost(host);
ipParameters.setPort(502);
ipParameters.setEncapsulated(false);
ModbusFactory modbusFactory = new ModbusFactory();
//TcpMaster extends ModbusMaster + Creates an object with ipParameters in it
ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, true);
// ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, false);
master.setTimeout(8000);
master.setRetries(0);
// openConnection method will be called - if KeepAlive be true - openConnection is in TcpMaster
// openConnection method will close other connections
// Socket.connect(ipParameters.getHost(), ipParameters.getPort(),getTimeout()) is in openConnection method
master.init();
try {
// master.send(new WriteCoilRequest(3, 120, true));
// master.send(new WriteCoilRequest(3, 256, false));
master.send(new ReadCoilsRequest(1, 17, 1));
master.send(new ReadCoilsRequest(3, 256, 1));
master.send(new WriteRegisterRequest(2, 15, 5));
ReadHoldingRegistersResponse rresponse = (ReadHoldingRegistersResponse) master
.send(new ReadHoldingRegistersRequest(1, 15, 1));
System.out.println(rresponse);
// System.out.println(master.testSlaveNode(1));
} catch (Exception e) {
e.printStackTrace();
}
master.destroy();
}
}在Java中使用:的从代码
public class SlaveTest {
static Random random = new Random();
static float ir1Value = -100;
//TEST VALUES
private static Integer twoByteIntUnsignedSwapped = 29187; //Register 16
private static Integer twoByteIntSignedSwapped = -257; //Register 17
private static Long fourByteIntUnsignedSwappedSwapped = 16777216L; //Register 18
private static Long fourByteIntSignedSwappedSwapped = (long) -16777217; //Register 20
private static Long register22 = 2369850368L; ////Register 22
public static void main(String[] args) {
ModbusFactory modbusFactory = new ModbusFactory();
ModbusSlaveSet slave = modbusFactory.createTcpSlave(false);
slave.addProcessImage(getModscanProcessImage(1));
new Thread(new Runnable() {
@Override
public void run() {
try {
slave.start();
} catch (ModbusInitException e) {
e.printStackTrace();
}
}
}).start();
while (true) {
synchronized (slave) {
try {
slave.wait(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (ProcessImage processImage : slave.getProcessImages()) {
try {
updateProcessImage((BasicProcessImage) processImage);
} catch (IllegalDataAddressException e) {
e.printStackTrace();
}
}
}
}
static void updateProcessImage(BasicProcessImage processImage) throws IllegalDataAddressException {
int hr16Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 16, DataType.TWO_BYTE_INT_UNSIGNED_SWAPPED).intValue();
if (hr16Value != twoByteIntUnsignedSwapped) {
throw new RuntimeException("Test failed on TWO_BYTE_INT_UNSIGNED_SWAPPED. Expected " + twoByteIntUnsignedSwapped + " but was: " + hr16Value);
}
short hr17Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 17, DataType.TWO_BYTE_INT_SIGNED_SWAPPED).shortValue();
if (hr17Value != twoByteIntSignedSwapped) {
throw new RuntimeException("Test failed on TWO_BYTE_INT_SIGNED_SWAPPED. Expected " + twoByteIntSignedSwapped + " but was: " + hr17Value);
}
long hr18Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 18, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED).longValue();
if (hr18Value != fourByteIntUnsignedSwappedSwapped) {
throw new RuntimeException("Test failed on FOUR_BYTE_INT_UNSIGNED_SWAPPED_INVERTED. Expected " + fourByteIntUnsignedSwappedSwapped + " but was: " + hr18Value);
}
int hr20Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 20, DataType.FOUR_BYTE_INT_SIGNED_SWAPPED_SWAPPED).intValue();
if (hr20Value != fourByteIntSignedSwappedSwapped) {
throw new RuntimeException("Test failed on FOUR_BYTE_INT_SIGNED_SWAPPED_INVERTED. Expected " + fourByteIntSignedSwappedSwapped + " but was: " + hr20Value);
}
long hr22Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 22, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED).longValue();
if (hr22Value != register22) {
throw new RuntimeException("Test failed on FOUR_BYTE_INT_UNSIGNED_SWAPPED_INVERTED. Expected " + register22 + " but was: " + hr22Value);
}
}
static class BasicProcessImageListener implements ProcessImageListener {
@Override
public void coilWrite(int offset, boolean oldValue, boolean newValue) {
System.out.println("Coil at " + offset + " was set from " + oldValue + " to " + newValue);
}
@Override
public void holdingRegisterWrite(int offset, short oldValue, short newValue) {
// Add a small delay to the processing.
// try {
// Thread.sleep(500);
// }
// catch (InterruptedException e) {
// // no op
// }
System.out.println("HR at " + offset + " was set from " + oldValue + " to " + newValue);
}
}
static BasicProcessImage getModscanProcessImage(int slaveId) {
BasicProcessImage processImage = new BasicProcessImage(slaveId);
//processImage.setAllowInvalidAddress(true);
processImage.setInvalidAddressValue(Short.MIN_VALUE);
//Register 16 Holds 1 and the data is transmitted as 0b00000001 00000000 which is 256
//processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 16, DataType.TWO_BYTE_INT_UNSIGNED_SWAPPED, new Integer(256));
processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 16, DataType.TWO_BYTE_INT_UNSIGNED_SWAPPED, 29187);
//Registery 16 Holds -2 and the data is transmitted as 0b1111110 11111111 which is -257
processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 17, DataType.TWO_BYTE_INT_SIGNED_SWAPPED, -257);
//Register 18 Holds 1 and the data is transmitted as 0b00000001 00000000 00000000 00000000 which is 16777216
processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 18, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED, 16777216L);
//Register 20 Holds -2 and the data is transmitted as 0b1111110 11111111 1111111 11111111 which is -16777217
processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 20, DataType.FOUR_BYTE_INT_SIGNED_SWAPPED_SWAPPED, (long) -16777217);
//Register 22 Holds 803213 and the data is transmitted as 0b10001101 01000001 00001100 00000000 which is 2369850368
processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 22, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED, 2369850368L);
processImage.setExceptionStatus((byte) 151);
// Add an image listener.
processImage.addListener(new BasicProcessImageListener());
return processImage;
}
}从码D1 (设备)C语言和Arduino IDE:
#include <ESP8266WiFi.h>
const char* ssid = "YOUR-WIFI-NAME";
const char* password = "YOUR-PASS";
int ModbusTCP_port = 502;
//////// Required for Modbus TCP / IP /// Requerido para Modbus TCP/IP /////////
#define maxInputRegister 20
#define maxHoldingRegister 20
#define MB_FC_NONE 0
#define MB_FC_READ_REGISTERS 3 //implemented
#define MB_FC_WRITE_REGISTER 6 //implemented
#define MB_FC_WRITE_MULTIPLE_REGISTERS 16 //implemented
//
// MODBUS Error Codes
//
#define MB_EC_NONE 0
#define MB_EC_ILLEGAL_FUNCTION 1
#define MB_EC_ILLEGAL_DATA_ADDRESS 2
#define MB_EC_ILLEGAL_DATA_VALUE 3
#define MB_EC_SLAVE_DEVICE_FAILURE 4
//
// MODBUS MBAP offsets
//
#define MB_TCP_TID 0
#define MB_TCP_PID 2
#define MB_TCP_LEN 4
#define MB_TCP_UID 6
#define MB_TCP_FUNC 7
#define MB_TCP_REGISTER_START 8
#define MB_TCP_REGISTER_NUMBER 10
byte ByteArray[260];
unsigned int MBHoldingRegister[maxHoldingRegister];
//////////////////////////////////////////////////////////////////////////
WiFiServer MBServer(ModbusTCP_port);
void setup() {
pinMode(14, OUTPUT);
Serial.begin(9600);
delay(100);
WiFi.begin(ssid, password);
delay(100);
Serial.println(".");
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
MBServer.begin();
Serial.println("Connected ");
Serial.print("ESP8266 Slave Modbus TCP/IP ");
Serial.print(WiFi.localIP()); Serial.print(":"); Serial.println(String(ModbusTCP_port));
Serial.println("Modbus TCP/IP Online");
}
void loop() {
// Check if a client has connected // Modbus TCP/IP
WiFiClient client = MBServer.available();
if (!client) { return; }
boolean flagClientConnected = 0;
byte byteFN = MB_FC_NONE;
int Start;
int WordDataLength;
int ByteDataLength;
int MessageLength;
// Modbus TCP/IP
while (client.connected()) {
if(client.available()) {
flagClientConnected = 1;
int i = 0;
while(client.available()) {
ByteArray[i] = client.read();
i++;
}
client.flush();
///// code here --- codigo aqui
///////// Holding Register [0] A [9] = 10 Holding Registers Escritura
///////// Holding Register [0] A [9] = 10 Holding Registers Writing
MBHoldingRegister[0] = random(0,12);
MBHoldingRegister[1] = random(0,12);
MBHoldingRegister[2] = random(0,12);
MBHoldingRegister[3] = random(0,12);
MBHoldingRegister[4] = random(0,12);
MBHoldingRegister[5] = random(0,12);
MBHoldingRegister[6] = random(0,12);
MBHoldingRegister[7] = random(0,12);
MBHoldingRegister[8] = random(0,12);
MBHoldingRegister[9] = random(0,12);
///////// Holding Register [10] A [19] = 10 Holding Registers Lectura
///// Holding Register [10] A [19] = 10 Holding Registers Reading
int Temporal[10];
Temporal[0] = MBHoldingRegister[10];
Temporal[1] = MBHoldingRegister[11];
Temporal[2] = MBHoldingRegister[12];
Temporal[3] = MBHoldingRegister[13];
Temporal[4] = MBHoldingRegister[14];
Temporal[5] = MBHoldingRegister[15];
Temporal[6] = MBHoldingRegister[16];
Temporal[7] = MBHoldingRegister[17];
Temporal[8] = MBHoldingRegister[18];
Temporal[9] = MBHoldingRegister[19];
/// Enable Output 14
digitalWrite(14, MBHoldingRegister[14] );
//// debug
for (int i = 0; i < 10; i++) {
Serial.print("[");
Serial.print(i);
Serial.print("] ");
Serial.print(Temporal[i]);
}
Serial.println("");
//// end code - fin
//// routine Modbus TCP
byteFN = ByteArray[MB_TCP_FUNC];
Start = word(ByteArray[MB_TCP_REGISTER_START],ByteArray[MB_TCP_REGISTER_START+1]);
WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]);
}
// Handle request
switch(byteFN) {
case MB_FC_NONE:
break;
case MB_FC_READ_REGISTERS: // 03 Read Holding Registers
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < WordDataLength; i++) {
ByteArray[ 9 + i * 2] = highByte(MBHoldingRegister[Start + i]);
ByteArray[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]);
}
MessageLength = ByteDataLength + 9;
client.write((const uint8_t *)ByteArray,MessageLength);
byteFN = MB_FC_NONE;
break;
case MB_FC_WRITE_REGISTER: // 06 Write Holding Register
MBHoldingRegister[Start] = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]);
ByteArray[5] = 6; //Number of bytes after this one.
MessageLength = 12;
client.write((const uint8_t *)ByteArray,MessageLength);
byteFN = MB_FC_NONE;
break;
case MB_FC_WRITE_MULTIPLE_REGISTERS: //16 Write Holding Registers
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
for(int i = 0; i < WordDataLength; i++) {
MBHoldingRegister[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]);
}
MessageLength = 12;
client.write((const uint8_t *)ByteArray,MessageLength);
byteFN = MB_FC_NONE;
break;
}
}
}用pyModbusTCP:编写python中的pyModbusTCP客户端代码
#!/usr/bin/env python
from pyModbusTCP.client import ModbusClient
client = ModbusClient(host="192.168.1.105", port=502, auto_open=True, auto_close=True, timeout=10)
data2 = client.write_single_register(14, 1) # FUNCTIE 06 - (Write register) (register=14, data=1)
data = client.read_holding_registers(14, 1) # FUNCTIE 03 - Read register (enkele register) (register=14, length=1)
print ("Data register: ", data[0])
client.close()https://stackoverflow.com/questions/71557133
复制相似问题