Hello all,
I'm trying to find the best way to set up an hardware object counter. As input I've a square waveform which comes from a proximity sensor tightened to a camshaft (one period of the square wave is equivalent to one object counted). I need to display on three 7 segments led display the objects/minute entity. The range goes from 0 objects/min to a maximum of 120 objects/min. Two solutions here:
measure each square wave period and calculate object/minute rate or
count how many periods fall in an interval and calculate object/minute rate.
I opted for the first solution, because it gives a more immediate display output of the rate.
So basically I need to count how long is a square wave period, calculate rate and display it.
Display output is multiplexed: 7 segments outputs are sent to each of the 3 display and (for example) each display cathode is activated by different Arduino outputs. In this way the Arduino is continuously cycling between: display hundreds on left 7 segment display, display tens on center 7 segment display and display units on right 7 segment display.
Problem: measuring square wave period using the function PulseIn (http://arduino.cc/en/Reference/PulseIn) is not possible because Arduino can't do anything while measuring T-ON of the square wave: it must do multiplexed display output at the same time.
Ok, discarded PulseIn function and chose the external interrupt solution. But... I need and internal auto-increment counter to read inside the interrupt service routine in order to calculate T-ON length. Is it possible to configure such counter in Arduino environment?
Thanks in advance for any suggestion you can give to me.
Why do you need to measure the duration of T-ON can you not just get away with counting transisions?
If you need to count duration then you could setup the interrupt to work on pin CHANGE. On a high to low interrupt the millis is read and var1 is subtracted from it, the result is stored in var2 and millis stored in var1, on the low to high millis is read, subtract var1 and stored in var3.
You will have var1=start time of last pulse off, var2=pitch period and var3=on period.
Thanks a lot Riva for your help! That was exactly what I was looking for. I simply wasn't aware of functions like mills() and micros() which are, indeed, a more readable version of auto-increment counters. As you can imagine I come from the assembly world and I often don't remember that there's a function() which can solve my needs.
Thanks again.
The idea of any interrupt routine should be to do what needs doing as quick as possible and then get out of the interrupt so normal code execution can continue. You should only store the values (with the basic arithmetic) and get the loop() code to interpret the results. Don't forget to use the volatile keyword in front of any variable definitions that are used both in and out of the interrupt and also be aware that milli & micro probably wont change while in the interrupt
Thanks again for your useful suggestions. Yes, the ISR routine will only copy the mills() value on a variable which will be processed in the loop() routine together with all the other tasks.
Thanks a lot.