Search code examples
c++arduinonested-if

C++ nested If statement, it doesn't work as expected


StackOverflow fellow developers,

I am doing some Arduino coding to working with measuring Fine Dust Monitoring Device,

However, I have a question regarding with If-statement.

In the code below, I added nested-if statement in the while loop, and some reason,

    else if (9999 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 52) {
      pm25i = 7;
    }
    else if (9999 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 102) {
      pm10i = 7;
    }
      else if (pm10i == 7) {
        status = "Hazardous (7) : Health warnings of emergency conditions. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are strongly discouraged.";
      }
    }

Those lines doesn't work as expected, as when pm10 or pm25 value reaches more than 100 ug / m^3, it doesn't sync with the ThingSpeak server anymore, but I don't know why it doesn't uploads any data. Interestingly rest of my source code parts work fine as expected.

However When I removed those nested-if statements it works fine. (It successfully uploads even pm10 or pm25 value reaches more than 100 ug / m^3.

Could somebody explain what's wrong with my code? and how should I fix this issue please?

Thanks.

void loop() {
  if (ss.available() <= 0) {
    Serial.println("SIGNAL STATUS : WEAK");
    s_map_x = String(map_x, 6);
    s_map_y = String(map_y, 6);
  }
  else {
    while (ss.available() > 0) {
      Serial.println("SIGNAL STATUS : GREAT");
      if (gps.encode(ss.read())) {
        Serial.println("GPS READ");
        Serial.println(ss.read());
        if (gps.location.isValid()) {
          Serial.println("LOCATION : GREAT");
          map_x = gps.location.lat();
          map_y = gps.location.lng();
          Serial.println(String(map_x, 6));
          Serial.println(String(map_y, 6));
          Serial.println(gps.satellites.value());
        }
      }
      s_map_x = String(map_x, 6);
      s_map_y = String(map_y, 6);
      yield();
    }
  }
  while (dust.available() > 0) {
    do_dust(dust.read(), got_dust);
    yield();                                          


    /* AQI (실시간 대기질 지수) 등급 분류를 위한 코드입니다.
       실시간 대기질 기준 수치는 국제 표준인 WHO 대기질 수치 기준으로 분류합니다.
       http://www.euro.who.int/__data/assets/pdf_file/0005/78638/E90038.pdf
       https://airnow.gov/index.cfm?action=aqibasics.aqi */

       
    // 초미세먼지 AQI (실시간 대기질 지수) 등급을 분류합니다.
    //   0 이상   8 이하 : 1
    //   9 이상  16 이하 : 2
    //  17 이상  26 이하 : 3
    //  27 이상  34 이하 : 4
    //  35 이상  43 이하 : 5
    //  44 이상  51 이하 : 6
    //  52 이상  ∞  이하 : 7

    if (8 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 0) { 
      pm25i = 1;
    }
    else if (16 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 9) {
      pm25i = 2;
    }
    else if (26 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 17) {
      pm25i = 3;
    }
    else if (34 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 27) {
      pm25i = 4;
    }
    else if (43 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 35) {
      pm25i = 5;
    }
    else if (51 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 44) {
      pm25i = 6;
    }
    else if (9999 >= int(pm25s.getMedian()) && int(pm25s.getMedian()) >= 52) {
      pm25i = 7;
    }


    // 미세먼지 AQI (실시간 대기질 지수) 등급을 분류합니다.
    //   0 이상   8 이하 : 1
    //   9 이상  16 이하 : 2
    //  17 이상  51 이하 : 3
    //  52 이상  68 이하 : 4
    //  69 이상  84 이하 : 5
    //  85 이상 101 이하 : 6
    // 102 이상  ∞  이하 : 7

    if (8 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 0) {
      pm10i = 1;
    }
    else if (16 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 9) {
      pm10i = 2;
    }
    else if (51 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 17) {
      pm10i = 3;
    }
    else if (68 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 52) {
      pm10i = 4;
    }
    else if (84 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 69) {
      pm10i = 5;
    }
    else if (101 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 85) {
      pm10i = 6;
    }
    else if (9999 >= int(pm10s.getMedian()) && int(pm10s.getMedian()) >= 102) {
      pm10i = 7;
    }

    /* ThingSpeak 채널 내 Status Update (상태 업데이트) 영역에 표시되는 문구이므로,  
        종합적인 정보 표현을 위해 초미세먼지와 미세먼지 등급을 비교 한 후 
        두 가지 중 높은 등급 기준으로 경고 혹은 권고메시지를 표시합니다. */

    // 분류된 초미세먼지 등급이 미세먼지 등급보다 같거나 높은 경우, 초미세먼지 등급을 기준으로 내용을 표시하기 위하여 아래의 문자열을 status 변수에 저장합니다. 
    if (pm25i >= pm10i) {
      if (pm25i == 1) {
        status = "Excellent (1) : The air quality is excellent. The air pollution pose no threat. The conditions ideal for outdoor activities.";
      }

      else if (pm25i == 2) {
        status = "Very Good (2) : Air quality is very good, and air pollution poses little or no risk. Conditions very good for outdoor activities.";
      }

      else if (pm25i == 3) {
        status = "Moderate (3) : Air quality is acceptable. however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution.";
      }

      else if (pm25i == 4) {
        status = "Satisfactory (4) : Members of sensitive groups may experience health effects, Other people should limit spending time outdoors, especially when they experience symptoms such as cough or sore throat.";
      }

      else if (pm25i == 5) {
        status = "Bad (5) : Everyone may begin to experience health effects, members of sensitive groups may experience more serious health effects. People at risk should avoid to go outside. Not recommended for outdoor activities.";
      }

      else if (pm25i == 6) {
        status = "Severe (6) : Air quality is severe. Everyone may experience more serious health effects. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are discouraged.";
      }

      else if (pm25i == 7) {
        status = "Hazardous (7) : Health warnings of emergency conditions. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are strongly discouraged.";
      }

    // 분류된 미세먼지 등급이 초미세먼지 등급보다 높은 경우, 미세먼지 등급을 기준으로 내용을 표시하기 위하여 아래의 문자열을 status 변수에 저장합니다.
    } else if (pm25i < pm10i) {
      if (pm10i == 1) {
        status = "Excellent (1) : The air quality is excellent. The air pollution pose no threat. The conditions ideal for outdoor activities.";
      }
      
      else if (pm10i == 2) {
        status = "Very Good (2) : Air quality is very good, and air pollution poses little or no risk. Conditions very good for outdoor activities";
      }

      else if (pm10i == 3) {
        status = "Moderate (3) :  Air quality is acceptable. however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution.";
      }

      else if (pm10i == 4) {
        status = "Satisfactory (4) : Members of sensitive groups may experience health effects, Other people should limit spending time outdoors, especially when they experience symptoms such as cough or sore throat.";
      }

      else if (pm10i == 5) {
        status = "Bad (5) : Everyone may begin to experience health effects, members of sensitive groups may experience more serious health effects. People at risk should avoid to go outside. Not recommended for outdoor activities.";
      }

      else if (pm10i == 6) {
        status = "Severe (6) : Air quality is severe. Everyone may experience more serious health effects. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are discouraged.";
      }

      else if (pm10i == 7) {
        status = "Hazardous (7) : Health warnings of emergency conditions. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are strongly discouraged.";
      }
    }
  }

  //Serial.println(map_x);
  //Serial.print("pm 25 : ");
  //Serial.println(int(pm25s.getMedian()));

  if (millis() > mark) {//one minute(60000) interval
    mark = millis() + 60000;
    got_interval = true;
  }

  if (got_interval) {
    got_interval = false;
    do_interval();
  }
  yield();
}

Solution

  • You may be getting unexpected behavior due to floating point comparisons or may be due to some unhandled cases, or may be because RunningMedian::getMedian() is changing on any/every condition check. Another possible reason is maybe RunningMedia::_cnt is not more than 0.

    Also I would recommend updating your library to its latest version (v0.1.15).

    Try putting this code inside your while loop:

    float _pm25Median = pm25s.getMedian();
    float _pm10Median = pm10s.getMedian();
    
    if (isnan(_pm25Median) || isnan(_pm10Median))
        continue; // or do something else to handle this exception properly
    
    if (_pm25Median < 9)
        pm25i = 1;
    else if (_pm25Median < 17)
        pm25i = 2;
    else if (_pm25Median < 27)
        pm25i = 3;
    else if (_pm25Median < 35)
        pm25i = 4;
    else if (_pm25Median < 44)
        pm25i = 5;
    else if (_pm25Median < 52)
        pm25i = 6;
    else
        pm25i = 7;
    
    if (_pm10Median < 9)
        pm10i = 1;
    else if (_pm10Median < 17)
        pm10i = 2;
    else if (_pm10Median < 52)
        pm10i = 3;
    else if (_pm10Median < 69)
        pm10i = 4;
    else if (_pm10Median < 85)
        pm10i = 5;
    else if (_pm10Median < 102)
        pm10i = 6;
    else
        pm10i = 7;
    
    if (pm25i >= pm10i) {
        switch (pm25i) {
        case 1:
            status = "Excellent (1) : The air quality is excellent. The air pollution pose no threat. The conditions ideal for outdoor activities.";
            break;
        case 2:
            status = "Very Good (2) : Air quality is very good, and air pollution poses little or no risk. Conditions very good for outdoor activities.";
            break;
        case 3:
            status = "Moderate (3) : Air quality is acceptable. however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution.";
            break;
        case 4:
            status = "Satisfactory (4) : Members of sensitive groups may experience health effects, Other people should limit spending time outdoors, especially when they experience symptoms such as cough or sore throat.";
            break;
        case 5:
            status = "Bad (5) : Everyone may begin to experience health effects, members of sensitive groups may experience more serious health effects. People at risk should avoid to go outside. Not recommended for outdoor activities.";
            break;
        case 6:
            status = "Severe (6) : Air quality is severe. Everyone may experience more serious health effects. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are discouraged.";
            break;
        case 7:
            status = "Hazardous (7) : Health warnings of emergency conditions. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are strongly discouraged.";
        default:
            break;
        }
    } else {
        switch (pm10i) {
        case 1:
            status = "Excellent (1) : The air quality is excellent. The air pollution pose no threat. The conditions ideal for outdoor activities.";
            break;
        case 2:
            status = "Very Good (2) : Air quality is very good, and air pollution poses little or no risk. Conditions very good for outdoor activities";
            break;
        case 3:
            status = "Moderate (3) :  Air quality is acceptable. however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution.";
            break;
        case 4:
            status = "Satisfactory (4) : Members of sensitive groups may experience health effects, Other people should limit spending time outdoors, especially when they experience symptoms such as cough or sore throat.";
            break;
        case 5:
            status = "Bad (5) : Everyone may begin to experience health effects, members of sensitive groups may experience more serious health effects. People at risk should avoid to go outside. Not recommended for outdoor activities.";
            break;
        case 6:
            status = "Severe (6) : Air quality is severe. Everyone may experience more serious health effects. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are discouraged.";
            break;
        case 7:
            status = "Hazardous (7) : Health warnings of emergency conditions. People at risk should be avoided to go outside and should limit the outdoor activities to minimum. Outdoor activities are strongly discouraged.";
            break;
        default:
            break;
        }
    }