02-05-2021 07:39 AM
Hello,
Even though I've done Modbus in many different variants earlier, it still can give me some issues it seems.
I have my computer connected to a custom instrument by RS232, and want to communicate with it using Modbus Serial Ascii.
I start by opening ModScan64 (external application) to test the connection, it works fine, and I'm reading good data:
In the above screenshot, all relevant information should be visible.
Next is doing this in LabVIEW. I make a very simple test.vi to do this, but I'm getting an error:
The error message pops up at once, and doesn't wait the 2000 ms that I read on the property node.
Source code here (and attached just in case):
("Read holding registers.vi" inside the while loop)
Does anyone of you see anything I can try? Thank you for having a look!
Best
Oksavik
Solved! Go to Solution.
02-05-2021 09:07 AM
Your starting address is wrong.
Although the modbus protocol describes holding registers as starting with a 4 and begin counting at register 1, the underlying data in the message packet and how LabVIEW and some other modbus programs will call the is 0-based. So for a starting address of 400001, drop the 0, subtract 1. You want to wire a 0 to the starting address.
I'm surprised you got an error of 56 for this rather than an invalid address error.
02-06-2021 08:34 AM
Hello, and thank you for your reply.
You are correct that the starting address was wrong, but unfortunately changing the address to zero did not resolve my problem. I still get the same timeout message.
Under you can see the revised code. I only tried reading two registers now.
I also inserted the "Set timeouts.vi", and set the timeout to 5000ms, now the code waits for 5 sec before throwing the error 56.
02-06-2021
11:01 AM
- last edited on
04-07-2025
12:15 PM
by
Content Cleaner
Try using an older LabVIEW modbus library. https://forums.ni.com/t5/Reference-Design-Content/LabVIEW-Modbus-API/ta-p/3524019
In theory, it should work the same, but the advantage is that the subVI's are fully open allowing you to drill down and see what the messages look like. You could try using a serial port sniffer program on your working application and see what differences there may be between the messages being sent.
It looks like all of your serial port settings match between the application and your LabVIEW program, so it is unlikely to be that.
02-06-2021 12:19 PM
Well here I am thinking I know Modbus in and out. Figured the ascii would be just as easy as RTU, but digging into it the formatting of things gets weird. I also happen to have access to the NI Modbus library and peeked into the code there and I'm not convinced the LRC check is being done correctly for Modbus ascii.
Using this as a reference I put together a simple VI that should build a Modbus ascii command. However I am still not sure what the port settings should be. I believe modbus ascii uses 7 data bits and there is parity, but I am not sure which one is correct so you may have to try different settings.
I think this should be a good test program because you can look at the raw data coming back. The NI Modbus library looks specifically for a carriage return AND a line feed and a lot of devices may only return one of those so that may warrant some looking at as well.
02-06-2021
12:20 PM
- last edited on
04-07-2025
12:17 PM
by
Content Cleaner
I have a "serial tap" device, so I can try a sniffer program. Not sure if I'm able to decipher and understand it, but I can maybe post it here?
I will also try a different modbus library, do you have experience with "Modbus Master by Plasmionique" ?
https://www.ni.com/en/support/downloads/tools-network/download.modbus-master.html
Could it somehow be related to wire mode? (DTE vs DCE)
https://www.ni.com/docs/en-US/bundle/ni-compactrio/page/rs232-dte-versus-dce.html
I also have a NI Usb RS232 adapter, that I have not tried yet. In the end this will be connected to the RS232-port of a small UNO-computer from Advantech. But if the NI USB adapter can give us any clues I will test it. Maybe it gives some more information in MAX?
I also tried the program "Modbus poll", which I've seen referenced in some posts here, and it also worked (not surprising I guess).
I can see you (RavensFan) have answered questions about Modbus for the past 10 years (at least) on this forum, so I'm grateful for helping me and so many others.
02-06-2021 12:33 PM
Hello StevenD, and thank you for joining the conversation.
I quickly compiled an application with your test program, and tested it. First result, with data bits 7, and even parity was not a success:
But then I changed to 8 and none, and it did not return an error:
What does this successful test tell us?
You mention that the LRC check might be wrong for the " NI Modbus library", is that the new version that I'm using?
Thank you.
02-06-2021 02:36 PM
It looks like you are getting valid data. I played around with the string in your picture and could (mostly) make sense of it. I have not used another Modbus library.
I looked more into the NI Modbus library and from what I can tell it seems like it just won't work with Modbus ascii. I think the library converts the human readable ascii to binary before being sent to the port which I don't think should happen with ascii. The conversion from ascii to hex/binary should be done in the visa write IMO.
Here's how I think the response should be parsed, make sure the data starts with ":" and ends with "\r\n", two characters for station ID, two characters for function, two characters for the length of the data message, the data message, and then two characters for the LRC.
I could get data from your example and if I converted the first register to a float I got 1536 which seems like it might make sense??? Not sure what a real value should look like.
Here's what I tried
02-07-2021 01:08 PM - edited 02-07-2021 01:11 PM
In Modscan I use Floating Point - Least significant register first. The two first registers then gives me the station number "1539", which is correct.
When I join the two registers that you read (17600 and 24576) I get the correct value:
Well done, it seems like you have managed to help me read, and parse data correctly.
Still I would prefer to use the Modbus library, and understand why it doesn't work for me.
It's hard for me to understand that the official Modbus Library from NI does not work with Modbus ascii.
You'd've thought that this would be found out a long time ago, right?
02-07-2021 02:14 PM - edited 02-07-2021 02:15 PM
Did you try the other library I posted yet?
I don't recommend using the built-in Modbus Init. Just use a regular Serial Configure and set your communication parameters that way. The reason is that the Modbus Init in the "white" library makes assumptions. It assumes that you want 7 data bits 1 stop bit for ASCII. I've had devices that wanted 7 data 2 stop. And in your case, it seems you want 8 data and 1 stop. Or 8 data and 2 stop for a Modbus RTU device.
It is hard to know what is going on in the purple library as when you get a little deeper, the subVI's are locked. But I can only assume that the purple library is making the same assumptions as the "white" library's Modbus Init.
Although the white library is older, I've used it since that was the only choice, trust it, and know it's flaws to work around it. Plus it is fully open so you can modify it if you need to.
It actually makes sense somewhat that Modbus serial ASCII would be 7 data bits. It is a protocol that takes twice as many bytes, but the raw bytes are all transmitted as hexadecimal characters that would fit within the 7-bit ASCII table (value 0-127 decimal). Probably so that the data could flow through some ancient serial equipment. I don't know if ASCII Modbus devices are required to be designed with a 7 data bit protocol, if so, you can see that devices such as yours were designed for 8 data bits even if they are Modbus ASCII.
In summary, my recommendation is to use the library I linked to, don't use the Modbus Init, and define your own serial parameters with the regular VISA Configure Serial Port subVI. When I set up a test (but I don't have your equipment) I could see that the string it transmitted matched the working string in your Message #9, including the LRC value of "FA".