You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It appears that the writeRegisters method with the PLC is being interpreted as 16 characters with terms between each character. I'm not sure if this is due to the library or the PLC. Or possibly something to do with the endianness for each character? I can't write to the individual registers because the PLC blocks all registers after the string starts for the duration of the string length.
Any help you can provide would be appreciated.
The text was updated successfully, but these errors were encountered:
After lots of shower thinking, I realized that the issue is due to the PLC packing 2 x 8 bit chars into a single 16 bit register for each register assigned to the string. Because the PLC blocks writing along the length of registers reserved for a string, the only way to get around this is bit packing each value being sent in the array with 2 chars.
if (charCodes.length > maxLength) {
console.warn(`String length exceeds maximum allowed length. Truncating to ${maxLength} characters.`);
charCodes.length = maxLength;
}
while (charCodes.length < maxLength) {
charCodes.push(0);
}
const registerValues = [];
for (let i = 0; i < charCodes.length; i += 2) {
const char1 = charCodes[i + 1] || 0;
const char2 = charCodes[i] || 0;
const value = (char1 << 8) | char2;
registerValues.push(value);
}
try {
await modbusConnection.writeRegisters(regAddress, registerValues);
console.log('Write successful');
} catch (error) {
console.error('Write failed:', error);
}
}
In my packing, I had to switch endianness for my PLC, but if you want it without it swapping the packed chars, it's this:
for (let i = 0; i < charCodes.length; i += 2) {
const char1 = charCodes[i] || 0;
const char2 = charCodes[i + 1] || 0;
const value = (char1 << 8) | char2;
registerValues.push(value);
}
My issue is resolved, but I'll comment and keep this here for you folks to close should you want the code. My suggestion would be to implement a string writing function but don't want to overstep if that would be considered bloat.
Thank you for the issue, and for the work around 💚
It looks like a good example code that may help other users, can you consider adding an example for reading and writing strings to "Schneider m172" to the examples directory ?
PLC: Schneider m172
String length: 32 (31 + null term)
Looking through some of the other issues here, I was able to use your help to pull the string successfully from the PLC. This is the code:
console.log("initial register read:")
let data = await modbusConnection.readHoldingRegisters(regAddress, 16);
console.log(data.buffer)
console.log((data.buffer.swap16().toString('ascii')).replace(/\0/g, ''));
console.log(Array.from(data.buffer))
console.log('Register write:')
const charCodes = Array.from(Buffer.from('abcdefghijklmnop', 'ascii'));
await modbusConnection.writeRegisters(regAddress, charCodes);
console.log(charCodes)
console.log('Second read back')
data = await modbusConnection.readHoldingRegisters(regAddress, 16);
console.log(data.buffer)
console.log((data.buffer.swap16().toString('ascii')).replace(/\0/g, ''));
console.log(Array.from(data.buffer))
The PLC contains the initial string of: "abcdefghijklmnopqrstuvwxyz" to show that it is reading properly.
Output from the code:
[2024-02-15T19:45:00.566Z] initial register read:
[2024-02-15T19:45:00.643Z] <Buffer 62 61 64 63 66 65 68 67 6a 69 6c 6b 6e 6d 70 6f 72 71 74 73 76 75 78 77 7a 00 00 00 00 00 00 00>
[2024-02-15T19:45:00.644Z] abcdefghijklmnopqrstuvwxyz
[2024-02-15T19:45:00.644Z] [
97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 0, 0, 0, 0, 0, 0
]
[2024-02-15T19:45:00.645Z] Register write:
[2024-02-15T19:45:00.739Z] [
97, 98, 99, 100, 101,
102, 103, 104, 105, 106,
107, 108, 109, 110, 111,
112
]
[2024-02-15T19:45:00.740Z] Second read back
[2024-02-15T19:45:00.812Z] <Buffer 00 61 00 62 00 63 00 64 00 65 00 66 00 67 00 68 00 69 00 6a 00 6b 00 6c 00 6d 00 6e 00 6f 00 70>
[2024-02-15T19:45:00.812Z] abcdefghijklmnop
[2024-02-15T19:45:00.813Z] [
97, 0, 98, 0, 99, 0, 100, 0, 101,
0, 102, 0, 103, 0, 104, 0, 105, 0,
106, 0, 107, 0, 108, 0, 109, 0, 110,
0, 111, 0, 112, 0
]
It appears that the writeRegisters method with the PLC is being interpreted as 16 characters with terms between each character. I'm not sure if this is due to the library or the PLC. Or possibly something to do with the endianness for each character? I can't write to the individual registers because the PLC blocks all registers after the string starts for the duration of the string length.
Any help you can provide would be appreciated.
The text was updated successfully, but these errors were encountered: