Digital I/O

Showing results for 
Search instead for 
Did you mean: 

cRio with 9401 and PWM over 10 Hz

This question/problem is along the lines of this one:


I have a cRio 9073 with the 9401 module.  I have a stepper motor amplifier that is looking for a pulsed input, and the speed of the pulses dictate the motor speed.


According to the spec sheet for the motor amplifier, it can handle upto 40 kHz signals.


Using the 'Simple PWM IO' example, I am able to get to the motor to spin at 10 steps per second/respond to a 10 Hz input.  If I go faster (meaning 10+ Hz), the system seems to choke.  What's strange is that it seems that the cRio is what starts to have problems, since using an LED or waveform output, just to see what is happening, starts to degrade, i.e., the output starts to become inconsistent.


In the above link, there was a suggestion of changing the timer.  I tried this, and it did not work.  It could be that I set it up incorrectly.


I am able to adjust the frequency with a knob on the front panel, and it follows pretty well with my command.  I am not so concerned with that.  10 Hz is fast enough for what I am doing, but really it is the principle of the thing:  I should be able to go faster.



On a separate note, I tried to setup the PWM timing routine through the FPGA wizard. I am not able to (it is greyed out).  Is the ability to use the PWM timing tied to a module, or software?


Since all I really want to do is have a DO turn on and off at a specified speed, is there something better to use?

0 Kudos
Message 1 of 9
Have you been able to verify that the module does not output above 10 Hz using seperate hardware?  It would be good to verify that the problem is definitely on the cRIO end.  Also, have you made any changes to the example program?  If so could you post your code?
0 Kudos
Message 2 of 9

At the time of opening this question I had not connected a scope.  Today I have. I should also mention I inherited the code, so some of the particulars I may not know the answer.


Attached is a picture of the scope's screen with a 50 ms cRio/9401 output, a jpeg of the PWM generator, and the host vi.


The output of the PWM generator is sent to a local variable, then output through the 9401.


Something I am not clear on, again, I inherited the base code, the host code is what is ran on the pc, correct?  The PC is very fast, but I am wondering if the ethernet connection is the culprit. 


Per my understanding, the host code is generating the output for the cRio and sending it across the the network cable (they are directly connected).  Is this the problem?



Download All
0 Kudos
Message 3 of 9

Out of curiosity, I ran the same PWM generator on the host computer, which has a PCI-6221 installed.  I am able to get to a time of 30 ms before it starts to do the same thing, essentially 3 times as fast.  Again, this was viewed through the scope.


It ends up that we may need 4-8 more digital outs.  If this is some how connected to the 9401, is there a better one to use?


In looking through the site, I found this:


I do not have this option.  When I go to properties, all I am able to see is Module Configuration.


I found on the site that there is a timing loop for the cRio that is specifically for PWM.  I can't choose that either.  Is there a software package I am missing?
0 Kudos
Message 4 of 9

So after looking at your oscilloscope reading it appears that the software is outputting pulses of 50 ms.  Its just not doing so very reliably.  I looked at your host code and there are a lot of things that I am confused about.  First of all, is this code being run under the 'My Computer' target, or under the 'cRIO' target?  If its being run on the cRIO, than the ethernet cable will have nothing to do with the problem (not that I think this could be the problem anyways). 


In either case, most of your while loops do not have any wait functions in them.  This could cause one of your loops to "starve" and not execute properly.  Also, your PWM algorithm is kind of strange.  Essentially you are ensuring that you have a 66% duty cycle (or that your high time is twice as long as your low time).  Is there any reason why you are coding this this way?  Also, you have not provided your FPGA code so I cannot fully understand how this output is being generated. 


At this point I would recommend opening the PWM Out, Simple -cRIO project example in the example finder.  This example generates the PWM signal solely on the FPGA and allows you to enter in precise high an low times.  Try this example and see if you get different behavior.  If so, you might want to revisit your Host program and supply high and low times to the FPGA instead of actual boolean values.  This architecture makes even more sense if you are planning on adding additional channels.  This could very well resolve this issue for you.  Hope this helps!

