How can I count the number of pulses using a microcontroller (any), provided the following conditions:

  1. Can not use any interrupt (no interrupt on pin change allowed)
  2. Can not use any of uC's hardware features (counter, timer etc.)

The width of the pulse is random and can not be predicted in advance. This pulse train is given to one of the general purpose IO pins. The solution should be purely software based ( C/assembly).

The software debouncing method which reads pin status as a series of 0's and 1's is a possible option but you need to hardcode the transition pattern, which means that you need to know the pulse width in advance and hence its can not be accepted.

Any idea?

PS: This question was asked on a technical interview with one of the major automotive component supplier.

  • \$\begingroup\$ Is your code the only thing executed? Because if not, it won't be possible. If not, then you can just do something like - add 1 - read gpio - add 1 - read gpio... and figure out how many clock cycles this takes. \$\endgroup\$ – NeinDochOah Jan 23 '16 at 16:14
  • \$\begingroup\$ Without hardware timer, counter and without interrupt this is not possible. And even if you would poll the GPIO status each scan makes this useless, since you would require all resources of a MCU to count pulses with no guarantee to catch all of them. \$\endgroup\$ – Marko Buršič Jan 23 '16 at 16:15
  • \$\begingroup\$ @Nein... yes that should be a reasonable assumption. \$\endgroup\$ – HKL Jan 25 '16 at 4:03

We have to assume that "it's impossible" is not the right answer, so that means that we can assume that the CPU has enough power to poll the pin at a rate that's fast enough not to miss any pulses.

I don't know why you think that "you need to hardcode the transition pattern". All you need to do is find the 0→1 and 1→0 transitions and count one or the other. The only thing required is to keep track of the previous state of the pin.

In pseudocode:

count = 0;
prev_pin = read_pin();
while (true) {
    pin = read_pin();
    if (pin && !prev_pin) ++count;
    prev_pin = pin;
  • \$\begingroup\$ And the candidate writing comments in the code gets the job, whether the algoritm is correct or not. ;o) \$\endgroup\$ – jippie Jan 23 '16 at 17:53
  • 1
    \$\begingroup\$ @jippie: The comments are the two paragraphs at the top. If I were writing actual source code, they would have been included. If someone needs inline comments to follow this code, then I'm not interested in hiring that person. \$\endgroup\$ – Dave Tweed Jan 23 '16 at 18:30
  • \$\begingroup\$ This is good if frequency is low, The OP didn't mention the max frequency and the min pulse duration. \$\endgroup\$ – Marko Buršič Jan 23 '16 at 22:36
  • \$\begingroup\$ @MarkoBuršič: I covered that in my stated assumptions. \$\endgroup\$ – Dave Tweed Jan 24 '16 at 3:40
  • 1
    \$\begingroup\$ Again, I don't know why you're reading so much into the question. Either you want to count ALL of the pulses, or you only want to count SOME of the pulses. If the latter, then someone needs to specify which pulses get counted. In the absence of that, we have to assume we're counting all of them. \$\endgroup\$ – Dave Tweed Jan 25 '16 at 5:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.