user79644: A sine wave is being fed to A0 and I would like to calculate the frequency. If a certain threshold is crossed, start the timer.....count 5 such crossings.....then stop the timer. The code is attached. Even though I understand while() with logical operators such as while(State<5) (shown in code), I do not understand the use of while(analogRead(A0)). I would like to know how it functions in relation the code? The program runs fine as it is. Tested this in Tinkercad, and got erroneous readings when while(analogRead(A0)) was commented. Thank you so much for reading my question ^_^.
void loop() 
{
  
  while(State<5)
  {
    val=analogRead(A0);
    if(val>200)
    { 
      Serial.println("Threshold Crossed");
      if(State==0)
      {
        Start_Time=millis();
      } 
      State++; 
      while(analogRead(A0)); //I DON'T UNDERSTAND THIS
    }
  }
      
End_Time=millis();

Period=(Start_Time-End_Time)/5;
Frequency=1000/(Start_Time-End_Time)
Serial.println(Frequency);

State=0;
}


user70044: As you correctly note, while typically takes a bool as argument. However, mainly for historical reasons, C/C++ don't really differentiate between int and bool, and therefore conditions can be of integer type. Any condition, be it in a while or an if, can be of int type. The condition evaluates to true if it is not zero. So the condition while(analogRead(A0)); loops (doing nothing) until analogRead returns 0.

user7508: What you have implemented, perhaps unknowingly, is called
hysteresis. Your program spends most of its time in either of these
two states:

It is continually running the outer while loop, and the value read
is ≤ 200. It gets out of this state as soon as it reads a value
larger than 200.
It is continually running the inner while loop, and the value read
is > 0. It gets out of this state only when analogRead()
returns zero.

Hysteresis is a good way to reject noise when you want to detect a
signal crossing a threshold. I would, however, recommend you use it in a
more controlled manner. Specifically, the second threshold should
probably be greater than zero, otherwise it won't be crossed unless the
signal goes all the way down to ground level. At a minimum, you can
replace the inner while loop with something like:
while (analogRead(A0) >= 100)
    /* wait until the signal gets low enough */;

For the record, this logic can be implemented in a non-blocking
fashion, which would let the program do other things, like responding to
button presses, while waiting for the transitions. For this, you need a
variable to record the current state of the signal (say, LOW or
HIGH) and record the state changes when the corresponding thresholds
are crossed.
The sketch below implements this non-blocking technique in loop(),
whereas setup() does block while waiting for the first LOW → HIGH
transition:
const int LOW_THRESHOLD  = 100;
const int HIGH_THRESHOLD = 200;

uint8_t state;      // either LOW or HIGH
uint8_t count = 0;  // count the LOW -> HIGH transitions
uint32_t start_time;

void setup() {
    // Wait for the first LOW -> HIGH transition.
    while (analogRead(A0) >= LOW_THRESHOLD)
        /* Wait for the LOW state. */;
    while (analogRead(A0) < HIGH_THRESHOLD)
        /* Wait for the HIGH state. */;
    state = HIGH;

    // Record transition time.
    start_time = millis();
}

void loop() {
    // Record transitions.
    uint8_t val = analogRead(A0);
    if (state == HIGH && val < LOW_THRESHOLD) {
        state = LOW;
    } else if (state == LOW && val >= HIGH_THRESHOLD) {
        state = HIGH;
        ++count;
    }

    if (count >= 5) {
        // Report measured frequency.
        uint32_t end_time = millis();
        int frequency = 1000 * count / (end_time - start_time);
        Serial.println(frequency);

        // Prepare for the next round.
        start_time = end_time;
        count = 0;
    }
}


79644: <p>A sine wave is being fed to <code>A0</code> and I would like to calculate the frequency. If a certain threshold is crossed, start the timer.....count 5 such crossings.....then stop the timer. The code is attached. Even though I understand <code>while()</code> with logical operators such as <code>while(State&lt;5)</code> (shown in code), I do not understand the use of <code>while(analogRead(A0))</code>. I would like to know how it functions in relation the code? The program runs fine as it is. Tested this in Tinkercad, and got erroneous readings when <code>while(analogRead(A0))</code> was commented. Thank you so much for reading my question ^_^.</p>
<pre class="lang-cpp prettyprint-override"><code>void loop() 
{
  
  while(State&lt;5)
  {
    val=analogRead(A0);
    if(val&gt;200)
    { 
      Serial.println(&quot;Threshold Crossed&quot;);
      if(State==0)
      {
        Start_Time=millis();
      } 
      State++; 
      while(analogRead(A0)); //I DON'T UNDERSTAND THIS
    }
  }
      
End_Time=millis();

Period=(Start_Time-End_Time)/5;
Frequency=1000/(Start_Time-End_Time)
Serial.println(Frequency);

State=0;
}
</code></pre>
 70044: <p>As you correctly note, <code>while</code> typically takes a bool as argument. However, mainly for historical reasons, C/C++ don't really differentiate between int and bool, and therefore conditions can be of integer type. Any condition, be it in a <code>while</code> or an <code>if</code>, can be of int type. The condition evaluates to true if it is not zero. So the condition <code>while(analogRead(A0));</code> loops (doing nothing) until <code>analogRead</code> returns 0.</p>
 7508: <p>What you have implemented, perhaps unknowingly, is called
<a href="https://en.wikipedia.org/wiki/Hysteresis" rel="noreferrer">hysteresis</a>. Your program spends most of its time in either of these
two states:</p>
<ol>
<li>It is continually running the outer <code>while</code> loop, and the value read
is ≤ 200. It gets out of this state as soon as it reads a value
larger than 200.</li>
<li>It is continually running the inner <code>while</code> loop, and the value read
is &gt; 0. It gets out of this state only when <code>analogRead()</code>
returns zero.</li>
</ol>
<p>Hysteresis is a good way to reject noise when you want to detect a
signal crossing a threshold. I would, however, recommend you use it in a
more controlled manner. Specifically, the second threshold should
probably be greater than zero, otherwise it won't be crossed unless the
signal goes all the way down to ground level. At a minimum, you can
replace the inner <code>while</code> loop with something like:</p>
<pre class="lang-cpp prettyprint-override"><code>while (analogRead(A0) &gt;= 100)
    /* wait until the signal gets low enough */;
</code></pre>
<p>For the record, this logic can be implemented in a <em>non-blocking</em>
fashion, which would let the program do other things, like responding to
button presses, while waiting for the transitions. For this, you need a
variable to record the current state of the signal (say, <code>LOW</code> or
<code>HIGH</code>) and record the state changes when the corresponding thresholds
are crossed.</p>
<p>The sketch below implements this non-blocking technique in <code>loop()</code>,
whereas <code>setup()</code> does block while waiting for the first <code>LOW</code> → <code>HIGH</code>
transition:</p>
<pre class="lang-cpp prettyprint-override"><code>const int LOW_THRESHOLD  = 100;
const int HIGH_THRESHOLD = 200;

uint8_t state;      // either LOW or HIGH
uint8_t count = 0;  // count the LOW -&gt; HIGH transitions
uint32_t start_time;

void setup() {
    // Wait for the first LOW -&gt; HIGH transition.
    while (analogRead(A0) &gt;= LOW_THRESHOLD)
        /* Wait for the LOW state. */;
    while (analogRead(A0) &lt; HIGH_THRESHOLD)
        /* Wait for the HIGH state. */;
    state = HIGH;

    // Record transition time.
    start_time = millis();
}

void loop() {
    // Record transitions.
    uint8_t val = analogRead(A0);
    if (state == HIGH &amp;&amp; val &lt; LOW_THRESHOLD) {
        state = LOW;
    } else if (state == LOW &amp;&amp; val &gt;= HIGH_THRESHOLD) {
        state = HIGH;
        ++count;
    }

    if (count &gt;= 5) {
        // Report measured frequency.
        uint32_t end_time = millis();
        int frequency = 1000 * count / (end_time - start_time);
        Serial.println(frequency);

        // Prepare for the next round.
        start_time = end_time;
        count = 0;
    }
}
</code></pre>
