Операторы if

Тема в разделе "Arduino & Shields", создана пользователем amss, 12 фев 2020.

  1. amss

    amss Нуб

    Здравствуйте уважаемые форумчане.

    Требуется ваша помощь. Уже всю голову сломал. Делаю на ардуино управление термокамерой. Задача такая есть данные: Т0 - температура в камере и Т1 - температура внутри продукта. И соответственно реле - включения нагрева в камере. Нужно чтобы на первом этапе в камере поддерживалась температура Т0 = 30 градусов, пока Т1 не достигнет 15 градусов. Когда Т1 станет более 15 градусов, температура должна уже держаться в камере не выше Т0=60 градусов до достижения Т1=40. Ну и по аналогии следующие этапы.

    Я написал такую программу, тут пока выводится на монитор вкл или выкл, затем заменю на команды на вкл выкл реле:

    Код (Text):
    if (T1<=15)  {
    if (T0<=30) { Serial.println("Отепление вкл");}
        else { Serial.println("Отепление выкл");}
    }
    if (15<T1<=40)  {
    if (T0<=60) {Serial.println("Сушка вкл");}
        else { Serial.println("Сушка выкл");}
    }
    Но на практике вышло, что при Т1=25 и Т0=25 (температура в комнате) выполняются оба условия и включена и сушка и отепление. Что блин не так?
    Кстати с помощью оператора goto вроде все работает, но управление через телефон на RemoteXY не поддерживает этот оператор.
    Помогите пожалуйста разобраться.
     
    Последнее редактирование модератором: 13 фев 2020
  2. fogary

    fogary Гик

    Код (C++):
    if (T1 <= 15) {
      if (T0 <= 30) {
        Serial.println("Отепление вкл");
      } else {
        Serial.println("Отепление выкл");
      }
    } else if (T1 <= 40) {
      if (T0 <= 60) {
        Serial.println("Сушка вкл");
      } else {
        Serial.println("Сушка выкл");
      }
    }
     
  3. b707

    b707 Гуру

    fogary - та же проблема, что у ТС, при Т0 = 25 и Т1=25 будут включены оба режима
     
  4. b707

    b707 Гуру

    проблема в строчке if (15<T1<=40) { - такое "двойное условие" в С++ не поддерживается. , пишите два отдельных и обьединяйте логическим "И"
     
  5. fogary

    fogary Гик

    При Т1=25 ветка "Отопление ..." будет пропущена (else if - же).

    Вообще странно, как при Т1=25 может срабатывать первая проверка (T1<=15)?
     
    Последнее редактирование: 12 фев 2020
  6. b707

    b707 Гуру

    насколько я понял из ТЗ, отопление надо сначала выключить, а потом уже переходить в ветку сушки.
    Но возможно я неверно понял условия, тогда извиняюсь
     
  7. amss

    amss Нуб

    Спасибо, сейчас попробую и отпишусь
     
  8. fogary

    fogary Гик

    Возможно Вы правы, но из ТЗ не ясно, чем отопление от сушки отличается. По этому авторский код, в этом месте, остался как есть.
     
  9. parovoZZ

    parovoZZ Гуру

    Секвенсор состояний и через switch case. Зачем if?
     
  10. Daniil

    Daniil Гуру

    Чуть-чуть уточню.
    поддерживается, но не так как мы читаем в математике.
    Такое выражение нужно читать так ((15<т1)<=40)
    при т1=25, 15<т1 = 1, т.к. Верно, а потом будет выполняться сравнение 1<=40, которое тоже верно и равно 1.
    при т1=10, 15<т1 = 0, т.к. Ложь, а потом будет выполняться сравнение 0<=40, которое верно и равно 1.
    Т.е. Всегда будет 1 у этого условия.
     
    akl нравится это.
  11. SergeiL

    SergeiL Оракул Модератор

    Ну, вроде Си знаю, вот прямо интересно стало, как в "switch - case" отработать "<=" ? Просветите :).
     
    issaom нравится это.
  12. parovoZZ

    parovoZZ Гуру

    Так это условие для секвенсора состояний.
     
  13. Airbus

    Airbus Радиохулиган Модератор

    У Вас ДВЕ переменные.Которые меняются независимо друг от друга.Поэтому Вам нужно двойное условие в коде.Достигается или вторым вложенным if или использованием операторов И &&; ИЛИ ||; итд. п5.10-5.11
    Пример использования-Скетч ИгоряК "подсветка кровати" переделаны мной под Тини-13. Авторский не привожу-можете сами найти.E меня упрощённый и более понятный вариант.Есть и ИЛИ и И условия.
    Код (Text):
    /* Плавная подсветка
       Работает с PIR датчиками
    /
    #define PIN_MOTION01 3                    // Ноги для ИК датчиков
    #define PIN_MOTION02 2
    #define PIN_PWM 0                        // MOSFET
    #define TIME_DELAY_LIGHT 15000            // Задержка включения подсветки
    #define LIGHT_NIGHT 127                    // Яркость свечения ленты
    #define DELAY_TO_NEXT_LIGHT 30            // Плавность изменения света

    bool gotMotion = false;                    // Флаг движение
    bool lightIsSwitchedOn = false;            // Флаг включения подсветки
    bool flag20 = false;                       // Флаг включения ночной подстветки
    #define LIGHT_VISION 10                    // Яркость постоянной ночной подсветки

    uint8_t sensorA=0, sensorB = 0, sensorStep = 0; // Разные счетчики
    unsigned long timeToNextDecision = 0;    // Когда принять решение о выключении

    void setup()
    { }

    void loop()
    {              // сработал любой из датчиков движения
                   // устанавливаем флаг обнаружения движения
                  //ЗДЕСЯ Условие ИЛИ!!!  
                    if ( (digitalRead(PIN_MOTION01)) || (digitalRead(PIN_MOTION02))  )
                    gotMotion = true;
                //А ТУТА условие И!!!
                // Если подсветка не включена и обнаружено движение
                    if((!lightIsSwitchedOn) && (gotMotion)) {
                    for(int i = LIGHT_VISION; i <LIGHT_NIGHT; i++) {    
               // Плавно включаем подсветку
                            analogWrite(PIN_PWM, i);
                            delay(DELAY_TO_NEXT_LIGHT);
                        }
                        lightIsSwitchedOn = 1;            // Устанавливаем флаг о включении
                        gotMotion = 0;                    // Сбрасываем флаг обнаружения движения
                        // Вычисляем время, когда будем проверять что подсветку пора выключать
                        timeToNextDecision = millis() + TIME_DELAY_LIGHT;
                    }
                    // Если движения нет, подсветка включена и наступило время ее выключать
                   // ТУТА условие И!!!
                    if((!gotMotion) && (lightIsSwitchedOn) && (millis() > timeToNextDecision)){
                        for(int i = LIGHT_NIGHT; i >LIGHT_VISION; i--) { // Плавно выключаем
                            analogWrite(PIN_PWM, i);
                            delay(DELAY_TO_NEXT_LIGHT);
                        }
                        analogWrite(PIN_PWM, LIGHT_VISION);
                        lightIsSwitchedOn = 0;                // Сбрасываем флаг включенной подсветки
                        timeToNextDecision = 0;                // Обнуляем время следующей проверки отсутствия движения
                    }                                        
                            // Если подсветка включена и движение продолжвается
                    if((gotMotion) && (lightIsSwitchedOn) && (millis() > timeToNextDecision)) {
                        timeToNextDecision = millis() + TIME_DELAY_LIGHT; // Устанавливаем новое время проверки отсутствия движения
                        gotMotion = 0;
                    }

                }
     
    Последнее редактирование: 13 фев 2020