Разные периоды "горит\не горит" светодиода

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

  1. yden

    yden Гик

    Здравствуйте.
    Подскажите пожалуйста, как можно используя millis сделать мигание светодиодом по следующему алгоритму: 0,5 сек. горит, 3 секунды не горит. Получается только одинаковые периоды горит\не горит.

    Спасибо
     
  2. qwone

    qwone Гик

    Код (C++):
    void antidelay(uint32_t timing){
    timing += millis();
    while(millis()<=timing);
    }
    void setup() {
    pinMode(13, OUTPUT);
    }
    void loop() {
    digitalWrite(13, HIGH);  
      antidelay(500);              
      digitalWrite(13, LOW);
      antidelay(3000);
    }
     
  3. vvr

    vvr Инженерище

    я такую конструкцию обычно использую

    Код (C++):
    #define relay 13

    void setup()
    {
      pinMode(relay, OUTPUT);
    }

    void loop()
    {
      static bool state;
      static unsigned long time;
      if((millis() - time) > (state ? 500 : 3000))
      {
        state = !state;
        digitalWrite(relay, state);
        time = millis();
      }
    }
     
    Tomasina нравится это.
  4. ostrov

    ostrov Гуру

    И чем это отличается от delay()?
     
  5. qwone

    qwone Гик

    Ничем. Зато использует millis . Как просили в начале.
    ПС: И да при компиляции меньше байт использует antidelay().
     
    Последнее редактирование: 12 авг 2016
  6. ostrov

    ostrov Гуру

    Надеюсь, вы понимаете что ТС имел ввиду не это.
     
  7. qwone

    qwone Гик

    Самое смешное то, что millis есть millis . Я упаковал в привычный delay() и получился привычный Blink, Другой вариант всего лишь просто другая упаковка привычного блинка.
     
  8. ostrov

    ostrov Гуру

    Это то же самое что delay(), вы или не понимаете или прикалываетесь? В курсе чем отличается организация того же blink через задержки и через таймер?
     
  9. yden

    yden Гик

    Я имел ввиду чтобы программа во время моргания светиком не останавливалась.
     
  10. qwone

    qwone Гик

    В курсе.
    Код (C++):
    const int Led_Pin = 13; // нога светодиода

    void flashing_non_stop_program(uint16_t time_0,uint16_t time_2 ) {
      static bool state = 0;
      static uint32_t timing = 0;
      if (millis()<timing) return;
      state = !state;
      timing += state ? time_0 : time_2 ;
      digitalWrite(Led_Pin, state);
    }
    void setup() {
    pinMode(Led_Pin, OUTPUT);
    }
    void loop() {
       flashing_non_stop_program(100,900);// 0.1 сек горит 0.9 сек нет
       // идет продолжение программы без задержки на millis()
    }
     
  11. vvr

    vvr Инженерище

    а чем ваш код принципиально отличается от кода в посте #3
     
  12. qwone

    qwone Гик

    Вам нужны принципы. Так у меня тоже "принципы". Я стараюсь делать удобные решения в модулях.В данном решении в виде функции. Понадобится такое решение в программе большого объема. Копипаст кода и вызов функции в нужном месте программы. Опробованое решении, меньше ошибок.меньше время отладки. А пальму первенства можете отдать другому участнику. Я на нее не претендую.
    Код (C++):
    flashing_non_stop_program(100,900);// 0.1 сек горит 0.9 сек нет
    Если встречу в большом тексте эту строчку, я сразу пойму что она делает.
     
  13. yden

    yden Гик

    спасибо
    можно попросить вас пояснить каждую строку, а то код работает, а как - не могу понять. если не трудно.
     
    Последнее редактирование: 13 авг 2016
  14. Limoney

    Limoney Гик

    Код vvr лучше, отсчет точнее
     
  15. qwone

    qwone Гик

    Считай что millis это часы, которые считают милисекунды. Вот программа выставляет нужное время для реагирования и периодически сверяет не наступило ли оно. Наступило , выставило новое время для реагирования и поменяло на новое значение. Вот только в отличии от первой моей программы процессор не ждет когда это время наступит, а бегает и выполняет действие по циклу loop(){ }. так что все же функцию надо очень часто вызывать. Это как часы, они позволяют узнать точное время, но надо периодически на них посматривать.

    Код (C++):
    const int Led_Pin = 13; // нога светодиода

    void flashing_non_stop_program(uint16_t time_0,uint16_t time_1 ) {
      static bool state = 0;       // состояние светодиода
      static uint32_t future = 0;  // время будущего перескока на другое состояние
      if (millis()<future) return; // если время не пришло(нужное значение millis() ) то выйти из функции
      state = !state;              // время смены пришло поменяйте состояние
      future += state ? time_0 : time_1 ;
       // определите новое время для перескока если state = 1 то future=future+time_0
       //                                      если state = 0 то future=future+time_1
      digitalWrite(Led_Pin, state);
    }
    void setup() {
    pinMode(Led_Pin, OUTPUT);
    }
    void loop() {
       flashing_non_stop_program(100,900);// 0.1 сек горит 0.9 сек нет
       // идет продолжение программы без задержки на millis()
    }
     
    yden нравится это.
  16. qwone

    qwone Гик

    Вот еще на тему этой конструкции
    Код (C++):
    uint8_t non_stop_program(uint16_t span) {
      static uint32_t future = 0;
      if (millis()<future) return 0;
      future += span;
      return 1;
    }
    void setup() {
      Serial.begin(9600);
    }
    void loop() {
      if (non_stop_program(500))  Serial.println("knok");
    }
    Если нужно опрашивать датчик и отправлять сообщение с периодичностью в 0,5 сек. Понятно кроме этого и остальная программа должна работать.
     
    yden нравится это.
  17. yden

    yden Гик

    Благодарю
     
  18. yden

    yden Гик

    Я так сделал задержку опроса датчиков dht21, bme280, ds18b20:

    Код (C++):

    //влажность+температура+давление
      if (currentMillis_sensor - previousMillis_sensor > interval_sensor)
      {
        previousMillis_sensor = currentMillis_sensor;
        i++;
      }

      //улица
      if (i == 1)
      {
        h_out = dht1.readHumidity();
        t_out = dht1.readTemperature();
      }

      //санузел
      if (i == 2)
      {
        h_san = dht2.readHumidity();
        t_san = dht2.readTemperature();
      }

      //кухня
      if (i == 3)
      {
        h_kux = dht3.readHumidity();
        t_kux = dht3.readTemperature();
      }

      //давление
      if (i == 4)
      {
        p_atm = bme.readPressure() * 0.00750061683;
      }

      //dallas подготовка
      if (i == 5)
      {
        ds.requestTemperatures(); // считываем температуру с датчиков
      }

      //dallas считывание
      if (i == 6)
      {
        t_budka = ds.getTempC(ds_budka);
        i = 0;
      }
     
  19. yden

    yden Гик

    А если 2 светика использовать с индивидуальным алгоритмом работы?
     
  20. qwone

    qwone Гик

    static uint32_t future в функции один.Может только 1 процесс реализовывать. необходимо 2 разные функции писать. Или же класс городить. А если есть желание, то я подобное делал смотри ссылку на другом форуме.
    http://forum.arduino.ua/viewtopic.php?id=728