delay что делает с питанием?

Тема в разделе "Arduino & Shields", создана пользователем ELITE, 3 апр 2018.

  1. ELITE

    ELITE Гик

    delay по сути останавливает работу кода - фактически пауза

    а как он влияет на остальное? идет ли тактирование, работают ли счетчики и прерывания... питание по полной идет или потребление снижается?

    и да, есть ли способ оборвать выполнение delay не дожидаясь его окончания?
     
  2. DetSimen

    DetSimen Guest

    delay это просто пустой цикл. Прервать его можно, досрочно выйти - нет.
     
    ELITE нравится это.
  3. DIYMan

    DIYMan Guest

    delay ничего не делает с питанием - он крутит бесконечный цикл, никакой паузы в работе кода нет, т.к. delay - это тоже код.

    Штатных способов оборвать выполнение delay, не дожидаясь его окончания - нет, но всегда можно допилить, при желании.
     
    NikitOS и ELITE нравится это.
  4. DIYMan

    DIYMan Guest

    Предвосхищая вопрос "как допилить". Примерно так, как вариант:

    Код (C++):

    typedef bool (*PDelayBreakFunc)();

    void myDelay(unsigned long ms, PDelayBreakFunc func)
    {
        uint32_t start = micros();

        while (ms > 0) {
         
            if(func && func())
                return;
         
            while ( ms > 0 && (micros() - start) >= 1000) {
                ms--;
                start += 1000;
            }
        }
    }

    bool canBreakDelay()
    {
        // тут по каким-то параметрам выясняете, что надо прервать delay
        if(someCondition)
            return true;
     
        return false;
    }


    void setup()
    {
        myDelay(5000,canBreakDelay);
    }
     
    ELITE нравится это.
  5. ELITE

    ELITE Гик

    после "это цикл" всё стало на свои места. дальше можно было даже не продолжать ) спасибо.

    я не использую delay в коде. все на millis
     
  6. parovoZZ

    parovoZZ Гуру

    На каждой итерации проверяется условие выполнения цикла. Затем выполняется пустая инструкция - nop. И так по кругу. Досрочно выйти можно через прерывание.
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    Вроде даже в исходниках есть заложенная возможность параллельно во время delay выполнять другой код (функция yield()), но что-то разработчики на это забили.
     
    ELITE нравится это.
  8. DetSimen

    DetSimen Guest

    Выйти нельзя, прервать - можно.
     
    ELITE нравится это.
  9. parovoZZ

    parovoZZ Гуру

    break цикл не прервет?
     
  10. ELITE

    ELITE Гик

    для прерывание бреком (как и любым иным программым методом) надо условие его срабатывание - но это уже совсем иная песня....
     
  11. parovoZZ

    parovoZZ Гуру

    в прерывании формируешь условие срабатывания, в цикле выполняешь. Вопрос закрыт.
     
    ELITE нравится это.
  12. ELITE

    ELITE Гик

    да, закрываем тему, с этим всё ясно
     
  13. parovoZZ

    parovoZZ Гуру

    а свою функцию делея не написать?
     
  14. Asper Daffy

    Asper Daffy Иксперд

    Почему забили? Выполняйте на здоровье, кто не даёт-то?
     
    Последнее редактирование: 3 апр 2018
  15. ostrov

    ostrov Гуру

    И как она работает конкретно в Ардуино?
     
  16. Asper Daffy

    Asper Daffy Иксперд

    Также, как и везде.

    Вот, пожалуйста, блинк на фоне delay(100500). запускайте - мигает за милую душу.

    Код (C++):
    void setup(void) {
        pinMode(LED_BUILTIN, OUTPUT);
    }

    void loop(void) {
        delay(100500);
    }

    void yield(void) {
        static uint32_t startIntrval = 0;
        const uint32_t currentMillis = millis();
        if (currentMillis - startIntrval >= 500) {
            startIntrval = currentMillis;
            digitalWrite(LED_BUILTIN, ! digitalRead(LED_BUILTIN));
        }
    }
     
     
    Tomasina нравится это.
  17. parovoZZ

    parovoZZ Гуру

    и как часто будет происходить вызов этой функции?
     
  18. Asper Daffy

    Asper Daffy Иксперд

    Открываем исходник dealy и смотрим:
    Код (C++):
    void delay(unsigned long ms)
    {
        uint32_t start = micros();

        while (ms > 0) {
            yield();
            while ( ms > 0 && (micros() - start) >= 1000) {
                ms--;
                start += 1000;
            }
        }
    }
    Очевидно, что внутренний while полностью идентичен if (зачем автор использовал while знает только он и его поставщик травы), т.е. yield() вызывается с периодом равным суммарному времени выполнения проверок во внешнем и внутреннем while'ах - достаточно часто.
     
  19. DIYMan

    DIYMan Guest

    Они не забыли, yield - это функция позднего связывания, я юзаю этот механизм в полный рост ;) Другое дело, что по сути вопроса из delay досрочно вывалится штатными средствами - никак, так что yield там - просто для обеспечения возможности выполнения другого кода, пока цикл в delay крутится.
     
  20. Asper Daffy

    Asper Daffy Иксперд

    Это смотря что считать "штатными средствами". Существующий с момента "рождества С" механизм longjmp - штатное средство или не штатное?

    (надеюсь, тут не структурастов поблизости, а то "ой чо щас будет!!!")
     
    Последнее редактирование: 3 апр 2018