Pulse count program*

I am trying to do a pulse count using a sine wave as input to the arduino - I offset the function generator so the sine wave is positive (since the arduino input cannot take more than -300mV).

So, I am able to serial print all values from the sine wave and they correspond to the sine wave.. Now I would like to take those numbers and do a pulse/peak count. I see the numbers rising and falling.

Any thoughts/ suggestions?

For demonstration purposes, I will assume that the range of your measured analog value is between the range of 0 - 1000.

I'm only including void loop() and necessary variable declarations. I leave setup up to you. This is untested code

#define SINE_PIN 3
#define HI_THRESHOLD 500

bool count_flag = false;
int n; //will be used to store the count

void loop()
{
      int analog_in = analogRead(SINE_PIN);

      if(analog_in > HI_THRESHOLD && !count_flag) //if analog_in > Hi_THRESHOLD and count_flag == false
      {
            n++;
            count_flag = true;
      }
      
      if(analog_in <= HI_THRESHOLD) //set count_flag to false only when below the threshold
            count_flag = false;

}

The idea behind this is that each time the input crosses a certain threshold and it hasn't already counted, it counts. Once its counted, it sets a bool count_flag to true. The next time the code reaches this check, even though the input is still above the threshold value, the count flag doesn't allow it to count. The only way to reset the count flag is to drop to below the threshold value.

Give it a try and let me know how this works out. You're going to run into reliability issues if the frequency of the input is extremely high. What's your frequency like right now?

Can't you use a schmitt trigger to convert the input to a clean square wave with each rising edge counting for one pulse?

And as far as your offset, instead of changing what you're measuring, you can use a diode to clip the negative portion of the sine wave and protect the arduino.

The software equivalent of a Schmitt trigger:

If this_sample is greater than last_sample, we're increasing.
If this_sample is less than last_sample, we're decreasing.
If we're increasing through a handy threshold, like the offset zero line, count the rising edge.

If you really want to count local maxima, or the humps, then remember if you were increasing last time, and count it if you are also decreasing this time. But I worry about signal jitter (and so did FusiveResonance above), so counting the times when you have the strongest slope from sample to sample is the safest way to go.

Thank you for your input!

Funny thing is, after I posted this I went on and ended up doing a similar concept as to what FusiveResonance suggests- it's the best way to go.

As for protection, yes a 1k resistor followed by a Shottky diode will do the trick (I used a 1N5818 for future reference to anyone). I believe the Arduino can handle a maximum of -300mV.

All in all, flagging is safest when doing this.

Again, thank you for your time and input, much appreciated!

1 thing to add... While playing around with millis(), I wanted to record the period time of the sine wave and reproduce the actual frequency.

When will calling of millis() not perform properly? As I have used millis() while filling arrays and it wasn't all that great

If this_sample is greater than last_sample, we're increasing.
If this_sample is less than last_sample, we're decreasing.
If we're increasing through a handy threshold, like the offset zero line, count the rising edge.

This is not like a schmitt trigger, it's more like a comparator. In your algorithm, if we jitter near that "handy threshold" you'll count extra pulses, which is exactly the problem that schmitt triggers solve.

Oracle, you're right. A true software schmitt would model the HIGH LOW separately, and would have two thresholds for changing the model, one rising and one falling, to avoid hysteresis.