Using Interrupts or DMA or timing to control digital I/O switch


We are trying to kick a ball with a revolving drum, driven by a toughbox from andymark and a CIM motor. We are using an Allied Electronics Infrared Optical Switch as a digital I/O. This I/O has a resolution of about 1ms pulses.


We have written code to stop our Jaguar driving the CIM / toughbox when the beam of light is detected. Note: There is a hole in our drum for the light to pass through.

What Happens:

When we run the code, we are seeing that the switch is detected every other rotation of our drum. So it seems that lab view is running to slow to accurately pick it up.

The way our code works is, there are two routines in tele-op. One to fire, which is a button press and a set motor value to the jaguar. The second routine is to reposition, which is currently driven by a button press, with a series of case structures.

Any recommendations will be helpful. I can post our code in a few hours.
Any ideas would be helpful.

Another quick question… is there a way to use labview to set a flag. Say, I want a button press, to turn a switch “on” and then a routine would run, and another boolean var, like a digital I/O or switch would turn off this routine.

Thanks in advance for your help!

I think the simplest solution for you would be to use the DIO pin as the input to a Counter. That way you won’t need to rely on reading the state of the pin at the precise moment the sensor is detecting the hole. Just reset the counter before you run the drum, then watch the output of the counter and take appropriate action when it has counted the pulse. You might end up reacting slightly later than you think you should, but that’s better than not reacting at all.

Hi Alan,

Could you please elaborate a bit on this “counter” implementation?

i.e., Is the counter implemented in the FPGA so that it is independent of the cRIO main processor? Or is the counter implemented as a high-priority interrupt of the cRIO processor? Finally, how, in LabVIEW, does one set up such a counter?

Thank you!


The counters (and encoders, for that matter) are handled by the FPGA.

The Sensors palette has the Counter functions in it. I don’t have access to LabVIEW for FRC at the moment, so I can’t be sure, but I think there’s an example project showing how to open and read a counter. It works very much like an encoder, but with only one DIO connected

I just now looked at the counter VI function and they will take two Digital In lines but only one is a required input.

So as Alan suggest you could wire the IO line to the Up Source and check when it is greater than 0



Thanks Alan.

Let me say back to you what I am understanding, so you can correct me if it’s wrong:

  • the programmer doesn’t really need to know anything about FPGA. As far as the programmer is concerned, the code looks like all the other code.

  • when LabVIEW compiles and deploys, it doesn’t “re-program” the FPGA - it simply contains run-time initialization code that sets up the affected DIO port to be handled by existing FPGA code that has been pre-programmed by NI.

  • when the program is running, the signal on the affected DIO channel is handled directly by the FPGA - the execution of the cRIO software is not affected in any way

  • the FPGA contains a counter that is incremented by the FPGA code each time a leading edge (for example) is detected on the affected DIO port

  • the cRIO software can read (and clear) the FPGA-maintained counter

Is that about right?


Hi Everyone,

Thanks for your advice. I have tried the counter example and it is working… But we mainly care about the Digital I/O get value… Which is working. I have added screen shots of our code to help you gauge what we are doing.

We are also expanding the hole or the “window” persay of the light. Maybe if we expand this window, the motor will stop within the window. This routine should be very simple…

If you have any other ideas, please feel free to share. Thanks again!

2-20 new (276 KB)

2-20 new (276 KB)

Hey Everyone,

Thanks for your help! The solution to this problem was using the “periodic” to accomplish this… For some reason yesterday, it just wasn’t working. Today, the main thing we changed was adding the joystick reference in order for a button press to control the routine.

Earlier on, we were trying to have this running as a background task, if the user wasn’t firing. We will still pursue this method, but right now, it works!

I’m afraid you’ll find that this sometimes won’t work. If you use the counter instead, it will be almost as simple to implement and will never miss an event.

I only have knowledge of the FPGA from an outside view. Everything you said matches my understanding, though I see a small implication on your part that you’re treating it as if it were just more code. It’s certainly defined by code (in LabVIEW, even), but I think it makes more sense to think of it as dedicated hardware with a layer of software-configurable connections to the cRIO modules.

The cRIO FPGA is normally just another LabVIEW target. You write VIs for very low level I/O and simple computation, twiddle your thumbs for quite some time as the VHDL tool chain constructs the image, and then you deploy it to the FPGA.

When it executes, the FPGA has complete control of all module I/O and on the other end is user definable memory, typically called registers. They will contain configuration data for the FPGA, or results from the I/O. The registers are represented as front panel controls in LV, by the way.

The next layer of code is written using RT and runs on the cRIO. It accesses the registers and typically implements higher level control, monitoring, logging, user protocols, etc.

For FRC, the FPGA image contains the safety mechanism for shutting down all outputs, so it is used as binary, and acts as the I/O engine. When the cRIO is imaged, one part of that image is the FPGA bitmask. For FRC, the FPGA is responsible for all PWM generation, counters and encoders, analog averaging and oversampling, digital and analog triggers, I2C and SPI, and I’m sure I’m leaving out plenty of other tasks. This leaves the cRIO to the job of communications, scaling, configuring, control, vision, serial and CAN. This is still a very simplistic view of the system. If you are in Atlanta, there will likely be some more in depth presentations, and you can of course always drop by the booth. Or ask the more detailed questions here if you like.

Greg McKaskle

OK, I agree.

What I was wondering was, when an FRC team writes application code using the LabVIEW framework and then “deploys” it, does this ever “re-program” the FPGA? Or, does it simply add cRIO runtime initialization code that configures the (pre-programmed by NI) FPGA?

Greg, does my question above make sense?


For FRC, the FPGA is programmed only when imaging the cRIO. Teams have no way to change it using their own code. This is a essentially a safety issue, as the FPGA handles all of the robot watchdog and disable features.

OK. Got it. That makes sense.