Ошибка в программе - помогите решить :(

Тема в разделе "Arduino & Shields", создана пользователем Djvan, 26 янв 2015.

  1. Djvan

    Djvan Нерд

    Здравствуйте. Помогите мне найти ошибку в программе – или подскажите, как поправить. В общем сделал я контроллер для аквариума:

    5 реле, датчик температуры, часы реального времени, инфракрасный приемник. В общем в зависимости от режима работы (флаг света = 0 – автоматический режим, =1 – включен, =0 –выключен, и флаг остального оборудования так же.) происходило управление –если режим авто – то соответственно свет включался и выключался в заданное время и оборудование тоже включалось по определенным условиям – в зависимости от температуры или времени. Переключение флага сделал через инфракрасный пульт (по умолчанию, после включения питания все флаги стоят в авторежиме)

    и все нормально работало – но потом решил добавить блок синезуба, чтобы с телефона можно было управлять. Соответственно удалил или закоментил все выводы в сериал порт, кроме показ температуры (чтобы программа на андроиде получала по сериалу эти циферки и показывала). Далее ввел дополнительные условия полученных данных из серала (строки после войд луп и до условия с пульта ИР) телефон передавал цифры от 0 до 6 – и соответственно по этим цифрам менялись флаг света и оборудования. Но тут устройство затупило. Вероятно я все это очень криво сделал, или где то накосячил с { }. В общем симптомы такие – на пульт вообще не реагирует, при нажатии кнопки в программе андроида (передача сигналов 1-6, 0 устанавливается первоначально) периодически щелкает реле и показывает температуру в программе (нажал кнопку – через пару секунд поменялась температура) – в общем ощущение, что условия у меня пошли как то неправильно работать. В общем товарищи – подскажите, что нужно поменять – или где я накосячил?????

    Файл для андроид в mit app inventor http://vk.com/doc3522071_361298844?hash=74b5dfefd79f791305&dl=9258df8293097fd561


    Код (Text):
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <Wire.h>
    #include <DS1307new.h>
    #include <IRremote.h>


    #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры

    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    //для часиков
    uint16_t startAddr = 0x0000;            // Начальный адрес для хранения в NV-RAM
    uint16_t lastAddr;                      // новый адрес для хранения в NV-RAM
    uint16_t TimeIsSet = 0xaa55;            // По этой переменной проверяется то, что время не нужно устанавливать заново

    int Relay1 = 3; //реле на нагреватель
    int Relay2 = 4; // реле на воздух
    int Relay3 = 6; // реле на фильтр
    int Relay4 = 7; // реле на свет
    int Relay5 = 8; // реле на кулеры
    int  theat=24;  //температура при которой включается нагреватель
    int  tcool=29;  //температура при которой включается кулер
    int svet = 0;  //флаг по умолчанию равен нулю - свет
    int oborud = 0;  //флаг по умолчанию равен нулю - все остальное оборудование
    int av=0;//флаг по умолчанию равен одному - auto режим
    int vkl = 9;  //время (в часах), когда включается свет - первый интервал
    int vykl = 15; //время (в часах), когда выключается свет  второй интервал
    int vkl2 = 18;  //время (в часах), когда включается свет - второй интервал
    int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал
    int vklvozduh = 4; //время (в часах), когда включается компрессор
    int vyklvozduh = 6; //время (в часах), когда включается компрессор
    int RECV_PIN = 11; // пин на инфракрасный приемник
    char incomingByte; // переменная для входящих значений по сериал порту

    // Инициализация ИК приемника
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup(void)
    {
        pinMode(Relay1, OUTPUT);  //ставим силовые реле на выход
        pinMode(Relay2, OUTPUT);
        pinMode(Relay3, OUTPUT);
        pinMode(Relay4, OUTPUT);
        pinMode(Relay5, OUTPUT);
      digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW
      digitalWrite(4, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
     
      Serial.begin(9600);
      irrecv.enableIRIn(); // Включение IR приемника
      int on = 0; // для IR
      unsigned long last = millis(); // для IR
    // Запускаем наши часики (RTC)
    RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));
      RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
      if (TimeIsSet != 0xaa55)
      {
        RTC.stopClock();
           
        RTC.fillByYMD(2015,01,24); //устанавливаем дату
        RTC.fillByHMS(23,57,0); //устанавливаем время
        RTC.setTime();
        TimeIsSet = 0xaa55;
        RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
        RTC.startClock();  }
      else
      { RTC.getTime();  }
      RTC.setCTRL();
      sensors.begin(); }

    void loop(){
    if (Serial.available() > 0) {  // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги
        incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл
        if(incomingByte == '0') { // 6 - оборудование выкл
        oborud=0;
        svet=0;
        }
        if(incomingByte == '1') {
        svet=0;
    }

        incomingByte = Serial.read();
        if(incomingByte == '2') {
        svet=1;
        }
        if(incomingByte == '3') {
        svet=2;
    }
        incomingByte = Serial.read();
        if(incomingByte == '4') {
        oborud=0;
        }
        if(incomingByte == '5') {
        oborud=1;
    }
    if(incomingByte == '6') {
        oborud=2;
    }



    {if (irrecv.decode(&results)) { ///Далее идет код проверки IR датчика
    //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код...(если надо узнать код - раскоменте)
    if (results.value==3672802284) {// Кнопка "A" - переключает режимы света поменяйте на свой код кнопки
      if (svet==0) { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
        svet=1;}
      else
      if (svet==1) {
        svet=2;}
        else{
        svet=0;}
    }

    if (results.value==732942060) {// Кнопка "B" - включает и отключает оборудование поменяйте на свой код
    if (oborud==0) {//устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
        oborud=1;}
      else
      if (oborud==1) {
        oborud=2;}
        else{
        oborud=0;}
    }
    irrecv.resume(); // Получение нового значения через пульт
    }

    switch (svet) { //блок управления светом
          case 2:// если свет выключен
            //Serial.println("Svet vykluchen");
            digitalWrite(7, HIGH);
            break;
          case 1:// если свет включен
            //Serial.println("Svet vkluchen");
            digitalWrite(7, LOW);
            break;
            case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
          //Serial.println("Svet auto");
            RTC.getTime();
            if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) )  // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем
            {digitalWrite(7, LOW);}
          else
          {digitalWrite(7, HIGH);}
            break;  }  

    switch (oborud) { //блок управления оборудованием (кроме света)
          case 2:// если все оборудование выключено
          // Serial.println("Oborudovanie vykluchen");
            digitalWrite(3, HIGH);
            digitalWrite(4, HIGH);
            digitalWrite(6, HIGH);
            digitalWrite(8, HIGH);
            break;
          case 1:// если все оборудование включено
          // Serial.println("Oborudovanie vkluchen");
            digitalWrite(3, LOW);
            digitalWrite(4, LOW);
            digitalWrite(6, LOW);
            digitalWrite(8, LOW);
            break;
          case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
            //Serial.println("Oborudovanie auto");
            digitalWrite(6, LOW); //фильтр включен всегда
            sensors.requestTemperatures(); // запрашиваем данные датчика температуры
            float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика
            if (temp< theat){ //если температура меньше theat то включить нагреватель, иначе - выключить
              digitalWrite(3, LOW);}
            else {
              digitalWrite(3, HIGH);}
            sensors.requestTemperatures();// запрашиваем данные датчика температуры
            if (temp>tcool){ //если температура больше tcool то включить кулеры, иначе - выключить
              digitalWrite(4, LOW);}
            else {
              digitalWrite(4, HIGH);}
            Serial.println(temp);
            RTC.getTime();// запрашиваем время
            if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh)  // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :)
            {digitalWrite(8, LOW);}
          else
          {digitalWrite(8, HIGH);}
            break;  }  
         
    }}}
     
  2. Alex19

    Alex19 Гуру

    Не экономьте время, при написании программы, очень важно, удобство чтения кода. Вот как правильно должен выглядеть Ваш код (не вносил изменений, только отступы и привел скобочки к более наглядному виду), в таком коде сложнее ошибиться.
    Код (Text):

    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <Wire.h>
    #include <DS1307new.h>
    #include <IRremote.h>


    #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры

    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    //для часиков
    uint16_t startAddr = 0x0000;            // Начальный адрес для хранения в NV-RAM
    uint16_t lastAddr;                      // новый адрес для хранения в NV-RAM
    uint16_t TimeIsSet = 0xaa55;            // По этой переменной проверяется то, что время не нужно устанавливать заново

    int Relay1 = 3; //реле на нагреватель
    int Relay2 = 4; // реле на воздух
    int Relay3 = 6; // реле на фильтр
    int Relay4 = 7; // реле на свет
    int Relay5 = 8; // реле на кулеры
    int  theat=24;  //температура при которой включается нагреватель
    int  tcool=29;  //температура при которой включается кулер
    int svet = 0;  //флаг по умолчанию равен нулю - свет
    int oborud = 0;  //флаг по умолчанию равен нулю - все остальное оборудование
    int av=0;//флаг по умолчанию равен одному - auto режим
    int vkl = 9;  //время (в часах), когда включается свет - первый интервал
    int vykl = 15; //время (в часах), когда выключается свет  второй интервал
    int vkl2 = 18;  //время (в часах), когда включается свет - второй интервал
    int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал
    int vklvozduh = 4; //время (в часах), когда включается компрессор
    int vyklvozduh = 6; //время (в часах), когда включается компрессор
    int RECV_PIN = 11; // пин на инфракрасный приемник
    char incomingByte; // переменная для входящих значений по сериал порту

    // Инициализация ИК приемника
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup(void)
    {
        pinMode(Relay1, OUTPUT);  //ставим силовые реле на выход
        pinMode(Relay2, OUTPUT);
        pinMode(Relay3, OUTPUT);
        pinMode(Relay4, OUTPUT);
        pinMode(Relay5, OUTPUT);
        digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW
        digitalWrite(4, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(8, HIGH);

        Serial.begin(9600);
        irrecv.enableIRIn(); // Включение IR приемника
        int on = 0; // для IR
        unsigned long last = millis(); // для IR
        // Запускаем наши часики (RTC)
        RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));
        RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
        if (TimeIsSet != 0xaa55)
        {
            RTC.stopClock();

            RTC.fillByYMD(2015,01,24); //устанавливаем дату
            RTC.fillByHMS(23,57,0); //устанавливаем время
            RTC.setTime();
            TimeIsSet = 0xaa55;
            RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
            RTC.startClock();
        }
        else
        {
            RTC.getTime();
        }
        RTC.setCTRL();
        sensors.begin();
    }

    void loop()
    {
        if (Serial.available() > 0)
        {  // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги
            incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл
            if(incomingByte == '0') // 6 - оборудование выкл
            {
                oborud=0;
                svet=0;
            }
            if(incomingByte == '1')
            {
                svet=0;
            }

            incomingByte = Serial.read();
            if(incomingByte == '2')
            {
                svet=1;
            }
            if(incomingByte == '3')
            {
                svet=2;
            }
            incomingByte = Serial.read();
            if(incomingByte == '4')
            {
                oborud=0;
            }
            if(incomingByte == '5')
            {
                oborud=1;
            }
            if(incomingByte == '6')
            {
                oborud=2;
            }



            {
                if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика
                {
                    //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код...(если надо узнать код - раскоменте)
                    if (results.value==3672802284) // Кнопка "A" - переключает режимы света поменяйте на свой код кнопки
                    {
                        if (svet==0) //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            svet=1;
                        }
                        else
                            if (svet==1)
                            {
                                svet=2;
                            }
                            else
                            {
                                svet=0;
                            }
                    }

                    if (results.value==732942060) // Кнопка "B" - включает и отключает оборудование поменяйте на свой код
                    {
                        if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            oborud=1;
                        }
                        else
                            if (oborud==1)
                            {
                                oborud=2;
                            }
                            else
                            {
                                oborud=0;
                            }
                    }
                    irrecv.resume(); // Получение нового значения через пульт
                }

                switch (svet) //блок управления светом
                {
                    case 2:// если свет выключен
                        //Serial.println("Svet vykluchen");
                        digitalWrite(7, HIGH);
                        break;
                    case 1:// если свет включен
                        //Serial.println("Svet vkluchen");
                        digitalWrite(7, LOW);
                        break;
                    case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
                        //Serial.println("Svet auto");
                        RTC.getTime();
                        if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) )  // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем
                        {
                            digitalWrite(7, LOW);
                        }
                        else
                        {
                            digitalWrite(7, HIGH);
                        }
                        break;
                }

                switch (oborud) //блок управления оборудованием (кроме света)
                {
                case 2:// если все оборудование выключено
                    // Serial.println("Oborudovanie vykluchen");
                    digitalWrite(3, HIGH);
                    digitalWrite(4, HIGH);
                    digitalWrite(6, HIGH);
                    digitalWrite(8, HIGH);
                    break;
                case 1:// если все оборудование включено
                    // Serial.println("Oborudovanie vkluchen");
                    digitalWrite(3, LOW);
                    digitalWrite(4, LOW);
                    digitalWrite(6, LOW);
                    digitalWrite(8, LOW);
                    break;
                case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
                    //Serial.println("Oborudovanie auto");
                    digitalWrite(6, LOW); //фильтр включен всегда
                    sensors.requestTemperatures(); // запрашиваем данные датчика температуры
                    float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика
                    if (temp< theat)  //если температура меньше theat то включить нагреватель, иначе - выключить
                    {
                        digitalWrite(3, LOW);
                    }
                    else
                    {
                        digitalWrite(3, HIGH);
                    }
                    sensors.requestTemperatures();// запрашиваем данные датчика температуры
                    if (temp>tcool)//если температура больше tcool то включить кулеры, иначе - выключить
                    {
                        digitalWrite(4, LOW);
                    }
                    else
                    {
                        digitalWrite(4, HIGH);
                    }
                    Serial.println(temp);
                    RTC.getTime();// запрашиваем время
                    if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh)  // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :)
                    {
                        digitalWrite(8, LOW);
                    }
                    else
                    {
                        digitalWrite(8, HIGH);
                    }
                    break;
                }
            }
        }
    }
    И сразу видим ошибки не вооруженным глазом.
     
  3. Alex19

    Alex19 Гуру

    Пришлось разбить сообщение не поместилось.

    Код (Text):
    {
                if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика
                {
    Что это, видимо был удален if но открывающие и закрывающие скобки (3-я снизу) остались.

    Код (Text):
    if (svet==0) //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            svet=1;
                        }
                        else
                            if (svet==1)
                            {
                                svet=2;
                            }
                            else
                            {
                                svet=0;
                            }
    Код (Text):
    if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            oborud=1;
                        }
                        else
                            if (oborud==1)
                            {
                                oborud=2;
                            }
                            else
                            {
                                oborud=0;
                            }
    Почему в одном случае с else Вы пользуетесь скобочками, другом нет?
    Более подробно с if else можно ознакомится тут.

    Если правильно понял мысль, на ардуину передается число от 1 до 6, тогда поменяйте работу с Serial.
    Код (Text):
    void loop()
    {
      int val = 0;
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
      }

      // Дальше Ваш код, анализирует полученное число
    }
    Дальше не смотрел, начните с этого.
     
  4. Megakoteyka

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

    Вместо
    Код (Text):
    if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            oborud=1;
                        }
                        else
                            if (oborud==1)
                            {
                                oborud=2;
                            }
                            else
                            {
                                oborud=0;
                            }
    пишите
    Код (Text):
    oborud++;
    if(oborud == 2)
      oborud = 0;
    или
    Код (Text):
    if(++oborud == 3)
      oborud = 0;
    Меньше кода, лучше читаемость.
    Аналогично с переменной svet.
     
  5. Alex19

    Alex19 Гуру

    Все верно, не перерабатывал код, просто искал ошибки.

    Но во по поводу
    Код (Text):
    if(++oborud == 3)
      oborud = 0;
    не соглашусь, мне кажется лучше будет так,
    Код (Text):

    if(++oborud == 3)
    {
        oborud = 0;
    }
     
    но как говорится дело вкуса.

    UPD.
    Ошибся по 2 пункту, это не ошибка.
    Код (Text):

    if (oborud==0) //устанавливаю режимы флага оборудования на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                        {
                            oborud=1;
                        }
                        else
                            if (oborud==1)
                            {
                                oborud=2;
                            }
                            else
                            {
                                oborud=0;
                            }
     
    Данный код рабочий, но это уже C, подробнее тут.

    Если кому интересно, можете посмотреть.
    Код (Text):
    void setup()
    {
      Serial.begin(115200);
    }

    void loop()
    {
      int val = 0;
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
        //Serial.println(val);
       
    //    if (val == 1)val++;
    //      Serial.println(val);
         
    //    if (val == 1)
    //      val++;
    //      Serial.println(val);

          if (val==0)
          {
              val++;
          }
          else
              //val++;
              if (val==1)
              {
                  val=10;
              }
              else
              {
                  val=11;
              }
         
          Serial.println(val);
      }
    }
    Но для меня он сложнее в прочтении, поэтому остаюсь при своих скобочках:).
     
    Последнее редактирование: 27 янв 2015
  6. Djvan

    Djvan Нерд

    Возможно - с программированием я не очень. Но пытаюсь разобраться через видео уроки и примеры - анализируя разные примеры смог собрать вот такую сборную солянку - для себя все откомментил (чтобы не забыть где что :)) - я так понимаю, что я как бы лишний блок сделал? т.е. третья снизу фигурная скобка закрывающая - должна быть удалена и соответсвующая ей октрывающая скобка тоже? у меня вообще со всеми этими скобками проблема -как то в бейсике в школе их не было :):):)

    в смысле когда указано (svet==0) ? лучше все эти скобки вообще убрать?

    Для анализа наверно лучше тогда воспользоваться не условием if а выбором? CASE?


    Спасибо - так действительно проще.

    Вечером попробую исправить и оптимизировать
     
  7. Djvan

    Djvan Нерд

    и еще - я так понимаю, с получением данных по bluetooth - мне лучше часть кода заменить:
    Код (Text):
    if (Serial.available() > 0) {  // далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги
        incomingByte = Serial.read(); // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл
        if(incomingByte == '0') { // 6 - оборудование выкл
        oborud=0;
        svet=0;
        }
        if(incomingByte == '1') {
        svet=0;
    }

        incomingByte = Serial.read();
        if(incomingByte == '2') {
        svet=1;
        }
        if(incomingByte == '3') {
        svet=2;
    }
        incomingByte = Serial.read();
        if(incomingByte == '4') {
        oborud=0;
        }
        if(incomingByte == '5') {
        oborud=1;
    }
    if(incomingByte == '6') {
        oborud=2;
    }
    На:

    Код (Text):
    int val = 0;
        if (Serial.available() > 0)// далее проверяет прход по сериал порту - например от bluetooth и в зависимости от цифры - выставляет флаги
        {                          // 0 - все авто. 1- свет авто, 2 - свет вкл, 3 - свет выкл, 4 - оборудование - авто, 5 оборудование вкл
        val = Serial.parseInt();  // 6 - оборудование выкл
        }

    switch (val)
      {
          case 0:
            oborud=0;
            svet=0;
          break;
          case 1:
            svet=0;
          break;
          case 2:
            svet=1;
          break;
          case 3:
            svet=2;
          break;
          case 4:
            oborud=0;
          break;
          case 5:
            oborud=1;
          break;
          case 6:
            oborud=2;
          break;
      }  
     
     
  8. Alex19

    Alex19 Гуру

    Да, остался лишний блок.

    Увы придется учится, поищите на форуме достойную книгу для начинающих. Думаю она позволит ускорить процесс обучения.

    Нет, эти скобки обязательны, типичный if можно записать несколькими способами

    Вариант 1
    Код (Text):

    if (svett==0)
    {
      i++;
    }
    Вариант 2
    Код (Text):

    if (svett==0)
      i++;
     
    Но вариант 2, не стал бы советовать начинающим. Причина в том, что он мене читабельный и может стать причиной ошибки. Предположим, что нам нужно написать условие, если svett==0, то необходимо добавить 1 к переменой i и добавить 2 к переменой e.

    Если просто добавить e+= 2; к варианту 2, он будет выполнен не так как ожидаем.
    Код (Text):

    if (svett==0)
      i++;
      e+= 2;
     
    i++; будет выполнено только если svett==0, а e+= 2; будет выполнено, не зависимо от значения переменой svett.

    А вариант 1, i++ и e+=2 будет выполнен только если svett==0
    Код (Text):

    if (svett==0)
    {
      i++;
      e+= 2;
    }
     
    Поэтому и не рекомендую, Ваш код в этом месте был рабочим но у меня не хватает знаний пояснить почему. Можете проверить, взяв мой код для теста и поиграться с вариантами.
    Код (Text):
    void setup()
    {
      Serial.begin(115200);
    }

    void loop()
    {
      int val = 0;
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
        //Serial.println(val);

    //    if (val == 1)val++;
    //      Serial.println(val);
     
    //    if (val == 1)
    //      val++;
    //      Serial.println(val);

          if (val==0)
          {
              val++;
          }
          else
              //val++;
              if (val==1)
              {
                  val=10;
              }
              else
              {
                  val=11;
              }
     
          Serial.println(val);
      }
    }
    Но лучше все таки хорошая книга.

    Да код с использованием switch и Serial.parseInt() будет более логичным.
     
    Djvan нравится это.
  9. Djvan

    Djvan Нерд

    Спасибо - со скобками разобрался.... завтра буду мучить устройство :)
     
  10. Djvan

    Djvan Нерд

    В общем программу переработал - нифига хорошего не получилось :(
    Код (Text):
    if(++oborud == 3)
    {
        oborud = 0;
    }
    С этим блоком - как то реакций не было :(

    С блоком работы сериала -
    Код (Text):
    {
      int val = 0;
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
      }

      // Дальше Ваш код, анализирует полученное число
    }
    После переключения - сразу все скидывалось на 0 - т.е. авторежим.

    Я тут еще грешу на bluetooth - он у меня какой то глючный - очень много помех идет - в сериал все четко идет, но если подключаю синезуб - помимо цифр еще куча всякого мусора - непонятные символы... Должны через пару недель новые блоки прийти - надеюсь после замены все будет хорошо... В итоге получилась программа (ниже) - которая работает в авто режиме, имеет возможность переключения режимов пультом, но не реагирует на синезуб... Может я конечно еще накосячил в программе - но вроде просмотрел все...

    Код (Text):
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <Wire.h>
    #include <DS1307new.h>
    #include <IRremote.h>


    #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры

    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    //для часиков
    uint16_t startAddr = 0x0000;            // Начальный адрес для хранения в NV-RAM
    uint16_t lastAddr;                      // новый адрес для хранения в NV-RAM
    uint16_t TimeIsSet = 0xaa55;            // По этой переменной проверяется то, что время не нужно устанавливать заново

    int Relay1 = 3; //реле на нагреватель
    int Relay2 = 4; // реле на воздух
    int Relay3 = 6; // реле на фильтр
    int Relay4 = 7; // реле на свет
    int Relay5 = 8; // реле на кулеры
    int  theat=24;  //температура при которой включается нагреватель
    int  tcool=29;  //температура при которой включается кулер
    int svet = 0;  //флаг по умолчанию равен нулю - свет
    int oborud = 0;  //флаг по умолчанию равен нулю - все остальное оборудование
    int av=0;//флаг по умолчанию равен одному - auto режим
    int vkl = 9;  //время (в часах), когда включается свет - первый интервал
    int vykl = 15; //время (в часах), когда выключается свет  второй интервал
    int vkl2 = 18;  //время (в часах), когда включается свет - второй интервал
    int vykl2 = 21; //время (в часах), когда выключается свет - второй интервал
    int vklvozduh = 4; //время (в часах), когда включается компрессор
    int vyklvozduh = 6; //время (в часах), когда включается компрессор
    int RECV_PIN = 11; // пин на инфракрасный приемник
    char incomingByte; // переменная для входящих значений по сериал порту

    // Инициализация ИК приемника
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup(void)
    {
        pinMode(Relay1, OUTPUT);  //ставим силовые реле на выход
        pinMode(Relay2, OUTPUT);
        pinMode(Relay3, OUTPUT);
        pinMode(Relay4, OUTPUT);
        pinMode(Relay5, OUTPUT);
        digitalWrite(3, HIGH);// Выключаем реле (у меня обратное реле, т.е. HIGH - выключено, LOW - включено - у кого наоборот поменяйте все HIGH на LOW
        digitalWrite(4, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(8, HIGH);

        Serial.begin(9600);
        irrecv.enableIRIn(); // Включение IR приемника
        int on = 0; // для IR
        unsigned long last = millis(); // для IR
        // Запускаем наши часики (RTC)
        RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));
        RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
        if (TimeIsSet != 0xaa55)
        {
            RTC.stopClock();

            RTC.fillByYMD(2015,01,29); //устанавливаем дату
            RTC.fillByHMS(8,50,0); //устанавливаем время
            RTC.setTime();
            TimeIsSet = 0xaa55;
            RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
            RTC.startClock();
        }
        else
        {
            RTC.getTime();
        }
        RTC.setCTRL();
        sensors.begin();
    }

    void loop()
    {
       
        if (Serial.available() > 0)
          {
          incomingByte = Serial.read();
         
              if (incomingByte==0)
                    {
                      svet=0;
                      oborud=0;
                    }
              if (incomingByte==1)
                    {
                      svet=0;                        
                    }
              if (incomingByte==2)
                    {
                      svet=1;                        
                    }
              if (incomingByte==3)
                    {
                      svet=2;                        
                    }
              if (incomingByte==4)
                    {
                      oborud=0;                        
                    }
              if (incomingByte==5)
                    {
                      oborud=1;                        
                    }
              if (incomingByte==6)
                    {
                      oborud=2;                        
                    }
          }
                if (irrecv.decode(&results)) ///Далее идет код проверки IR датчика
                {
                    //Serial.println(results.value); //вывожу код нажатой кнопки в сериал - там можете узнать свой код...
                    if (results.value==3672802284) // Кнопка "A" - переключает режимы света поменяйте на свой код кнопки
                        {
                          if (svet==0)
                            { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                              svet=1;
                                //Serial.println("svet=1");
                            }
                          else
                          if (svet==1)
                            {
                              svet=2;
                              //Serial.println("svet=2");
                            }
                          else
                            {
                              svet=0;
                              //Serial.println("svet=0");
                            }
                        }
                    if (results.value==732942060) // Кнопка "B" - включает и отключает оборудование поменяйте на свой код
                    {
                          if (oborud==0)
                            { //устанавливаю режимы флага света на последовательное переключение - 0 - auto, 1 - вкл, 2 - выкл - и далее по кругу
                              oborud=1;
                              // Serial.println("oborud=1");
                            }
                          else
                          if (oborud==1)
                            {
                              oborud=2;
                              //Serial.println("oborud=2");
                            }
                          else
                            {
                              oborud=0;
                              //Serial.println("oborud=0");
                            }
                        }
                    irrecv.resume(); // Получение нового значения через пульт
                }
       
                switch (svet) //блок управления светом
                {
                    case 2:// если свет выключен
                        digitalWrite(7, HIGH);
                        break;
                    case 1:// если свет включен
                        digitalWrite(7, LOW);
                        break;
                    case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
                        RTC.getTime();
                        if ((vkl < RTC.hour & RTC.hour < vykl) | (vkl2 < RTC.hour & RTC.hour < vykl2) )  // если время больше времени включения и меньше времени выключения (в часах), включаем свет - иначе - отключаем
                        {
                            digitalWrite(7, LOW);
                        }
                        else
                        {
                            digitalWrite(7, HIGH);
                        }
                        break;
                }

                switch (oborud) //блок управления оборудованием (кроме света)
                {
                case 2:// если все оборудование выключено
                    digitalWrite(3, HIGH);
                    digitalWrite(4, HIGH);
                    digitalWrite(6, HIGH);
                    digitalWrite(8, HIGH);
                    break;
                case 1:// если все оборудование включено
                    digitalWrite(3, LOW);
                    digitalWrite(4, LOW);
                    digitalWrite(6, LOW);
                    digitalWrite(8, LOW);
                    break;
                case 0: // оборудование в авто режиме (по умолчанию - при отключении от эл-ва автоматом включается)
                    digitalWrite(6, LOW); //фильтр включен всегда
                    sensors.requestTemperatures(); // запрашиваем данные датчика температуры
                    float temp = sensors.getTempCByIndex(0); // привязываем переменную temp к запросу датчика
                    if (temp< theat)  //если температура меньше theat то включить нагреватель, иначе - выключить
                    {
                        digitalWrite(3, LOW);
                    }
                    else
                    {
                        digitalWrite(3, HIGH);
                    }
                    sensors.requestTemperatures();// запрашиваем данные датчика температуры
                    if (temp>tcool)//если температура больше tcool то включить кулеры, иначе - выключить
                    {
                        digitalWrite(4, LOW);
                    }
                    else
                    {
                        digitalWrite(4, HIGH);
                    }
                    Serial.println(temp);
                    RTC.getTime();// запрашиваем время
                    if (vklvozduh < RTC.hour & RTC.hour < vyklvozduh)  // если время больше времени включения компрессора и меньше времени выключения компрессора (в часах), включаем пузырьки :)
                    {
                        digitalWrite(8, LOW);
                    }
                    else
                    {
                        digitalWrite(8, HIGH);
                    }
                    break;
                }
    }
     
  11. Alex19

    Alex19 Гуру

    Код (Text):
    if(++oborud == 3)

    {
        oborud = 0;
    }
    Мы прибавляем 1 к переменной oborud (++oborud) и проверяем равно ли условие 3. Чтобы данное условие сработало, до if, oborud должно равняться 2. Более подробно тут.

    Код (Text):

    int val = 0;
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
      }
    Да все правильно, просто не вникал в Ваш код, а Вы просто вставили его:), даже не разбирая.

    Предположим нам надо хранить режим в переменой и менять его в зависимости от полученных данных, тогда надо просто сделать int val = 0; глобальной переменной, вынести за пределы loop.
    Код (Text):

    int val = 0;
    void loop()
    {
      if (Serial.available()>0)
      {
        val = Serial.parseInt();
      }
    }
    Что здесь будет происходить, ардуина стартует с режимом 0, после получения команды режим меняется, примеру на 2. И до следующей смены режима он остается тем же, то есть 2-ым.

    С ним не работал.

    Удачи в проекте и изучении (Там все очень просто, если идти шаг за шагом;)).
     
  12. Djvan

    Djvan Нерд

    Это я понял - выносил за луп - все равно сбивала почему то на 0. единственный вариант был - представить val к цифре не используемой в условии - например =7 . Но в общем потом вернулся к первоначальному варианту. Так все работает, но проблема в синезубе - он сплошной мусор в эфир кидает и принимает кучу мусора. Я уже намучался с этим синезубом - с уной он вообще не хочет работать (причем как я понял, поискав в инете - у многих такая проблема бывает), вероятнее всего просто глючный. Сейчас заказал несколько разных синезубов - попробую поэксперементировать. Если через сериал команды подаю - то все переключается - специально вводил команды вывода в сериал, чтобы провести отладку.
    Это я понял - сам удивился, что не захотело нормально работать..... Хотя сейчас пытаюсь вспомнить - возможно это чисто мой глюк был (у меня там провод отсоединился, который как раз шел на пин ir, а я не заметил) - может как раз тогда я этот вариант скетча проверял :):):):) В общем - пока подключил устройство в таком режиме - а то рыбкам грустно без света и тепла :) А как придет синезуб - буду дальше шаманить - все атки хочется сделать уже нормальное устройство с возможностью управления через мобильник или планшет...


    Спасибо. я понял, что тут не сложно - главное алгоритм правильный разработать, да логику продумать... В принципе первоначальный вариант и не включал в себя управление через доп устройства (пульт, телефон) - но хотелки приходят во время еды :)