Objective: Control and communicate with Sure Servo VFD (Automation Direct) to eventually control a motor.
Protocol: MODBUS RTU (RS 485)
Problem: I did a very basic vi to see if LabVIEW is communicating with the VFD. I am trying to read data off a register, to see what data it is holding (firmware version). I'm trying to do this for self learning and eventually apply this to a project I'm working on. I downloaded the MODBUS API and I; not familiar with using these blocks. I'm attaching the basic VI and the spec sheet for the VFD. The VFD uses Hex addresses, and I'm not sure how to read and write data off and into it.
The VFD manual has a set of hex commands (i suppose) that can be send to the VFD to perform control. I want to know how i can send these commands using MODBUS API blocks. If there are other alternatives i can try that too. Seems like the VISA read/write blocks cannot be used in conjunction with MODBUS blocks.
The VI i probably have right now could be utterly wrong, so I'm looking forward to any feedback and recommendations. I have attached the basic VI, VFD manuall and screenshot of hex commands (i think).
1)How do you decided the number of <<Write Single Holding Register>>?
2)The address and input data for each one of them?
I don't know what the original poster ended up doing, but the general answer to this is: "read the documentation of the device, as that's what defines this".
In the example posted by the OP, assuming I understand it correctly, you can read the firmware version from holding registers 1 and 2 (the 4 at the beginning indicates that this is a holding register) and that the data will be encoded as "dec" (I'm assuming that's decimal and that it means a simple integer) and will be 16 bits in size. This actually doesn't make sense, as each holding register holds 16 bits and you have two here, so it should be 32 bits, but this entirely depends on the device and its documentation.
In this case, I'm assuming you're not supposed to write that specific holding register and the device probably ignores writes to it. You would decide which registers to write to based on the things that the device expects and the things that you actually want to change.
Also, note that in general you would probably be better off using a single write multiple holding registers call, as that would be more efficient in terms of the amount of data you have to pass and your communication rate. This would depend on things like how often you want to actually make the calls, how close the registers you want to change are to each other, etc., but that's already an optimization.
Firstly, thank you for helping out with my question. I want to make a correction, I haven't been able to set any any sort of communication with the VFD yet. I was trying to read the firmware version as a start to the whole project. I understand the register that has the firmware version details is a read only register. I was basically just trying to read the version from the register. To do that I am assuming I would need a command or a pointer to the register.
My actual question is: How do I send commands or read write data from register of the VFD, as i am using the MODBUS API blocks? I am still a beginner for this matter, so kindly bare with my ignorance, I am in the process of learning. I have used serial VISA functions to read and write, but seems like I cant use a VISA read or write with the MODBUS API blocks. The data sheet i have attached with the OP has the commands for the functions that i wanted to use.
Sorry I don't have LabVIEW on this computer so I can't look at your code, but if you're doing RTU, I'm assuming it's a serial connection to the VFD. Check your manual for the serial configuration needed to communicate to the device (e.g., baud rate, flow control, etc.), as well as the Modbus device ID (usually it's 1, but verify in the manual). Once you have all that information, you can use the code found in this post, but modified with your settings and address.
The register you're going to read is 40001, which is a holding register (denoted by the 40xxx address). From the image you posted, it looks like the manufacturer has added an offset of 1 to all register values -- i.e., 0x0000 is 0, but they've associated that with 40001 and 0x0001 is 1, but they've associated that with 40002. That's a relatively common practice.
Your other picture that has the digital inputs looks like it is probably a Modbus Coil. Those do not have the 40xxx nomenclature, so their actual value will just be the decimal version of the hex associated with that register. i.e., 0x01 should correspond to coil address 1. The LabVIEW Modbus library has Read Coil functions you can use for this particular data. Using the Read Holding Registers won't work for coil data.
Thanks a lot for this insight. Gives me something to start learning and working on working on. I have figured the baud rate and flow control for the device but I haven't figured the MODBUS device ID, but i will find it. What you said makes sense now, i was trying to read coil data by using read holding register function. I will rework the VI and see if its working. But thanks again for understanding the my questions and helping me out here.
I tried tried making a vi with what you recommended, but i am still not able to communicate with the servo drive. I found out the configuration settings (device ID and transmission speed). I am attaching the snip of the VI I did based on your feedback. I think i am missing something basic.
I found that the device !D is by default 0x7F which is a decimal 127. And the transmission speed is @ 38400.
Do you think I am missing a driver software or anything of that sort? The servo driver didn't have any driver software along with it, it just had a toolkit software which allows to see and edit parameters.
Also i noticed that the MODBUS block icon colors in the example you shared and that of mine are different. Do you think if I am using the correct blocks even? Like i mentioned before i am pretty new to this stuff, so please bare with my ignorance
When you say you can't communicate with the servo drive, what do you mean? It's throwing a connection error or it's just returning 0 from the register you're reading? The Modbus library I use comes with LVRT or maybe with the DSC module or something, but I'd imagine they're all the same when it comes to reading basic register values.
Can you put an error indicator on the Modbus Close so we can see what it says? Also, what is the name of your Read VI? Is it Read Holding Registers or Read Coil or something else? It also looks like you've requested that it read register 0, which isn't valid -- if you're attempting to read a Holding Register I would recommend reading register 40769 just to confirm it works, which should return a U16 value of 127 according to that snippet of the manual you posted.
Hi @ DHerron
No its not throwing any connection errors at all. The servo drive has RJ45 connector port that enables RS485 comm. I am using a RJ45 ethernet cable to an RS485 adapter (i have the wires cross wired for DTE to DTE comm).
The front panel is just blank and all i see is this register showing 0. I tried using a error indicator but its not showing anything either. I am using 'Read Holding Registers' for the read
Okay, try changing the number of registers to read to 2 and typecast the array to an I16 (currently a DBL in your diagram). I did think it was strange they said that value was 16-bit but listed two registers. Maybe it's a signed integer?