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

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

  1. sanik

    sanik Гик

    Насчет сбоев я уже писал но повторюсь можно даже проверять не застряла ли гайка на шпильке на мотор подцепить датчик тока в циклах пока открывается или закрывается форточка отслеживать силу тока и если она превысит допустимых значений останавливать моторы так же отслеживать в какую сторону крутится мотор и написать если в течении заданного времени мотор не остановился значит он не достиг конца шпильки это буде аварийная ситуация гайка застряла. Думаю это будет лучше так как контроллер уже будет знать что гайка застряла и можно предпринять для этого какое либо действие например типа крутить туда сюда пока все таки не пройдем свое расстояние.
     
  2. MESS

    MESS Гик

    Ввести обратную связь по току несложно, но пока не время. Хочу добиться того чтобы имеющийся скетч отрабатывал без непонятных импульсов на выходах нано. Может быть это и не будет мешать приводу, но уже стало интересно почему так. Это ведь не помехи - это от скетча идет. Причем пробовал несколько разных выходов. Может китай- нано непутевая. На той неделе найду другие нанки и проверю.
     
  3. sanik

    sanik Гик

    Что за импульсы? Итоговый код скинь посмотреть
     
  4. MESS

    MESS Гик

    Так в посту #55 я об этом писал. Ведь помехи на выходе не появляются произвольно.
     
  5. sanik

    sanik Гик

    Перереши для начала код и проверь импульсы из за этого while(millis()- currentTime <=(Otshet +(timeHeat *1))) цикл while поставлен на одну микросекунду
     
  6. sanik

    sanik Гик

    Убедиться не сложно убрать все в void loop() и прописать
    digitalWrite(FORTON, 1)
    delay (3000);
    digitalWrite(FORTOFF, 1)
    если импульсы исчезнут значит все в порядке значит переписываешь весь код внимательно и timeHeat *1 умножаешь на timeHeat *60000
     
    MESS нравится это.
  7. lerik2703

    lerik2703 Гик

    while(millis()- currentTime <=(Otshet +(timeHeat *1)))
    не ясно в чем смысл этого выражения?
    и зачем вызывать функции digitalWrite(FORTOFF, 0); и digitalWrite(FORTON, 0); не определенное количество раз?
    ...
    while (millis() - currentTime <= (Otshet + (timeHeat * 1))) // таймер открытия крутим цыкл пока не выйдет время
    digitalWrite(FORTON, 0); //прекращаем открытие
    ...
     
    Последнее редактирование: 19 янв 2016
  8. MESS

    MESS Гик

    Так подскажите пожалуйста, как правильно. Дайте попробовать Ваш вариант. Мне нужно просто ограничить время открытия и закрытия при достижении порогов гистерезиса. Т.е. Т>26 включился привод на время 1мин (пока так) и выключился по истечении. Так же и при нижнем пороге закрытие происходит. А когда температура в промежутке ( в зоне гистерезиса), ничего не должно происходить.
    А что касается рекомендации
    digitalWrite(FORTON, 1)
    delay (3000);
    digitalWrite(FORTOFF, 1) - то это для проверки работоспособности нано. Сегодня я получу другие нано и попробую- может в старом дефект какой.
     
  9. lerik2703

    lerik2703 Гик

    пожалуйста пока как я вижу вы не можете организовать выход(ы) в открытом состоянии на заданное время !? вот пример

    Код (C++):
    #define OPEN_WINDOWS 1
    #define CLOSE_WINOWS 2
    #define STOP_ENGINE  3
    #define MOTOR_PIN_ON 13 // выход для команды на открытие форточки
    #define MOTOR_PIN_OFF 10 // на закрытие форточки
    #define TIME_WORK_MOTOR 1 // время открытия в минутах
    #define MINUTE 60000

    void setup() {

      pinMode(MOTOR_PIN_ON, OUTPUT);
      pinMode(MOTOR_PIN_OFF, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {

      if (Serial.available()) {
        char incomingByte = Serial.read();
        if (incomingByte == '1')
          EngineControl (OPEN_WINDOWS);
        if (incomingByte == '2')
          EngineControl (CLOSE_WINOWS);

      }

      if (digitalRead(MOTOR_PIN_OFF) or digitalRead(MOTOR_PIN_ON))
        RunMotorTime();

    }


    void EngineControl (byte arg) {

      switch (arg) {
        case OPEN_WINDOWS:

          if (!digitalRead(MOTOR_PIN_OFF))
            digitalWrite(MOTOR_PIN_ON, HIGH);

          break;
        case CLOSE_WINOWS:
          if (!digitalRead(MOTOR_PIN_ON))
            digitalWrite(MOTOR_PIN_OFF, HIGH);

          break;
        case STOP_ENGINE:

          digitalWrite(MOTOR_PIN_ON, LOW);
          digitalWrite(MOTOR_PIN_OFF, LOW);

          break;
      }
    }

    void RunMotorTime() {

      static unsigned long lastTime;
      static bool first_once;
      static int min ;

      if (!first_once) {
        first_once = true;
        lastTime = millis();
      }

      if ((millis() - lastTime) >= MINUTE ) {
        ++min;

        if (TIME_WORK_MOTOR == min) {
          min = 0;
          first_once = false;
          EngineControl (STOP_ENGINE);

        }
        lastTime = millis();
      }
    }
    что не понято спрашивайте отвечу по возможности
     
    MESS и Sparkfire нравится это.
  10. MESS

    MESS Гик

    Уважаемый lerik2703! Ваш код сразу скомпилировался без проблем. Огромное спасибо!
    Проверил в работе. На открытие работает как надо. (условия проверки пока не очень подходящие)
    Заметил, что команда MOTOR_PIN_OFF появляется и пропадает ( интервал примерно 20сек) периодически при Т, выше нижнего порога. Я пока не подключал дисплей. Для удобства проверки мне нужно уменьшить время меньше минуты. как это правильно сделать? строка 10 и 11 чем отличаются?
    Вот код по Вашему варианту. Я многого не понимаю, только кое что.


    Код (C++):
    // REG_Lerik
    #include <OneWire.h>
    OneWire ds(8);

    #define OPEN_WINDOWS 1  // что означает цифра? для switch (arg)?
    #define CLOSE_WINOWS 2
    #define STOP_ENGINE  3
    #define MOTOR_PIN_ON 13 // выход для команды на открытие форточки
    #define MOTOR_PIN_OFF 10 // на закрытие форточки
    #define TIME_WORK_MOTOR 1 // время открытия в минутах
    #define MINUTE 60000


    void setup() {

      pinMode(MOTOR_PIN_ON, OUTPUT); // назначение пина
      pinMode(MOTOR_PIN_OFF, OUTPUT);
      Serial.begin(9600);
    }

    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 ;

    if (temperature >=26)        //условие для OPEN_WINDOWS
    {
      EngineControl (OPEN_WINDOWS);   //открыть!
    }
      else if (temperature <= 24)   // условие  для CLOSE_WINOWS
      {
      EngineControl (CLOSE_WINOWS);   // закрыть!
      }
      if (Serial.available()) {
        char incomingByte = Serial.read();
        if (incomingByte == '1')     // ?? в чем суть этого условия? , как с порогом температуры его связать?
          EngineControl (OPEN_WINDOWS); //  В чем отличие от  digitalWrite(MOTOR_PIN_ON, 1); ?
        if (incomingByte == '2')
          EngineControl (CLOSE_WINOWS);

      }

      if (digitalRead(MOTOR_PIN_OFF) or digitalRead(MOTOR_PIN_ON))
        RunMotorTime();      // если привод включен , то отсчет времени?

    }

    //   это альтернативный код, проверяет три объявленных case (строки 5,6и 7). Чувствую, что  правильно понял
    void EngineControl (byte arg) {  //  что за переменная  arg ( не та ли это цифра в строке 5)   как сказать?

      switch (arg) {      //оператор вычисляет (или проверяет?) переменную arg для  первого кейса OPEN_WINDOWS ?
        case OPEN_WINDOWS:  // первый кейс
          if (!digitalRead(MOTOR_PIN_OFF))
            digitalWrite(MOTOR_PIN_ON, HIGH);
          break;  // команда выхода из оператора switch, если не та ццифра
     
        case CLOSE_WINOWS: //второй кейс
          if (!digitalRead(MOTOR_PIN_ON))
            digitalWrite(MOTOR_PIN_OFF, HIGH);
          break;
     
        case STOP_ENGINE:  // третий кейс
          digitalWrite(MOTOR_PIN_ON, LOW);
          digitalWrite(MOTOR_PIN_OFF, LOW);
          break;
      }
    }

    void RunMotorTime() {  // просьба, если можно,  пояснить эти строки  ниже


      static unsigned long lastTime; //
      static bool first_once;
      static int min ;

      if (!first_once) {
        first_once = true;
        lastTime = millis();
      }

      if ((millis() - lastTime) >= MINUTE ) {
        ++min;

        if (TIME_WORK_MOTOR == min) {
          min = 0;
          first_once = false;
          EngineControl (STOP_ENGINE);

        }
        lastTime = millis();
      }
    }
     
    Последнее редактирование: 20 янв 2016
  11. MESS

    MESS Гик

    Подключил дисплей для контроля за цифрами - с ним работает так же: открытие происходит правильно -только при превышении порога температуры, но в течении 40сек (при define MINUTE 60000), а CLOSE_WINOWS почти сразу включается (через 20 сек), хотя еще только 25,4гр, потом отключается на такое же время (меандр) и так себя ведет, пока не достигнет нижнего порога 24гр.
    При дальнейшем понижении Т , CLOSE_WINOWS не сбрасывается!. При подъеме Т выше 24гр выключается, затем включается - опять меандр. Где же я накосячил?
     
    Последнее редактирование: 20 янв 2016
  12. lerik2703

    lerik2703 Гик

    это можете вообще убрать как и строку Serial.begin(9600); это для проверки через терминал 1 открыть 2 закрыть проверенно на диодах)))
    внутренняя переменная функции иногда мне лень придумывать имена переменных называю тупа arg ... argn
    конечно не правильно ,но что поделаешь ... лень:)

    здесь все о нем http://arduino.ru/Reference/SwitchCase
     
    Последнее редактирование: 20 янв 2016
    MESS нравится это.
  13. MESS

    MESS Гик

    код с дисплеем. Поправил по Вашему, но закрытие появляется не по моему условию.
    Код (C++):
    // REG_Lerik
    #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[];

    #define OPEN_WINDOWS 1  // что означает цифра? для switch (arg)?
    #define CLOSE_WINOWS 2
    #define STOP_ENGINE  3
    #define MOTOR_PIN_ON 13 // выход для команды на открытие форточки
    #define MOTOR_PIN_OFF 10 // на закрытие форточки
    #define TIME_WORK_MOTOR 1 // время открытия в минутах
    #define MINUTE 60000


    void setup() {
       myGLCD.InitLCD();
      pinMode(MOTOR_PIN_ON, OUTPUT); // назначение пина
      pinMode(MOTOR_PIN_OFF, 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);

    if (temperature >=26)        //условие для OPEN_WINDOWS
    {
      EngineControl (OPEN_WINDOWS);   //открыть!
    }
      else if (temperature <= 24)   // условие  для CLOSE_WINOWS
      {
      EngineControl (CLOSE_WINOWS);   // закрыть!
      }
     

      if (digitalRead(MOTOR_PIN_OFF) or digitalRead(MOTOR_PIN_ON))
        RunMotorTime();      // если привод включен , то отсчет времени?

    }

    //   это альтернативный код, проверяет три объявленных case (строки 5,6и 7). Чувствую, что  правильно понял
    void EngineControl (byte arg) {  //  что за переменная  arg ( не та ли это цифра в строке 5)   как сказать?

      switch (arg) {      //оператор вычисляет (или проверяет?) переменную arg для  первого кейса OPEN_WINDOWS ?
        case OPEN_WINDOWS:  // первый кейс
          if (!digitalRead(MOTOR_PIN_OFF))
            digitalWrite(MOTOR_PIN_ON, HIGH);
          break;  // команда выхода из оператора switch, если не та ццифра
       
        case CLOSE_WINOWS: //второй кейс
          if (!digitalRead(MOTOR_PIN_ON))
            digitalWrite(MOTOR_PIN_OFF, HIGH);
          break;
       
        case STOP_ENGINE:  // третий кейс
          digitalWrite(MOTOR_PIN_ON, LOW);
          digitalWrite(MOTOR_PIN_OFF, LOW);
          break;
      }
    }

    void RunMotorTime() {  // просьба, если можно,  пояснить эти строки - не складывается


      static unsigned long lastTime; //
      static bool first_once;
      static int min ;

      if (!first_once) {
        first_once = true;
        lastTime = millis();
      }

      if ((millis() - lastTime) >= MINUTE ) {
        ++min;

        if (TIME_WORK_MOTOR == min) {
          min = 0;
          first_once = false;
          EngineControl (STOP_ENGINE);

        }
        lastTime = millis();
      }
    }
     
    Последнее редактирование: 20 янв 2016
  14. lerik2703

    lerik2703 Гик

    давайте пока без дисплея разберемся !
    поправлю пост но завтра
    датчика у меня все равно нет попробую вслепую ... мне бы уточнить время сколько требуется на получения данных с датчика!
     
  15. lerik2703

    lerik2703 Гик

    изменить значение директивы MINUTE 30000 это 30 сек 15000 это 15 сек соответственно
     
    MESS нравится это.
  16. MESS

    MESS Гик

    Дисплей я подключил только для того, чтобы видеть то, что сам датчик. Ввел доп условие, и закрытие не стало появляться до своего порога.
    else if (temperature < 25,5 ) // условие для CLOSE_WINOWS
    {
    digitalWrite(MOTOR_PIN_OFF, LOW); // прекратить закрытие
    }
    Теперь остается добиться соблюдения выдержки при закрытии. Сейчас MOTOR_PIN_OFF не выключается когда ниже порога. наверно цикл ее включает заново. Буду дальше пробовать тыком ( к сожалению).
    Считаю, что с Вашим кодом все ОК! Еще раз благодарю Вас за помощь!
     
  17. lerik2703

    lerik2703 Гик

    пока по тыкайте))) а я завтра согласую свой код и ваш.
     
  18. lerik2703

    lerik2703 Гик

    Код (C++):
    #include <OneWire.h>
    OneWire ds(8);

    #define OPEN_WINDOWS 1  // что означает цифра? для switch (arg)?
    #define CLOSE_WINOWS 2
    #define STOP_ENGINE  3
    #define MOTOR_PIN_ON 13 // выход для команды на открытие форточки
    #define MOTOR_PIN_OFF 10 // на закрытие форточки
    #define TIME_WORK_MOTOR 1 // время открытия в минутах
    #define MINUTE 15000
    bool WindowsPosition = false; //виртуальный концевик  так как у нас нет реального положения форточки(по умолчанию форточка закрыта)

    void setup() {

      pinMode(MOTOR_PIN_ON, OUTPUT); // назначение пина
      pinMode(MOTOR_PIN_OFF, OUTPUT);
      Serial.begin(9600);
    }
    //--================================================================================================================================--
    void loop() {

      float temperature = SensorGetTemperature ();//упаковываем в функцию должно работать)
     
       Serial.println(temperature);//стотрите пока темперратуру через терминал

      bool RunMotor = digitalRead(MOTOR_PIN_OFF) or digitalRead(MOTOR_PIN_ON);//проверяем работает ли у нас мотор

      if (!RunMotor) { //запрешаем переключение мотора до окончании его работы

        if (temperature >= 26.0 and !WindowsPosition)       //условие для OPEN_WINDOWS
        {
          WindowsPosition = true;//считаем что форточка открылась
          EngineControl (OPEN_WINDOWS);  //открыть!
        }
        else if (temperature <= 24.0 and WindowsPosition)   // условие  для CLOSE_WINOWS
        {
          WindowsPosition = false;//считаем что форточка закрылась
          EngineControl (CLOSE_WINOWS);   // закрыть!
        }

      }


      if (RunMotor)//если мотор работает запускаем таймет. погрешность таймера напрямую связанно с время затратами на выполнение друих задач ,
        RunMotorTime();      //  для уменьшения погрешности можно вызывать функцию из разных мест в пределах loop
      //и ещё подводный камень это переполнение счетчика приблизительно через 50 дней (функция  millis())
    }
    //--==================================================================================================--

    //   это альтернативный код, проверяет три объявленных case (строки 5,6и 7). Чувствую, что  правильно понял
    void EngineControl (byte arg) {  //  что за переменная  arg ( не та ли это цифра в строке 5)   как сказать?

      switch (arg) {      //оператор вычисляет (или проверяет?) переменную arg для  первого кейса OPEN_WINDOWS ?
        case OPEN_WINDOWS:  // первый кейс
          if (!digitalRead(MOTOR_PIN_OFF))//
            digitalWrite(MOTOR_PIN_ON, HIGH);
          break;  // команда выхода из оператора switch, если не та ццифра

        case CLOSE_WINOWS: //второй кейс
          if (!digitalRead(MOTOR_PIN_ON))
            digitalWrite(MOTOR_PIN_OFF, HIGH);
          break;

        case STOP_ENGINE:  // третий кейс
          digitalWrite(MOTOR_PIN_ON, LOW);
          digitalWrite(MOTOR_PIN_OFF, LOW);
          break;
      }
    }

    //--==================================================================================================--

    void RunMotorTime() {  // просьба, если можно,  пояснить эти строки  ниже


      static unsigned long lastTime; //локальные переменные видны только в этой функции
      static bool first_once;
      static int min ;

      if (!first_once) {// это первый вызов или функция начинает отсчет времени
        first_once = true;
        lastTime = millis();//сохранили текушее время
      }

      if ((millis() - lastTime) >= MINUTE ) {//ждем когда пойдет минута
        ++min;

        if (TIME_WORK_MOTOR == min) {
          min = 0;
          first_once = false;
          EngineControl (STOP_ENGINE);
        }
        lastTime = millis();
      }
    }

    //--==================================================================================================--

    float SensorGetTemperature () {

    static byte addr[8];
      if ( !ds.search(addr)) {
        ds.reset_search();
      }
      ds.reset();
      ds.select(addr);
      ds.write(0x44);
      ds.reset(); //
      ds.select(addr);
      ds.write(0xBE);
      return (ds.read() | (ds.read() << 8)) / 16.0 ;
    }
     
    как успехи? вот мой вариант управления двигателем проверяйте.
     
  19. MESS

    MESS Гик

    Я пробовал создать еще один case (END), чтобы вырубить мотор после. Но мне сложно самому разобраться т.к. непонятки негде выяснить. Ваш скетч загрузил и он сразу заработал как надо. Закрытие отключилось после выдержки! Так как и нужно.
    Респект Вам и уважение! Спасибо!
    Сейчас физически не могу продолжить, хотя и хочется - устаю сильно (запрягли в комиссию по проверке московских лифтов). К утру надеюсь полностью соберу девайс. И доложу Вам
     
  20. MESS

    MESS Гик

    Виноват, не сдержал слово - работа в цейтноте.