0 Kudos
Message 5 of 9

The code that I sent is being ran on the host, not the cRio.  The person that set the system up did this.  Attached is the current FPGA vi.  Per my understanding, it is the very basic code that is generated from running the FPGA wizard.  It contains two Single-Point Continous Timing Engines.


The PWM generator that I am using is a 'mutated' version of the PWM Out, Simple example.  It is being executed on the host.  When I tried to copy it (not the example) to the cRio, it gave me errors accosiated with everything in the loop.  I will try to copy the example to the cRio and see if it will run it.


The changes I made to the example I thought were minor.  All I need to do is be able to vary the number of pulses per second.  The on/off time is not important, in the strictest sense.  The amplifier I am feeding into can handle up to 1 kHz per channel.  Ultimately the code that works will be duplicated to drive 4 motors, but not in a coordinated motion.  I would like to do coordinated motion, but it is not needed in this application. 


The PWM generator code I uploaded is not the exact code that I am trying to run.  The true code is taking a desired linear velocity and calculating the timing required.  For example, for a velocity of 0.127 mm/s = 100 ms.  I take 100 ms and divide it by 2 to give a 50% duty cycle.  I do not want the user to adjust this number, and until I hit 100 ms/10 Hz, it works perfectly.  See the attached picture of the output at 100 ms/10 Hz.  This was generated with the 'true code' ran on the host.  Currently, there is a number that is added when I send a pulse, which tells me 'where' I am.  When this number is equal or greater to a desired displacement I kill the motor.  This works on the host just fine, until I try to go faster than 100 ms/10 Hz.


The original version of the code ran the example code exactly how it is in the example folder, with the exception of having the output connected to a shared variable, which was sent to the digital output on the 9401.  If you look at the vi, you will see the variable.  It has the exact same problem.


In looking, I found a paper that they ran into the same problem.  They were able to get to 87 ms, but below that things went south.  Their assumption is that the networking overhead eats up 50 ms.  This makes sense because it seems that there is a buffer overrun somewhere.


 Is there a way to setup the cRio so that it runs the timing loop, the host sends the variables for it to react to?  In other words, the host sends the time and the cRio sends back the distance so that the operators knows where the slide is?



Download All
0 Kudos
Message 6 of 9



So a couple of things.  First of all, the code that you have posted is not really a muted version of the example program I mentioned.  The two programs generate the PWM signal in two completely different ways.  Your program generates the signal on the host (which can be very slow), and the example generates the pulse on the FPGA (which can be extremely fast).  In order to specify the speed of the output for the example program on the host, you will simply need to write new values to the controls using the read/write control.  Just to make sure that we are talking about the same example, I am including the VI.  There is only an FPGA VI for this example so you will have to add the rest (or simply run the FPGA VI and make sure that it works).


As for getting your distance information, you can have the FPGA keep track of how many pulses it has sent and can read this value with a Read/Write control.  This should be able to give you equivalent functionality to your current code.


Another benefit to this example is that you can add multiple channels easily without having to worry about throughput.  The FPGA will simply process everything in parallel.  Give this example a shot and let me know how it works out. 


0 Kudos
Message 7 of 9

Today I started the whole project over.  I am running the pwm code on the cRio, not the host.  The difference is significant.  I think you are right, the problem was the host creating the output, then sending it.


I am also not using a shared-variable, which I noticed was causing an issue with somthing else.  


I can drive the motor very quickly now.  Thank you for your help.


Out of curiosity, when will SoftMotion be available for LabView 8.6?

0 Kudos
Message 8 of 9

I am glad everything is working for you now. 


SoftMotion for 8.6 is currently available.  Our website is showing an outdated version of the module, which is being fixed.  If you purchase the module you will actually get version 2.2 instead of 2.1, which works with 8.6.  Hope this helps!

0 Kudos
Message 9 of 9