首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pyModbusTCP PC机到PC机连接

pyModbusTCP PC机到PC机连接
EN

Stack Overflow用户
提问于 2022-03-21 11:48:16
回答 1查看 582关注 0票数 1

我正试图用pyModbusTCP将两台pcs连接在一起。当我在本地使用本地主机运行客户机和服务器时,它工作得很好。

当我尝试在单独的PC上运行它们时,客户端需要一段时间才能“连接”,然后将寄存器读入“无”。我已经为服务器设置了一个静态IP地址为192.254.100.101,并且可以在另一台PC上使用终端来平分它。我在客户端也有一个静态IP地址,为192.254.100.102。

客户代码:

代码语言:javascript
复制
    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")

服务器代码:

代码语言:javascript
复制
    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()
EN

回答 1

Stack Overflow用户

发布于 2022-09-04 05:05:44

.i.e:

您有一个Raspberry pi,静态IP地址为"192.254.100.101“,一些设备连接到它,然后当您向它发送请求时,您也将声明从id号,这里您请求一个数据寄存器。

现在,在服务器应用程序中,您将使用发送方数据包IP地址返回答案。

使用Wireshark和您的本地网络来理解。

java语言中使用Modbus4J代码

代码语言:javascript
复制
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中使用:的从代码

代码语言:javascript
复制
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:

代码语言:javascript
复制
#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客户端代码

代码语言:javascript
复制
#!/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()

Modbus协议规范

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71557133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档