I am having an issue measuring the right time between rising edges with a tachometer:
The hardware consists of a transmissive sensor (slot sensor) with a disc with 20 tines on it. The sensor is then connected to a cRIO 9205 module and will read around 0V when blocked and 5V when clear. I know that the motor that is driving the disc is running at a constant RPM, however, reading the period between the rising edges of the disc tines is giving fluctuating readings, resulting in the RPM reading changing by up to 100RPM.
The sensor input is processed on the FPGA with a 1uSec loop rate and the rise and fall time of the slot sensor is 10uSec. The disc should be rotating at around 600rpm with a 30mm diameter.
The issue is most likely due to the code so is attached.
It looks like everything you've done in the code snippet below should be fine however your period will vary slightly. I would implement a piece of code that monitors the period Max and Min and has a condition around it to keep the most up to date Max period. This way your fluctuations should decrease and you will be able to look at a more stable rpm which is expected.
NI UK AE
According to the NI 9205 datasheet, that module only supports a maximum sampling rate of 250 kS/s, which corresponds to a 4 us loop rate. You are trying to run your loop faster than you can acquire and read new data from the module.
In general, I/O nodes are too slow to acquire at 1 us loop rates without using User-Controlled I/O Sampling, per this article:
This may not be applicable to the NI 9205.
I have now changed the loop rate to 64us as I am using 16 sensors, all with a differential configuration to reduce any noise but am still not getting a consistent RPM. With the disc rotating at 10 times per second, there will be a single revolution of the disc every 0.1 second. I have three discs, with 20, 24, and 26 tines, each with the same diameter. Therefore, with a 64us sample rate, there should be 1562 readings per revolution of the disc, more than enough to identify the rising edges of the disc.
Look carefully at how you are identifying a rising edge. You are looking for a 1 V step change between successive I/O reads, which are occurring at 1 us in your posted code, or 64 us according to your updated information. In the former case, the code would execute too fast for that to ever be true, and in the latter case, you could be missing rising edges. You are not interested in differential changes though - you're interested in absolute values.
Instead, for example, set a flag for whether your comparison is active, and look for an absolute measurement greater than e.g. 4 Volts. Once that is detected, you stop examining that condition until the measured signal once again drops below e.g. 1 Volt (i.e. a falling edge detector, but in this case it would just enable your rising edge detector again). This way, the accuracy of your result is not dependent on the wheel speed.
I've amended my code to convert the AI to a digital signal and compare two values to find a rising edge as shown.
However, I am still getting a very erratic RPM value. It looks like the output value is jumping between two values, rather than a more analog output. The graph below shows the RPM recorded while the disc is turning.
A couple of things:
First, there are 60,000,000 microseconds in a minute, not 1,000,000, and your measured period is between rising edges, not between revolutions of the disc. Your RPM indicator is actually reading rising edges (tines) per second, and not revolutions of the disc per minute.
Second, you are performing your conversion on the instantaneous previous period between detected rising edges. Perhaps a more robust way to do this is to increment a counter every time you encounter a rising edge, and compare the count increment over a longer time interval to get velocity out. This will average the error inherent to your measurement when the period between rising edges is not a multiple of the loop execution period. Keep in mind that you are not actually capturing the rising edge from the instrument, but rather are sampling it at a different rate than the state changes are occurring at. The difference between the actual rising edge and when you happen to detect that rising edge is significant if comparing over a 64 us period, for example, but perhaps not significant if you are averaging over e.g. 640 ms
Third, you are running a disc with 26 tines at one revolution per 0.1 seconds, so the actual rising edge frequency is 260 Hz. In order to capture that phenomenon, you need to acquire data at at least twice that rate, so 520 Hz at minimum, which corresponds to a loop period of 1923 us. Your loop timer is set at 64 us, so you should be okay there, but check using your benchmark code that it is performing as expected. I note from the NI 9205 datasheet that there are a couple of different sample settling times listed depending on required accuracy, so double check that you are meeting your requirements there, and adjust your loop timing accordingly if not.
What target are you running this VI on?
1. The 1,000,000 is taking into account gear ratio and number of tines on the disc to give the correct RPM value.
2. I feel that this is a way to mask the problem rather than identifying the core issue.
3. I have benchmarked my code and it is running at 208uSec, taking into account the other code that's within the VI.
The VI is running on a cRIO 9035 with the 9205 module in slot 1.
Do you mean to say that the loop which you are attempting to time at 64 us is taking 208 us to execute, on a real-time target? That is a problem. Also, I wasn't aware of the gears. What is the actual frequency of rising edges then?
I think I found the answer:
I had another loop with a FIFO to send the remaining of the sensor data up to the RT for processing. This was causing the loop rate to increase on the tach sensor loop. Once I removed that, it seems to work pretty well.