10-21-2021 03:41 AM
Hello everyone,
I made VI that is controlling servomotor - it is sending commands (by Modbus protocol) with position (rotation) of shaft: e.g. when I put "1141" it is 0.1141 of full rotation of shaft and so on.
The idea is that I have this position of full sequence divided into certain parts (now I have 66 parts, but it could be 43 or 72 or any other number). Full sequence should be realised in 2 seconds - so my motor should change his position 66 times during 2 seconds.
I have while loop that is realizing this task, by taking subsequent values from array and sending them to motor. But it is not working properly - motor is moving quite slowly (one move in one second), and after few (7-8) position changes is stopping.
Something in my VI is wrong - data is changing too fast? Computer is not managing with so many changes in short time?
Could you help me? 🙂
Best regards!
10-21-2021 03:59 AM
10-21-2021 04:12 AM
Hi,
in addition to altenbach's remarks:
Regards, Jens
10-21-2021 08:38 AM
Do you have a manual for this servo? The hoops you are jumping through make very little sense. You typically do not see a checksum with an ASCII formatted communication protocol.
11-02-2021 06:30 AM
Hello everyone, thanks a lot for your responses. I will try to do my best to answer your questions and explanate my problem.
@altenbach wrote:
- Your while loop should be replaced by a FOR loop, autoindexing on your array..
Thanks, I have done it.
@altenbach wrote:
- Where do you initialize the serial port?
I done it in another VI (my VI was in fact subVI of another VI), but I have transferred it now to this VI to make things clear.
@altenbach wrote:
- Why don't you define a reasonable loop rate? You seem to know what rate you want.
Changing waiting time is not correcting anything in my case... Servo is still not managing with this commands from VI.
@altenbach wrote:
- None of your inner FOR loops are needed.
Thanks, I deleted them.
@altenbach wrote:
- Why is the front panel and diagram maximized to the screen? Annoying!
I have week eyesight 😉
@altenbach wrote:
- Most (all) of your control terminals should be outside the loop because they should not change once the program has started.
Thanks, I have done it.
@JensG69 wrote:
- that is not modbus
So... What is it?
@JensG69 wrote:
- is your answer really always long as the command? Otherwise the read-command could take longer - waiting for a time-out.
I am afraid that I don't understand question...
@crossrulz wrote:
Do you have a manual for this servo? The hoops you are jumping through make very little sense. You typically do not see a checksum with an ASCII formatted communication protocol.
This is manual: https://www.estuneurope.eu/wp-content/uploads/download/Manuali/Azionamenti/ProNet-User-s-Manual-V2-1...
I made new VI using your tips - but the problem is still the same. I am attaching my new VI.
Best regards!
11-02-2021 09:55 AM - edited 11-02-2021 09:58 AM
Have you ever checked the answer given by the device? It may return an error instead of the echoed command you are expecting.
Wire a large number (say 100) to the byte count of the VISA Read function; due to the termination character management, the read will return as soon as the LF is received.
That said, you are quite near to the limit of the protocol possibilities. For each command, you send 17 characters and expect other 17. Given the serial settings, this means 34*11=374 bits (1 bit start, 8 for the character, 1 for parity, 1 for stop). In two seconds, you can transmit/receive 19200*2 bits, so there is time enough for 38400/374 = 102 queries. But this number is based only on the transmission time, so it's far from realistic. You must allow for the time needed for the device to dispatch, interpret, execute the command and build the answer, so you can bet the actual limit is significantly lower.
EDIT: there is a free NI library for MODBUS, see here for a link.
11-02-2021 12:05 PM
Are you sure your system architecture is correct? Why do you want to send 66 positions in 2000 ms? Is this just to have a smooth movement? 30 ms loop rate in Windows can easily end up being quite unprecise. BTW in version 2 you have wait 1000 ms, so loop time will be in any case at least 1000 ms, so movement will happen in 66 s.
If I'm correct, you could try setting the movement speed on the servo controller to suitable value and just send one move command from LV.
If you really want to continue finding out why your current solution does not work, I suggest the following actions. Set the wait to 30ms and measure the real loop interval for each iteration. Also as someone else mentioned, you should check what the controller reply contains. Maybe it's still busy or something when you send the next command. This is something that should be relatively easy to find in the manual.
11-03-2021 05:09 AM
@pincpanter wrote:
Have you ever checked the answer given by the device? It may return an error instead of the echoed command you are expecting.
Wire a large number (say 100) to the byte count of the VISA Read function; due to the termination character management, the read will return as soon as the LF is received.
I have done it and nothing really changed...
@pincpanter wrote:
For each command, you send 17 characters and expect other 17.
Why 17? I do not know how you are counting it...
@pincpanter wrote:
so there is time enough for 38400/374 = 102 queries. But this number is based only on the transmission time, so it's far from realistic. You must allow for the time needed for the device to dispatch, interpret, execute the command and build the answer, so you can bet the actual limit is significantly lower.
Yes, that is why I have 66 queries! It should be sufficient number I suppose.
@Jamosgee wrote:
Are you sure your system architecture is correct? Why do you want to send 66 positions in 2000 ms? Is this just to have a smooth movement?
Yes, exactly. As pincpanter counted, 66 positions should be ok.
@Jamosgee wrote:
BTW in version 2 you have wait 1000 ms, so loop time will be in any case at least 1000 ms, so movement will happen in 66 s.
I have changed it just for my knowledge to check if servodriver is working properly in such time step - and it is.
@Jamosgee wrote:
If I'm correct, you could try setting the movement speed on the servo controller to suitable value and just send one move command from LV.
Yes, I was thinking about it. But my first idea was such: if I set time step 30 ms and I am changing positions during this time, the loop will naturally execute my command with speed I want: x/30 ms, later y/30 ms and so on. But maybe idea wasn't good and I have to send also another command with speed?
@Jamosgee wrote:
Set the wait to 30ms and measure the real loop interval for each iteration
How can I do it?
@Jamosgee wrote:
Maybe it's still busy or something when you send the next command.
I think so! It is definitely still busy. But how to fix it? I don't have any idea. Manual of servo is not really helpful regarding this matter...
11-03-2021 05:21 AM
If you don't know how to measure execution time of a for/while loop, I'd highly recommend to study LabVIEW basics a little bit. Maybe do an online course for beginners or something.
Regarding the servo status and errors. I'm sure the answers are the manual, you just have to read it.
11-03-2021 05:44 AM - edited 11-03-2021 06:26 AM
@jeandebrem ha scritto:
@pincpanter wrote:
Have you ever checked the answer given by the device? It may return an error instead of the echoed command you are expecting.
Wire a large number (say 100) to the byte count of the VISA Read function; due to the termination character management, the read will return as soon as the LF is received.
I have done it and nothing really changed...
What's important is to check the device answer: do you receive the command echo or not?
@pincpanter wrote:
For each command, you send 17 characters and expect other 17.
Why 17? I do not know how you are counting it...
The command you send is :00060259017D21\r\n . You can count manually. Or use String Length from the String palette.
@pincpanter wrote:
so there is time enough for 38400/374 = 102 queries. But this number is based only on the transmission time, so it's far from realistic. You must allow for the time needed for the device to dispatch, interpret, execute the command and build the answer, so you can bet the actual limit is significantly lower.
Yes, that is why I have 66 queries! It should be sufficient number I suppose.
All suppositions must be validated. Since it's not working, I guess it's not sufficient.
@Jamosgee wrote:
Are you sure your system architecture is correct? Why do you want to send 66 positions in 2000 ms? Is this just to have a smooth movement?
Yes, exactly. As pincpanter counted, 66 positions should be ok.
This is not true. In fact, I said that the actual limit must be (much) lower than 102.
@Jamosgee wrote:
BTW in version 2 you have wait 1000 ms, so loop time will be in any case at least 1000 ms, so movement will happen in 66 s.
I have changed it just for my knowledge to check if servodriver is working properly in such time step - and it is.
So you tried with a 1 s delay and it works? You didn't mention this before. You should share with us those important information.
This is enough to prove that the device cannot keep up. You need to use another method. I could not suggest one, since I don't know in detail how the device works.
@Jamosgee wrote:
Set the wait to 30ms and measure the real loop interval for each iteration
How can I do it?
As Jamosgee already pointed out, this is a very basic task. Suggestion: consider the Tick Count (ms) function in the Timing palette.
You need to get the Tick Count just before sending the command and just after receiving the answer, then subtract the second from the first. Doing this, take into account LabVIEW's dataflow! The result will you give a hint on the maximum rate you can actually reach.