Установить длительность включенного состояния выхода

Тема в разделе "Arduino & Shields", создана пользователем MESS, 12 янв 2016.

  1. sanik

    sanik Гик

    Да действительно попутал :) Придется биологию заново учить.
     
  2. MESS

    MESS Гик

    Не совсем неправ, скорее неточен. Фотосинтез - это процесс роста клеток (условно), который начавшись, не может прерваться.
    Поэтому в темноте росток как бы ищет солнце, тянется к нему. Отсюда и выражение - "растет в темноте". Но это я примитивно выразился.
    Все растет и всегда. Не будет света совсем - вытянется бесцветная хилая ниточка - это и есть синтез без фото.
     
    Последнее редактирование: 13 янв 2016
  3. MESS

    MESS Гик

    Это правильно приучать к конкретному делу. Я могу оценить по фотографиям, что луку явно не хватает правильного синего (440нм) света. У него очень слабая корневая система, поэтому он худенький. Кстати лук и салат - не показательные растения. Они малотребовательны, а вот укроп - это сложно!
    При этом для роста, важна не сама температура, а обязательное наличие перепада температур: день - ночь. хотя бы 3-4гр. И влажность не менее 60%
    Дочке привет! пусть задает вопросы, если интересно и сделает более крутую презентацию по досветке растений. Я помогу.
     
    Последнее редактирование: 13 янв 2016
  4. MESS

    MESS Гик

    Отвлекся на любимую тему, а задачку пока не решил. Выполнил рекомендации sanik и вставил цикл While(millis(). В результате этот цикл выполняется непрерывно, а регулятор не реагирует на изменение температуры.
    Я вставил свои условия в тело цикла. Может в этом ошибка?
    Я предполагал что нужно начинать считать секунды с момента начала выполнения условия, а прекращать по истечении заданного интервала. Значит цикл вставлять после условия ?
    Правильно ли мыслю?
    Вот мой код
    Код (C++):
     //РЕГУЛЯТОР на 5110 с дополнением sanik
    #include <OneWire.h>
    #include <LCD5110_Basic.h>
    LCD5110 myGLCD(3,4,5,6,7);
    OneWire ds(8);
    extern uint8_t BigNumbers[];
    extern uint8_t SmallFont[];
    //Переменные для таймера
    unsigned long currentTime;
    unsigned long Otshet; // время отсчетное
    #define timeHeat 1 // время время открытия в минутах

    #define FORTON 13 // выход для команды на открытие форточки
    #define FORTOFF 10 // на закрытие форточки



    void setup(){
    myGLCD.InitLCD();
    pinMode(FORTON, OUTPUT);
    pinMode(FORTOFF, OUTPUT);
    }

    void loop(){
    byte addr[8];
    if ( !ds.search(addr)) { ds.reset_search(); }
    ds.reset();
    ds.select(addr);
    ds.write(0x44); //0x44 провести измерение температуры и записать данные в оперативную память

    ds.reset(); //
    ds.select(addr);
    ds.write(0xBE); //

    float temperature = (ds.read() | (ds.read()<<8)) / 16.0 ;
    myGLCD.setFont( BigNumbers);
    myGLCD.printNumF(temperature, 2, CENTER, 0);

    currentTime = millis(); // считываем время, прошедшее с момента запуска программы
    Otshet = currentTime; // записываем новое время
    //***************************************
    // ОТКРЫТИЕ ФОРТОЧКИ

    if (temperature >26) {
    digitalWrite(FORTON, 1);// форточку начать медленно открывать в течениие 3 мин.
    myGLCD.setFont(SmallFont);
    myGLCD.print("OTKR", CENTER, 40); }

    while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время

    // ЗАКРЫТИЕ
    else if (temperature < 25,30 )
    digitalWrite(FORTON, 0); //прекращаем открытие
    delay(500);
    digitalWrite(FORTOFF, 1);//форточку начать закрывать
    myGLCD.setFont(SmallFont);
    myGLCD.print("ZAKR", CENTER, 40);
    //while (millis() - currentTime <= (Otshet + (timeHeat * 1)));
    }
    Подскажите пожалуйста
     
  5. sanik

    sanik Гик

    Код (C++):
    //РЕГУЛЯТОР на 5110 с дополнением sanik
    #include <OneWire.h>
    #include <LCD5110_Basic.h>
    LCD5110 myGLCD(3,4,5,6,7);
    OneWire ds(8);
    extern uint8_t BigNumbers[];
    extern uint8_t SmallFont[];
    //Переменные для таймера
    unsigned long currentTime;
    unsigned long Otshet; // время отсчетное
    #define timeHeat 1 // время время открытия в минутах

    #define FORTON 13 // выход для команды на открытие форточки
    #define FORTOFF 10 // на закрытие форточки



    void setup(){
    myGLCD.InitLCD();
    pinMode(FORTON, OUTPUT);
    pinMode(FORTOFF, OUTPUT);
    }

    void loop(){
    byte addr[8];
    if ( !ds.search(addr)) { ds.reset_search(); }
    ds.reset();
    ds.select(addr);
    ds.write(0x44); //0x44 провести измерение температуры и записать данные в оперативную память

    ds.reset(); //
    ds.select(addr);
    ds.write(0xBE); //
    //========это работает вне цикла
    float temperature = (ds.read() | (ds.read()<<8)) / 16.0 ;
    myGLCD.setFont( BigNumbers);
    myGLCD.printNumF(temperature, 2, CENTER, 0);

    currentTime = millis(); // считываем время, прошедшее с момента запуска программы
    Otshet = currentTime; // записываем новое время
    //***************************************
    // ОТКРЫТИЕ ФОРТОЧКИ

    if (temperature >26) {
      // А это работает во время цикла я уже писал об этом
      while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время
    digitalWrite(FORTON, 1);// форточку начать медленно открывать в течениие 3 мин.
    myGLCD.setFont(SmallFont);
    myGLCD.print("OTKR", CENTER, 40);
    float temperature = (ds.read() | (ds.read()<<8)) / 16.0 ; // если надо мерять во время закрытия
    myGLCD.setFont( BigNumbers);
    myGLCD.printNumF(temperature, 2, CENTER, 0);
    }



    // ЗАКРЫТИЕ
    else if (temperature < 25,30 )
    {
    while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время
    digitalWrite(FORTON, 0); //прекращаем открытие
    delay(500);
    digitalWrite(FORTOFF, 1);//форточку начать закрывать
    myGLCD.setFont(SmallFont);
    myGLCD.print("ZAKR", CENTER, 40);
    //while (millis() - currentTime <= (Otshet + (timeHeat * 1)));
    }
     
  6. Onkel

    Onkel Гуру

    Пасиб. Имхо отсчитывать временные промежутки через millis - крайне некошерно и некомильфо. Вы можете сказать, какие вам нужны задержки и какой из таймеров (0, 1, 2) у вас не занят в коде, я , когда у меня будет ардуина на операционном столе, вам напишу. Тут дело пары минут, только мне нужно будет проверить потому что я обычно пишу код прямо в с и нужно будет перевести в ардуинские функции, ну по мелочам - названия функций прерывания по таймерам разные и прочая мелочь.
     
    MESS и ИгорьК нравится это.
  7. sanik

    sanik Гик

    Задача изначально была задержать код пока открываются форточки Что я и сделал
     
  8. sanik

    sanik Гик

    Я выполнил задачу которая была поставлена изначально вам нужно было открыть форточку до конца если это не так напишите что должно и как выполняться может у вас задумано форточку гонять туда сюда от температуры тогда вам нужны условия с разбросом температуры чтоб контролер не махал форточкой а закрывал при одной температуре а открывал при другой и что еще надо делать пока закрывается форточка об этом не было сказано. И еще прочитайте все сообщения которые я писал про цикл.
     
  9. sanik

    sanik Гик

    Для выполнения всего кода в момент закрытия форточки это будет выглядеть так. Такое же условие и при закрытии форточки
    Код (C++):
    //РЕГУЛЯТОР на 5110 с дополнением sanik
    #include <OneWire.h>
    #include <LCD5110_Basic.h>
    LCD5110 myGLCD(3, 4, 5, 6, 7);
    OneWire ds(8);
    extern uint8_t BigNumbers[];
    extern uint8_t SmallFont[];
    //Переменные для таймера
    unsigned long currentTime;
    unsigned long Otshet; // время отсчетное
    #define timeHeat 1 // время время открытия в минутах

    #define FORTON 13 // выход для команды на открытие форточки
    #define FORTOFF 10 // на закрытие форточки



    void setup() {
      myGLCD.InitLCD();
      pinMode(FORTON, OUTPUT);
      pinMode(FORTOFF, OUTPUT);
    }

    void loop() {
      byte addr[8];
      if ( !ds.search(addr)) {
        ds.reset_search();
      }
      ds.reset();
      ds.select(addr);
      ds.write(0x44); //0x44 провести измерение температуры и записать данные в оперативную память

      ds.reset(); //
      ds.select(addr);
      ds.write(0xBE); //

      float temperature = (ds.read() | (ds.read() << 8)) / 16.0 ;
      myGLCD.setFont( BigNumbers);
      myGLCD.printNumF(temperature, 2, CENTER, 0);

      currentTime = millis(); // считываем время, прошедшее с момента запуска программы
      Otshet = currentTime; // записываем новое время
      //***************************************
      // ОТКРЫТИЕ ФОРТОЧКИ

      if (temperature > 26) { // если условие верно то выполняется тело цикла если ложь то  ////        //читается следующее условие
        if (currentTime >= (Otshet + (timeHeat * 60000)))//идет отсчет 60000 мкс это одна минута
          digitalWrite(FORTON, 1);// форточку начать медленно открывать в течениие 3 мин.
        myGLCD.setFont(SmallFont);
        myGLCD.print("OTKR", CENTER, 40);
      }

      //while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время

      // ЗАКРЫТИЕ
      else if (temperature < 25, 30 )
        digitalWrite(FORTON, 0); //прекращаем открытие
      delay(500);
      digitalWrite(FORTOFF, 1);//форточку начать закрывать
      myGLCD.setFont(SmallFont);
      myGLCD.print("ZAKR", CENTER, 40);
      //while (millis() - currentTime <= (Otshet + (timeHeat * 1)));
    }
     
  10. MESS

    MESS Гик

    sanik ! Огромное Вам спасибо за подмогу. Да, на первом этапе мне нужно только ограничить время включенного состояния привода и ничего более. Вы все это сделали , скетч без проблем компилируется, но я не разобрался до конца с тем что происходит. То что задержка есть я вижу, но не ощущаю - не привык к виртуальной реальности, нужна реальность. Сегодня после работы по-быстрому сваяю реальный макет с подключением движка и тогда смогу осознать что происходит. Результат доложу.
     
  11. sanik

    sanik Гик

    Что бы разобраться что происходит прочитайте ветку полностью пока вас не было я много оставил сообщений с объяснениями.
     
  12. MESS

    MESS Гик

    К сожалению не могу заняться тем что обещал. - жуткая авария на лифте выбила из колеи. Постоянные звонки и переговоры коллег по этому поводу. Я ведь участвовал в пуско-наладке этих лифтов в начале 2000-ных. Там были и французские и питерские лифты. Руковводители стройки были бандюганы отпетые. Монтаж вели иногородние из Питера и гастарбайтеры. Проблем с пуском было очень много. Но лифты заработали. когда приняли не знаю.
    Вырвало отводной блок и кабина на двух тросах из пяти, дернула противовес (15 этажей выше должен быть) он рассыпался и его блоки упали на кабину, разбили ее в хлам, пол наклонился, погибшая выпала из кабины. Страшная смерть. Не могу в себя прийти. так не должно было быть.
    Сейчас нашли стрелочника -электромеханика. Конечно он в чем то виновен, но на самом деле виновата порушенная 9 лет назад, система государственного контроля за техническим состоянием в лице Ростехнадзора.
     
  13. sanik

    sanik Гик

    Дааа! Хорошо у меня в доме 2 этажа.
     
  14. MESS

    MESS Гик

    Сварганил и стал испытывать. По внешним признакам -все работает после подачи питания. Пальцем грею датчик выше 26 - не сразу, но начинает открывать, затем остыв - закрывает. Действительно дисплей не помощник- сбивает с толку своими надписями и я поставил контрольные светики на выходные пины. Оказалось, что при пороге открытия на пине 10 уровень"1", а на выходе закрытия вместо "0" короткие импульсы "1".
    При снижении температуры в промежуток гистерезиса ( от 26 до 24 гр), на пине 10 четкий "0" ,а на выходе закрытия (пин13) "1".
    Экспериментирую с первоначальным скетчем который без задержек. Нужно гарантированно вырубить закрытие при открытии. На аппаратном уровне -это простая взвимоблокировка, а в скетчу как это сказать -пока не знаю. 20160116_220246.jpg
     
    Последнее редактирование: 16 янв 2016
  15. MESS

    MESS Гик

    Код (C++):
    //РЕГУЛЯТОР на 5110 с дополнением sanik
    #include <OneWire.h>
    //#include <LCD5110_Basic.h>
    //LCD5110 myGLCD(3,4,5,6,7);
    OneWire ds(8);
    extern uint8_t BigNumbers[];
    extern uint8_t SmallFont[];
    //Переменные для таймера
    unsigned long currentTime;
    unsigned long Otshet; // время отсчетное
    #define timeHeat 0.02 // время время открытия в минутах

    #define FORTON 13 // выход для команды на открытие форточки
    #define FORTOFF 10 // на закрытие форточки



    void setup(){
    //myGLCD.InitLCD();
    pinMode(FORTON, OUTPUT);
    pinMode(FORTOFF, OUTPUT);
    }

    void loop(){
    byte addr[8];
    if ( !ds.search(addr)) { ds.reset_search(); }
    ds.reset();
    ds.select(addr);
    ds.write(0x44); //0x44 провести измерение температуры и записать данные в оперативную память

    ds.reset(); //
    ds.select(addr);
    ds.write(0xBE); //
    //========это работает вне цикла
    float temperature = (ds.read() | (ds.read()<<8)) / 16.0 ;
    //myGLCD.setFont( BigNumbers);
    //myGLCD.printNumF(temperature, 2, CENTER, 0);

    currentTime = millis(); // считываем время, прошедшее с момента запуска программы
    Otshet = currentTime; // записываем новое время
    //***************************************
    // ОТКРЫТИЕ ФОРТОЧКИ

    if (temperature >=26)
    {
      // А это работает во время цикла я уже писал об этом
      while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время
    digitalWrite(FORTOFF, 0);
    digitalWrite(FORTON, 1);// форточку начать медленно открывать в течениие 3 мин.
    //myGLCD.setFont(SmallFont);
    //myGLCD.print("OTKR", CENTER, 40);
    float temperature = (ds.read() | (ds.read()<<8)) / 16.0 ; // если надо мерять во время закрытия
    //myGLCD.setFont( BigNumbers);
    //myGLCD.printNumF(temperature, 2, CENTER, 0);
    }

    // ЗАКРЫТИЕ

      else if (temperature <= 24)
    while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время
    digitalWrite(FORTON, 0); //прекращаем открытие
    delay(1500);
    digitalWrite(FORTOFF, 1);//форточку начать закрывать
    //myGLCD.setFont(SmallFont);
    //myGLCD.print("ZAKR", CENTER, 40);

    }
     
    Этот скетч с выдержкой работает, но полностью блокировать импульсы закрытия, при открывании, не удается. У меня еще вопрос: можно ли дать команду полностью запретить включения привода в гистерезисе?
    И еще -
    #define timeHeat 0.02 // это какое время время открытия я накрутил?
     
  16. Onkel

    Onkel Гуру

    Это стандартная ситуация в окнах, экранах, шторах и пр. Делается так- один выход на подачу напряжения. второй выход - на переключение вверх / вниз. Блокировка получается сама собой.
     
  17. sanik

    sanik Гик

    timeHeat * 60000 надо умножать 60 тыс чтоб получить минуту Я думаю во время закрытия нет смыла мерить температуру за три минуты ничего не случиться millis() меряет время в миллисекундах в одной секунде 1000 милисекунд в условии if(temperature >=26) можно задать диапазон температур от и до тот же гистерезис получиться
     
    MESS нравится это.
  18. sanik

    sanik Гик

    Лучше всего форточку открывать до конца а потом уже закрывать если температура упала и конечно избавиться от delay();
     
  19. MESS

    MESS Гик

    Считаю, что взаимоблокировка более надежна, потому что уже не уверен, что во время работы движка уровень выхода направления не сбойнет! Однако попробую, спасибо.
     
    Последнее редактирование: 17 янв 2016
  20. MESS

    MESS Гик

    Как объект регулирования температуры парник очень инерционный и время открытого состояния будет измеряться сотнями минут, поэтому все принимаю как есть.
    Однако эксперимент помог увидеть разницу между жесткой логикой и программируемой в смысле целесообразности. Видимо для такого простого действа, как терморегулятор надежнее и проще термоконтакта ничего нет:) Без дисплея ардуина неинтересна. Конечно буду доводить скетч, может дисплей придется защищать, чтобы не мешал ардуине. Благодарю за терпение и помощь.