Использование break для выхода из цикла While

Тема в разделе "Arduino & Shields", создана пользователем okuznetcov, 18 май 2015.

  1. okuznetcov

    okuznetcov Нерд

    Всем привет! Совсем недавно купил себе Arduino. Изначально покупал плату для сбора проекта "умный дом" на даче, однако пока не все комплектующие доехали, решил собрать умную клетку для хомяка. Принцип работы достаточно прост: днем должен гореть зеленый свет, вечером- красный, а ночью- ничего. Относительно показаний датчика света и меняется цвет лампы, а температурный датчик включает небольшой компьютерный кулер, чтобы охлаждать клетку, когда в ней больше 32 С. Кроме того предусмотрен сбор и отправка данных через Serial-соединение, а также два режима работы, которые можно менять командами, отправляя их в COM-порт. Как раз на режимах работы и состоит проблема: при отправке единицы, микроконтроллер начинает выполнять цикл While, который проверяет равна ли единице переменная val (где val == Serial.read();). Если val перестает быть равен 1, то цикл завершается с помощью команды break. В теории то все вроде-бы понятно. Но вот как я не пытался, заставить arduino выйти из этого цикла не получается. Помогите сделать так, как было описано в теории.
    Код не влез в тему, т.к. сообщение с ним превышают ограничение в 10000 символов на формуме.
    P.S. Программа пока выглядит громоздко, т.к. писал "на черновую".
     

    Вложения:

    • IR1.zip
      Размер файла:
      1,9 КБ
      Просмотров:
      223
  2. Lagvin

    Lagvin Нерд

    Что-то не читается код.
     
  3. okuznetcov

    okuznetcov Нерд

    Тогда выложу сюда. Весь код не влезет, поэтому по частям.
    Код (Text):
    #define LED_RED 3        //дневной светодиод
    #define LED_GREEN 13    //ночной светодиод
    #define TEMP_PIN A1      //температурный датчик
    #define BUZZER 4        //пьезо-пищалка
    #define LIGHT_SENSOR A0  //датчик света
    int FAN = 7;            //вентилятор
    int val;                // переменная для данных с com-порта

    #define LIGHT_EVENING 450  //определяем световые пороги для режимов дня
    #define LIGHT_NIGHT 850
    void setup() {
      pinMode(LED_GREEN, OUTPUT); //показываем где выход/вход
      pinMode(LED_RED, OUTPUT);
      pinMode(BUZZER, OUTPUT);
      pinMode(FAN, OUTPUT);
      pinMode(LIGHT_SENSOR, INPUT);
      pinMode(TEMP_PIN, INPUT);

      Serial.begin(9600);  // запускаем serial-соединение
    }

    void loop() {
    // переводим информацию с термометра в нормальные значения
      float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN);
      float temp_c = ( voltage - 0.5 ) * 100;
      val = Serial.read(); //данные с Serial будем хранить в переменной val

      if (val == '0') {  //главное меню
        Serial.println("------------------------------------------");
        Serial.println("- Hello! Welcome to Hamster Smart Cage! -");
        Serial.println("-      Press 1 to go to auto mode      -");
        Serial.println("-      Press 2 to go to manual mode      -");
        Serial.println("------------------------------------------");
      }
     
    Последнее редактирование: 18 май 2015
  4. okuznetcov

    okuznetcov Нерд

    И вторая часть:
    Код (Text):
    if (val == '2') {  //меню ручного управления
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
      }
       
        if (val == '4') {  // если нажимаем 4, охлаждение выключается
        digitalWrite(FAN, LOW);
       
        Serial.println("Fan is OFF");
        Serial.print("Temperature: ");
        Serial.println(temp_c);
       
        delay(1000);
       
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
        if (val == '3') {  // если нажимаем 3, охлаждение включается
        digitalWrite(FAN, HIGH);
       
        Serial.println("Fan is ON");
        Serial.print("Temperature: ");
        Serial.println(temp_c);
       
        delay(1000);
       
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
     
        if (val == '6') {  // если нажимаем 6, светодиод выключается
        digitalWrite(LED_RED, LOW);
        Serial.println("Red LED is OFF");
       
        delay(1000);
       
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
        if (val == '5') {  // если нажимаем 5, светодиод включается
        digitalWrite(LED_RED, HIGH);
        Serial.println("Red LED is ON");
       
        delay(1000);
       
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
        if (val == '8') {  // если нажимаем 8, светодиод выключается
        digitalWrite(LED_GREEN, LOW);
        Serial.println("Green LED is OFF");
       
        delay(1000);
       
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
        if (val == '7') {  // если нажимаем 7, светодиод вкключается
        digitalWrite(LED_GREEN, HIGH);
        Serial.println("Green LED is ON");
         
        delay(1000);
         
        Serial.println("---------------------------------------");
        Serial.println("-      Welcome to manual mode!        -");
        Serial.println("-  Press 1 to swich to the auto mode  -");
        Serial.println("                                      ");
        Serial.println("-    Press 3 to swich on the FAN      -");
        Serial.println("-    Press 4 to swich off the FAN    -");
        Serial.println("                                      ");
        Serial.println("-  Press 5 to swich on the Red led  -");
        Serial.println("-  Press 6 to swich OFF the Red led  -");
        Serial.println("                                      ");
        Serial.println("-  Press 7 to swich on the Green led  -");
        Serial.println("-  Press 8 to swich OFF the Green led -");
        Serial.println("---------------------------------------");
        }
      while (val == '1') { // если val равно 1, гоняем этот цикл:
      // еще раз переводим информацию с термометра в нормальные значения
      float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN);
      float temp = ( voltage - 0.5 ) * 100;
     
      delay(1000); //ждем, чтобы не бомбить значениями com-порт
     
      int light = analogRead(LIGHT_SENSOR); //читаем информацию с датчика освещенности
      if (temp < 32) {
      digitalWrite(FAN, LOW); // навсякий случай выключаем вентилятор
     
      Serial.print("Temperature: "); //если температура меньше 32, отправляем данные
      Serial.println(temp);
     
      Serial.print("Light: ");
      Serial.println(light);
     
    //------------------------------------------------------------------------
    // освещение (изменяем свет в зависимости от времени суток)
      int ledLevel = map(light, LIGHT_EVENING, LIGHT_NIGHT, 180, 0);
     
      if (light < LIGHT_EVENING && light < LIGHT_NIGHT) {  // день
        digitalWrite(LED_GREEN, HIGH);
        digitalWrite(LED_RED, LOW);
        Serial.print("Day mode: ");
        Serial.println("Day");
      }
      if (light > LIGHT_EVENING && light < LIGHT_NIGHT) { // вечер
        digitalWrite(LED_GREEN, LOW);
        analogWrite(LED_RED, ledLevel);
        Serial.print("Day mode: ");
        Serial.println("Evening");
      }
      if (light > LIGHT_EVENING && light > LIGHT_NIGHT) { // ночь
        digitalWrite(LED_GREEN, LOW);
        digitalWrite(LED_RED, LOW);
        Serial.print("Day mode: ");
        Serial.println("Night");
      }
    //------------------------------------------------------------------------
    }
      if (temp > 32) { // если критическая температура, то
        digitalWrite(FAN, HIGH);  //включаем охлождение
        tone(BUZZER, 500, 300);  //пищим зуммером
        Serial.println("ALERT!"); //пишем alert в com-порт
        digitalWrite(LED_RED, HIGH);
        delay(300);
        digitalWrite(LED_RED, LOW);
        delay(300);
        digitalWrite(LED_GREEN, HIGH);
        delay(300);
        digitalWrite(LED_GREEN, LOW);
        delay(300);
      }
     
      val == Serial.read();  //сохраняем значения с com-порта в val
     
      if (val == '2') {  //если val равен 2, выходим из цикла While
        break;
      }
      }  //закрываем цикл While
      delay(1000);
    }
     
     
  5. okuznetcov

    okuznetcov Нерд

    Фото конструкции:
     

    Вложения:

    • IMG_4150-2.jpg
      IMG_4150-2.jpg
      Размер файла:
      749,1 КБ
      Просмотров:
      698
  6. Megakoteyka

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

    Раз:
    Код (Text):
    void PrintInstruction()

    {
      Serial.println("---------------------------------------");
      Serial.println("-      Welcome to manual mode!        -");
      Serial.println("-  Press 1 to swich to the auto mode  -");
      Serial.println("                                      ");
      Serial.println("-    Press 3 to swich on the FAN      -");
      Serial.println("-    Press 4 to swich off the FAN    -");
      Serial.println("                                      ");
      Serial.println("-  Press 5 to swich on the Red led  -");
      Serial.println("-  Press 6 to swich OFF the Red led  -");
      Serial.println("                                      ");
      Serial.println("-  Press 7 to swich on the Green led  -");
      Serial.println("-  Press 8 to swich OFF the Green led -");
      Serial.println("---------------------------------------");
    }
    Для вывода текста вызывайте PrintInstruction().
     
  7. okuznetcov

    okuznetcov Нерд

    Да, это сильно упростит код. А что на счёт break?
     
  8. Megakoteyka

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

    Два:
    Код (Text):
    #define LED_RED 3        //дневной светодиод
    #define LED_GREEN 13    //ночной светодиод
    #define TEMP_PIN A1      //температурный датчик
    #define BUZZER 4        //пьезо-пищалка
    #define LIGHT_SENSOR A0  //датчик света
    int FAN = 7;            //вентилятор
    int val;                // переменная для данных с com-порта

    #define LIGHT_EVENING 450  //определяем световые пороги для режимов дня
    #define LIGHT_NIGHT 850

    void setup() {
      pinMode(LED_GREEN, OUTPUT); //показываем где выход/вход
      pinMode(LED_RED, OUTPUT);
      pinMode(BUZZER, OUTPUT);
      pinMode(FAN, OUTPUT);
      pinMode(LIGHT_SENSOR, INPUT);
      pinMode(TEMP_PIN, INPUT);

      Serial.begin(9600);  // запускаем serial-соединение
    }

    void loop()
    {
      // переводим информацию с термометра в нормальные значения
      float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN);
      float temp = ( voltage - 0.5 ) * 100;
      int light = analogRead(LIGHT_SENSOR); //читаем информацию с датчика освещенности

      if(Serial.available() > 0)// считываем данные только тогда, когда они есть
        val = Serial.read();

      switch(val)
      {
      case '0'://главное меню
        Serial.println("------------------------------------------");
        Serial.println("- Hello! Welcome to Hamster Smart Cage! -");
        Serial.println("-      Press 1 to go to auto mode      -");
        Serial.println("-      Press 2 to go to manual mode      -");
        Serial.println("------------------------------------------");
        break;

      case '1':
        if (temp < 32)//если температура меньше 32, отправляем данные
        {
          digitalWrite(FAN, LOW); // на всякий случай выключаем вентилятор

          Serial.print("Temperature: ");
          Serial.println(temp);
          Serial.print("Light: ");
          Serial.println(light);

          //------------------------------------------------------------------------
          // освещение (изменяем свет в зависимости от времени суток)
          int ledLevel = map(light, LIGHT_EVENING, LIGHT_NIGHT, 180, 0);

          if (light < LIGHT_EVENING && light < LIGHT_NIGHT)// день
          {
            digitalWrite(LED_GREEN, HIGH);
            digitalWrite(LED_RED, LOW);
            Serial.print("Day mode: ");
            Serial.println("Day");
          }
          if (light > LIGHT_EVENING && light < LIGHT_NIGHT)// вечер
          {
            digitalWrite(LED_GREEN, LOW);
            analogWrite(LED_RED, ledLevel);
            Serial.print("Day mode: ");
            Serial.println("Evening");
          }
          if (light > LIGHT_EVENING && light > LIGHT_NIGHT)// ночь
          {
            digitalWrite(LED_GREEN, LOW);
            digitalWrite(LED_RED, LOW);
            Serial.print("Day mode: ");
            Serial.println("Night");
          }
          //------------------------------------------------------------------------
        }
        if (temp > 32)// если критическая температура, то
        {
          digitalWrite(FAN, HIGH);  //включаем охлождение
          tone(BUZZER, 500, 300);  //пищим зуммером
          Serial.println("ALERT!"); //пишем alert в com-порт
          digitalWrite(LED_RED, HIGH);
          delay(300);
          digitalWrite(LED_RED, LOW);
          delay(300);
          digitalWrite(LED_GREEN, HIGH);
          delay(300);
          digitalWrite(LED_GREEN, LOW);
          delay(300);
        }
        break;

      case '2'://меню ручного управления
        PrintInstruction();
        break;

      case '3':// если нажимаем 3, охлаждение включается
        digitalWrite(FAN, HIGH);
        Serial.println("Fan is ON");
        Serial.print("Temperature: ");
        Serial.println(temp);
        PrintInstruction();
        break;

      case '4':// если нажимаем 4, охлаждение выключается
        digitalWrite(FAN, LOW);
        Serial.println("Fan is OFF");
        Serial.print("Temperature: ");
        Serial.println(temp);
        PrintInstruction();
        break;

      case '5':// если нажимаем 5, светодиод включается
        digitalWrite(LED_RED, HIGH);
        Serial.println("Red LED is ON");
        PrintInstruction();
        break;

      case '6':// если нажимаем 6, светодиод выключается
        digitalWrite(LED_RED, LOW);
        Serial.println("Red LED is OFF");
        PrintInstruction();
        break;

      case '7':// если нажимаем 7, светодиод вкключается
        digitalWrite(LED_GREEN, HIGH);
        Serial.println("Green LED is ON");
        PrintInstruction();
        break;

      case '8':// если нажимаем 8, светодиод выключается
        digitalWrite(LED_GREEN, LOW);
        Serial.println("Green LED is OFF");
        PrintInstruction();
        break;
      }

      delay(1000);
    }

    void PrintInstruction()
    {
      Serial.println("---------------------------------------");
      Serial.println("-      Welcome to manual mode!        -");
      Serial.println("-  Press 1 to swich to the auto mode  -");
      Serial.println("                                      ");
      Serial.println("-    Press 3 to swich on the FAN      -");
      Serial.println("-    Press 4 to swich off the FAN    -");
      Serial.println("                                      ");
      Serial.println("-  Press 5 to swich on the Red led  -");
      Serial.println("-  Press 6 to swich OFF the Red led  -");
      Serial.println("                                      ");
      Serial.println("-  Press 7 to swich on the Green led  -");
      Serial.println("-  Press 8 to swich OFF the Green led -");
      Serial.println("---------------------------------------");
    }
     
    okuznetcov нравится это.
  9. Megakoteyka

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

    А break в цикле while вообще не нужен. Цикл сам завершится, когда условие перестанет выполняться.
    В вашем случае и сам цикл не нужен.
    Нажимайте Ctrl+T для автоматического форматирования кода.
     
  10. okuznetcov

    okuznetcov Нерд

    Все хорошо, за исключением того, что при отправке единицы, case 1 должен крутиться постоянно, пока в COM-порт не послать, скажем, двойку.
     
  11. Megakoteyka

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

    А он и будет крутиться. Переменная val меняет свое значение толь при приходе новых данных. При каждом проходе loop крутится та ветка, которая соответствует val.
     
  12. okuznetcov

    okuznetcov Нерд



    не получается. Значение показывается один раз, но не обновляется
     
  13. okuznetcov

    okuznetcov Нерд

    Все, сам въехал как сделать циклическое повторение: убрал break;, поставил вторичное считывание Serial в val и добавил delay(1000) чтобы не бомбить com-порт. В итоге, в конце case 1 получилось следующее:
    Код (Text):
    val == Serial.read();
        delay(1000);
    Напоследок, выражаю огромную благодарность Megakoteyka. Демонстрация работы устройства:


    Код (Text):
    Использовалось:
    1. Iskra Neo
    2. Troyka Shield
    3. Relay Shield
    4. Аналоговый термометр
    5. Красный светодиод
    6. Зеленый светодиод
    7. Зуммер (пьезо-пищалка)
    8. Датчик освещенности
    9. Провода 1mm
    10. Зарядка от мобильного телефона (9V, 500mA)
    11. Компьютерный кулер Tornado (2000 об/мин; 12V)
    12. Трехпроводные шлейфы
    13. USB-удлинитель 3 метра
     
  14. DrProg

    DrProg Вечный нерд

    Разве
    Код (Text):
    val == Serial.read();
    считывает из серийного порта? Двойное равно не присваивает, а сравнивает, или я не прав?
     
  15. geher

    geher Гуру

    Строка программы
    val == Serial.read();
    бесследно убирает один байт из данных, идущих по последовательному порту (если он там имеется, естественно).
    Эквивалентно просто Serial.read(); , поскольку результат сравнения никак не используется.