10-13-2011 02:23 PM
Hello,
I'm having trouble getting started with this problem:
I have 20 motors, each needs to run a specific PWM profile. These profiles come as CSV files that have two columns, Time and %PWM. My code will parse the file and make the motors follow the profiles, changing the PWM with respect to the time. All of these motors share one serial connection, so I can never send a command to more than one motor at a time. The fastest my PWM will change is 100mS.
I'm not sure how to approach this, there's basically 2 problems: 1. keeping accurate timing for 20 devices and 2. executing the commands serially (even though the CSV file might imply simultaneous commands i.e.. 2 motors following the same profile)
a couple approaches I've thought of
1. Make 20 timed while loops, and adjust the period of each timed while loop iteration according to the time on the CSV file. Have all of the timed while loop output serial commands to a queue, then send the queue to another independent while loop that will carry out the commands as fast as possible.
2. Make 1 timed while loop with say a 20mS period, and in that have 20 timers with the timing set by the CSV files. When a timer goes off it will add a PWM command to a queue and that queue will be sent to another loop that executes the command...
I feel kinda funny about using 20 timed while loops.... maybe there's nothing wrong with that... I don't know. But I like the timed while loops because they seem very accurate and don't miss timing, I'm pretty sure a queue is the way to go to keep my commands happening as close to the profiles as possible (even when profiles overlap) can anyone suggest any approaches to this or comment on the two I'm considering?
much thanks!
10-13-2011 02:27 PM
I would use your first method but I would use a subVI and dynamically invoke 20 instances with the appropriate timing values. This method is more flexible than simply creating 20 parallel loops. Using this method you can programmatically support any number of motors without having to change your code.
10-13-2011 02:38 PM
Hi Mark, thanks for the reply, what do you mean by "20 instances"..... 20 instances of what? Timed While Loops? the number of motors is hard set, there will not be any more added, do you think I should just go with the 20 parallel loops? (I'm assuming all I'm gaining for dynamicall invoking the loops is flexability to add more in the future)
thanks
10-13-2011 02:43 PM
Create a single subVI which is reentrant. During your initialization determine how many motors are in your system (read from a file, prompt the user, get it from a database) and then use a for loop to spawn "N" number of instances of the subVI. (Look at the examples for calling VIs dynamically). You will not want to wait until the subVI completes. This will create 20 "N" copies of the VI running. Each will run independently. When you start the VI you will need to pass the appropriate parameters to it such as it's timing profile, the address/port of the specific motor, etc. Each of these can post the next message to send to your message queue. Your application will have another parallel task waiting on this queue which will actually send the command over the serial port.
10-13-2011 03:03 PM
I'm not seeing why I should dynamically create these SubVI instances, instead of just hard coding 20 of them from the begging. Are the SubVI's while loops? Essentially the 20 SubVI instances are the 20 timed while loops I was describing, is this right?
thanks
10-13-2011 03:29 PM
There really is no difference in functionality. It would make prettier looking code by having one for-loop instead of 20 while loops. But the biggest advantage is (as was stated before) dynamic addition/subtraction of the # of motors controlled. It makes the code more versatile and able to be reused for another instance.
10-13-2011 03:48 PM
@Fibo wrote:
I'm not seeing why I should dynamically create these SubVI instances, instead of just hard coding 20 of them from the begging. Are the SubVI's while loops? Essentially the 20 SubVI instances are the 20 timed while loops I was describing, is this right?
thanks
The subVI would have a loop in it and it would run continually in the background. You need some global method to stop all the running VIs such as a notifier or user event. The reason I suggested this approach is what happens a few months from now if they ask you to add two more motors. If you simply hardcode the loops you will have to edit the code to add the new motors. My approach you simply input that the count is 22 rather than 20 and away you go. No need to modify your code.