Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] ModbusTCP 16bit register write - bad function code #1175

Closed
AllmarkPL opened this issue May 2, 2024 · 21 comments
Closed

[BUG] ModbusTCP 16bit register write - bad function code #1175

AllmarkPL opened this issue May 2, 2024 · 21 comments
Labels

Comments

@AllmarkPL
Copy link

Hello,
I'd run into an issue where I can't write values into single 16bit register of modbus device. I have created a single tag with INT16 datatype and proper device addressing, but when I tried to write data into it nothing happended. Quick look into modbus logs has shown that function 16 (multiple registers) is used instead of 06 (single registers) and communication is interrupted due to "bad lenght 8 (expected more than 8)". When I switched Fuxa tag datatype to INT32 all started working, but I can't leave it that way, because device I'm using have 6 consecutive 16bit registers which I got to use... Is there a way to properly send single 16bit register by modbus TCP in Fuxa? I don't think it's issue with the device itself, because I can write data into it using simulator or HMI.

To Reproduce

  1. Create a modbus TCP IP device with single INT16 tag
  2. Try to write any value either due to script action or by input.

Expected behavior
I think it may be a bug in modbus tcp plugin.

Environment

  • FUXA Version 1.1.19-1524
  • latest docker container
  • Platform/OS: Server: Ubuntu; Client: WIN11
  • Browser: Chrome 123.0.6312.86
@rvbatista
Copy link
Contributor

Hello, thanks for your issue.
Are you able to test both conditions with Wireshark capturing the packages?

@AllmarkPL
Copy link
Author

Hello,
as for now I can provide packet data for writing into modbus simulator software, I will have access to physical device on monday.
As You can see on packets below, the function code used for writing is in fact 16, and is lacking second byte in transmission which causes error. First screen is from writing by script, second is from writing by input box. Third is after changing datatype to INT32.
I think, that it was working properly in one of older versions, but I got to verify that.
Writing to INT16 by input box:
image
Writing to INT16 by script:
image
Device dataset:
image
Modbus dump:
image
Writing to INT32 by the same script:
image
Device datset:
image

@unocelli
Copy link
Member

unocelli commented May 7, 2024

Hi, have you try to update modbus-serial to 8.0.16?

@rvbatista
Copy link
Contributor

What are your modbus server? The reading is working? The usage of write multiple registers is in fact bad for efficiency, but it should work if your server have it implemented.

@AllmarkPL
Copy link
Author

Hello,
reading works without problem and writing 32 bit registers and booleans is working fine, also this error (FC16 used instead of FC06 when trying to write single INT16) appears on multiple devices and simulators I've tested. I will try to check modbus-serial version, because now I can confirm that this is case on version which is included in latest docker container (I don't have access to server now, but will check later and also test on modbus-serial 8.0.9 which I have on another server).

@rvbatista
Copy link
Contributor

The usage of FC16 instead of FC06 is in fact I'm the logic, today Fuxa will never use FC06. You know this is not exactly an error, since you can use FC16 to write only one register, but I trying to figure out why you are having an error in this case.

@unocelli
Copy link
Member

Hi, I added the possibility to set a frame delay that maybe can help (in master branch), would be nice to try and give me feedback

@AllmarkPL
Copy link
Author

Hello, thank You for reply. I tested it (tried several delay values from 10 ms to 2000 ms) just now, but it don't fix the issue - still the same error ("bad lenght 8, expected more than 8"). I had worked around it using OpenPLC on server and some DINT to INT processing, because I had to move forward with the project. I got to make it that way, because device which I'm working with had scrict registers addresing (separate memory part for 16 bit HR for setting and setpoints for which it will only accept FC06 modbus command separate and 32 bit memory registers for process settings).

@andy8601
Copy link

andy8601 commented Aug 1, 2024

Is it true that some devices do not support the 16 function and can only accept the 06 write function? I have no problem writing registers with modscan32, but FUXA has the same problem, I am not sure if the old version has this problem, 8.0.9 have you tested it? Can you share the script written in 06?
@AllmarkPL

@andy8601
Copy link

andy8601 commented Aug 1, 2024

I have tested many previous docker versions, and the previous modbus version also has this problem. Some devices indeed only support 06 function codes and do not accept 16 function codes. Now I don't know if there is any other way to solve this problem, I hope you can get help.

@andy8601
Copy link

andy8601 commented Aug 2, 2024

const net = require("net");

// 目标服务器的 IP 地址和端口
const HOST = "192.168.5.22";
const PORT = 502;

// 要发送的数据
const DATA = Buffer.from([0x0A, 0x1D, 0x00, 0x00, 0x00, 0x06, 0x02, 0x06, 0x00, 0x00, 0x0C, 0x1C]);

// 创建一个新的 TCP 套接字
const client = new net.Socket();

// 连接到目标服务器
client.connect(PORT, HOST, function() {
    console.log("Connected to server");
    client.write(DATA);
    console.log("Data sent:", DATA);
});

// 处理服务器响应的数据
client.on("data", function(data) {
    console.log("Received data from server:", data);
    client.destroy(); // 在接收到响应后关闭连接
});

// 处理连接关闭事件
client.on("close", function() {
    console.log("Connection closed");
});

// 处理错误事件
client.on("error", function(err) {
    console.error("Error:", err);
});

@unocelli
Copy link
Member

Hi, fuxa uses the modbus-serial library, try investigating whether the library has a the describe issue

@andy8601
Copy link

andy8601 commented Sep 5, 2024

Thank you for your reply, this problem has always been, I looked at the modbus - serial library (https://github.com/yaacov/node-modbus-serial), I think the problem on FUXA call, although I don't know much about, But I think there should be a call option like the following to choose whether to use the 06 function code or the 16 function code.
1725512251474

嗨,fuxa 使用 modbus-serial 库,请尝试调查该库是否存在 describe 问题

rvbatista added a commit to rvbatista/FUXA that referenced this issue Sep 9, 2024
@rvbatista
Copy link
Contributor

rvbatista commented Sep 9, 2024

Create a new PR, I already know how to solve it, but was not able to test.

} else if (memoryAddress === ModbusMemoryAddress.HoldingRegisters) { // Holding Registers (Read/Write 400001-465535) if (value.length > 1){ // <<<< greater than 2 for bytes and 1 for words. client.writeRegisters(start, value).then(res => {

unocelli added a commit that referenced this issue Sep 12, 2024
@unocelli
Copy link
Member

Thanks @rvbatista PR should be solved.
@AllmarkPL @andy8601 can you confirm?

@haslish
Copy link

haslish commented Sep 13, 2024

@unocelli
I tried with a device that doesnt support function code 16 and it works now.

@rvbatista
Copy link
Contributor

@haslish please, try a 0xf0f0 (61680) value also.

@haslish
Copy link

haslish commented Sep 14, 2024

I get "_writeMemory error! Error: Modbus exception 3: Illegal data value (value cannot be written to this register)". But its because the server doesnt have a big range in values it accepts. 6000 was the biggest value I could test.

@rvbatista
Copy link
Contributor

6000 is ok, it use both bytes. I believe that everything is ok.
Thank you.

@unocelli
Copy link
Member

I’m going to close this as resolved. let me know if you have any issues.

@faywong
Copy link

faywong commented Nov 21, 2024

Why need to limit the modbus register address range?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants