If-statement executes wrong sometimes

Hi all,

I’m new on the forum and facing a very odd issue.

Screenshot of the portion of the code in which i am having problem is attached. All variables are self explanatory except mL, which is for ‘milliliters’, a variable storing current delivered air-volume.

Second screenshot is of the serial monitor. If statement “if(mL>=requied_mL-100)” executes, which is usually the case, ‘1’ is printed on the monitor with both variables being compared in the if-statement (mL is being printing somewhere later in the code).

The problem is underlined in the serial monitor - if-statement executing wrong… And it executes wrong at least one times in 50 executions. Moreover, the underlined value of mL prints every time, every time.

Kindly tell me what is wrong. Thanks!

Screenshot of the portion of the code in which i am having problem is attached.

Post ALL of your code AS TEXT, NOT as a stupid picture. Where YOU think the problem is may completely wrong.

Second screenshot is of the serial monitor.

More stupidity. The serial monitor application displays TEXT, which you can copy and paste here AS TEXT.

Code has 1128 lines. I don’t want trouble for anyone to read all of it, whereas the problem is in just one line.

You see the while(1)? It will never break until the any if-statement gets true. The statement getting true prints its number, 1, 2 and 3.

You see, every time 1 gets true i.e. if(mL>=required_mL-100) gets true, thus printing “1” at the first column of the monitor.

But in underlined line, same if-statement is getting true, that is “1” but seeing the both variables being compared, this is not possible.

I don't want trouble for anyone to read all of it

If you don't post the code AS TEXT, no one will read any of it. Your choice.

SaadPasha:
Code has 1128 lines. I don't want trouble for anyone to read all of it, whereas the problem is in just one line.

Then post an MCVE. This is the smallest, COMPLETE (meaning we can copy into the IDE and compile it) program that demonstrates the problem you're seeing. Leave out everything unrelated to the problem.

Also, see:
Read this before posting a programming question ..., especially Item #6 that explains how to post your code with Code Tags.

Here is the code.

//____________________________________________
//____________________________________________

//called every 1msec
ISR(TIMER1_OVF_vect) 
{ 
  TCNT1 = 65286;      // preload timer = 2^16 - 16MHz/64/1000Hz
  sei();              // takes 4us only.
  
  flowRateA2DInput = analogRead(pin_flowRateSensor);
  flowRateInput = ((flowRateA2DInput - flowRateA2D_drift)/(1023-flowRateA2D_drift))*maxAllowable_FR;
  
  if (flowRateInput > 0.15)
    mL = mL + (flowRateInput/60);
  
  pressureA2DInput = analogRead(pin_pressureSensor);
  pressureInput = 70.307 * ((pressureA2DInput - pressureA2D_drift)/(920 - pressureA2D_drift)); // 
  
  if (peakPressure<pressureInput && pressureInput<70)
    peakPressure = pressureInput;
    
  if (peakFlow < flowRateInput)
     peakFlow = flowRateInput;     
     
}

//__________________________________________________
//__________________________________________________

void loop()
{ 
  CMV();
}

//_________________________________________________
//_________________________________________________

void CMV() 
{
  while(1)
  {
    mL = 0;
    peakFlow = 0;
    peakPressure = 0;
    peakPressure1 = 0;
    indicator = 1;
    
    analogWrite(pin_closePWM, pwm); 
    
    TIMSK1 = 1;
    t1 = millis();
    
    
    digitalWrite(pin_solinoidExhale, LOW);
   
    //______________________________________________________________ Inhalation
    while(1)
    {
      if (peakPressure < allowablePeakPressure)
      {
        if (mL >= required_mL) // Here is the problem
        {
          Serial.print("1");
          Serial.print(" ");
          Serial.print(required_mL);
          break;
        }
        else if (!digitalRead(pin_hallSensor_compressed))
        {
          Serial.print("2");
          Serial.print(" ");
          Serial.print(required_mL);
          break;
        }
        else if (millis()-t1 > allowableInhalationTime)
        {
          Serial.print("3");
          Serial.print(" ");
          Serial.print(required_mL);
          break;
        }
      }
      else
      {
        indicator = 0;
        Serial.print("4");
        Serial.print(" ");
        Serial.print(required_mL);
        break;
      }
    }

    strokeTime = millis() - t1;
    digitalWrite(pin_closePWM, 0);
    TIMSK1 = 0;
    
    printSerial();
  
    analogWrite(pin_openPWM, 255);
    digitalWrite(pin_solinoidExhale, HIGH);  

    if(indicator)
    {
      strokeError = strokeTime - inhalationTime;
      temp = float(strokeError) / 30 ;
      
      if (strokeError > 0 && pwm + temp <= 255)
      {
        pwm = pwm + temp;
      }
      else if (strokeError > 0 && pwm + temp > 255)
      {
        pwm = 255;
      }
      else if (strokeError < 0 && pwm + temp > 0)
      {
        pwm = pwm + temp;
      }
    } 
    
    //________________________________________ Waiting for next breath
    while (millis()-t1 <= breathPeriod);

  }
}

//___________________________________________
//___________________________________________

void printSerial()
{
  Serial.print(" ");
  Serial.print(mL);
  
  Serial.print(" ");
  Serial.print(peakFlow);
  
  Serial.print(" ");
  Serial.print(float(strokeTime)/1000);
  
  Serial.print(" ");
  Serial.print(peakPressure);
  
  Serial.print(" ");
  Serial.print(pwm);
  
  Serial.print(" ");
  Serial.print((float(millis())/1000));  
}

That code does not compile. See Reply #4.

If i just paste all of the code, how you people will check it as you don't have the hardware? Is there a way to check the code without hardware?

MCVE

SaadPasha:
If i just paste all of the code, how you people will check it as you don't have the hardware? Is there a way to check the code without hardware?

Well it might give us a chance to see it and spot problems - for instance we have no idea if you've correctly
declared the right variables as volatile, and you are using an ISR so this matters.

One thing I notice is that you enable interrupts inside your ISR. Why?

Other things is possible divide-by-zero in your ISR; what type are your variables peakPressure and peakFlow? The code will not crash but unexpected behaviour can be the result.

I would not recommend enabling interrupts in the ISR without a good reason. Pretty sure you dont have one, especially since the isr will execute quickly.

Could be related to that, but I'm betting it's variables not declared volatile which need to be.

I noticed two issues in the program.

mL and required_mL are never declared

There is an ISR with an analogRead() instruction in it.

Buddies, thanks for all your time and help.

The issue is resolved by one of my friend.

ISR is being calling after every 1msec. ISR updates the value of mL every time, and this is possible that timer interrupt comes in during "if(mL > required_mL-100)-condition" execution. And that was actually happening, which was leading to wrong if-condition execution.

Now, i put this if-condition in the ISR and used a flag in the CVM() function. Now it is working fine.

One thing left from you people, can you explain volatile variables? And why, when and where to use them?

And thanks for all your support and time. Thanks a lot.

One thing left from you people, can you explain volatile variables? And why, when and where to use them?

If a function, like loop(), accesses a variable who's contents can be changed by an ISR, the variable needs to marked volatile.

This will cause the compiler to generate code to fetch the value from the variable, rather than using a cached value, every time it is needed.