GyverTimer, обсуждение библиотеки

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
boolean isEnabled(); // вернуть состояние таймера (остановлен/запущен)

Здесь более уместно
boolean isReady(); // возвращает true, когда пришло время
Так я об этом и говорю. Что isReady() мне не подходит. Это другая логика вообще. Тоесть Ready моргнёт 1 раз True-шкой и снова false включит.
А мне надо - чтоб пока таймер работает, он выдавал true. И когда выйдет время включил false. Что и должна поидее делать функция isEnabled().
А получается , что Таймаутный таймер делает тоже самое что и интервальный (цикличный) таймер, только делает это 1 раз.
И ... она не делает вообще то что надо..
Я это проверил не мудрёным методом:
(код рабочий, экран только затереть если нету.)

C++:
#include <Arduino.h>
#define CLK 6
#define DIO 7
#include <GyverTM1637.h>
#include <GyverTimer.h>
GyverTM1637 disp(CLK, DIO);
GTimer Timer1(MS);

void setup() {
  Serial.begin(9600);
  disp.clear();
  disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)
  Timer1.setTimeout(2000);
}
void loop() {
  if(Timer1.isEnabled()){     // работает как будто всегда isEnabled() возвращает true
    Serial.println("isWork(true)");
    disp.displayInt(5555);
    delay(200);
  }else{
    Serial.println("isElse(false)");
    disp.displayInt(0000);
    delay(1000);
  }
}
Просто в данном случае придется хуевертить через дополнительный флаг, который будет перекидываться по isReady() и делать то что надо.
А это в прямом смысле лишние танцы с бубном.

Моё мнение - что функция не доработана и делает совсем не то.

Я и предлагаю допилить функцию isEnabled() чтоб она работала как я говорю.
Тогда эта функция будет очень даже рабочая. А щас показывает погоду в Гондурасе. :cautious:
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Короче. Всё решилось. Сообразил кое че.

Решение работы isEnabled():
include <Arduino.h>
#define CLK 6
#define DIO 7
#include <GyverTM1637.h>
#include <GyverTimer.h>
GyverTM1637 disp(CLK, DIO);
uint32_t Now, clocktimer;
boolean flag;
GTimer Timer1(MS);
//boolean flag=false;
void setup() {
  Serial.begin(9600);
  disp.clear();
  disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)
  Timer1.setTimeout(2000);
}
void loop() {
Timer1.isReady();    //ВОТ ТУТ СОБАКА ПОРЫЛАСЬ!! Если её нет, то и параметр _state никто не меняет .
  if(Timer1.isEnabled()){
    Serial.println("isWork(true)");
    disp.displayInt(5555);
    delay(200);
  }else{
    Serial.println("isElse(false)");
    disp.displayInt(0000);
    delay(1000);
  }
 
}
 

b707

★✩✩✩✩✩✩
4 Июн 2020
54
18
очередная кривая библиотека...

ТС. неужели ради одного таймаута вам нужна целая библиотека? с миллис работать умееете?
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
@b707,
а почему кривая?

C++:
// Пример работы в режиме таймаута
#include "GyverTimer.h"   // подключаем библиотеку
GTimer myTimer(MS);    // создать миллисекундный таймер
//GTimer myTimer(US);    // US - микросекундный
void setup() {
  Serial.begin(9600);
  myTimer.setTimeout(3000);   // настроить таймаут 3 сек
  Serial.println("Start");
}
void loop() {
  // выведет Timeout 3 sec! через 3 секунды после вызова setTimeout(3000)
  if (myTimer.isReady()) Serial.println("Timeout 3 sec!");
 
  // после срабатывания остановит счёт
  // можно перезапустить при помощи setTimeout(время) или start()
}
вот пример же из сайта
он разве не работает и таймер не останавливается?
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
очередная кривая библиотека...

ТС. неужели ради одного таймаута вам нужна целая библиотека? с миллис работать умееете?
Библиотека хорошая, знать надо как обращаться.

Не ради одного...С миллис() работать умею, но писать в 10 местах кусок кода из 20 строчек как то не адэкватно. При том что грамотно организованный таймер в этой библиотеке решает кучу задач. Ты же не знаешь какая задача решается.

вот пример же из сайта
он разве не работает и таймер не останавливается?
Останавливается, но ты не понял сути заморочки. И какой вопрос я решал.
Пример рабочий, к нему нет вопросов.
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
566
очередная кривая библиотека...
ТС. неужели ради одного таймаута вам нужна целая библиотека? с миллис работать умееете?
Почему кривая? Почему очередная кривая? Что-то конструктивное можно услышать?
В библиотеке реализован полноценный таймер с продолжением счёта и коррекцией после паузы. Для того библиотеки и используют, чтобы не изобретать велосипед заново и не тратить на это лишние часы
 
Изменено:

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
566
Так я об этом и говорю. Что isReady() мне не подходит. Это другая логика вообще. Тоесть Ready моргнёт 1 раз True-шкой и снова false включит.
А мне надо - чтоб пока таймер работает, он выдавал true. И когда выйдет время включил false. Что и должна поидее делать функция isEnabled().
А получается , что Таймаутный таймер делает тоже самое что и интервальный (цикличный) таймер, только делает это 1 раз.
И ... она не делает вообще то что надо..
Я это проверил не мудрёным методом:
(код рабочий, экран только затереть если нету.)

C++:
#include <Arduino.h>
#define CLK 6
#define DIO 7
#include <GyverTM1637.h>
#include <GyverTimer.h>
GyverTM1637 disp(CLK, DIO);
GTimer Timer1(MS);

void setup() {
  Serial.begin(9600);
  disp.clear();
  disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)
  Timer1.setTimeout(2000);
}
void loop() {
  if(Timer1.isEnabled()){     // работает как будто всегда isEnabled() возвращает true
    Serial.println("isWork(true)");
    disp.displayInt(5555);
    delay(200);
  }else{
    Serial.println("isElse(false)");
    disp.displayInt(0000);
    delay(1000);
  }
}
Просто в данном случае придется хуевертить через дополнительный флаг, который будет перекидываться по isReady() и делать то что надо.
А это в прямом смысле лишние танцы с бубном.

Моё мнение - что функция не доработана и делает совсем не то.

Я и предлагаю допилить функцию isEnabled() чтоб она работала как я говорю.
Тогда эта функция будет очень даже рабочая. А щас показывает погоду в Гондурасе. :cautious:
Очень просто решается задачка, дополнительным условием по isEnabled:
C++:
if (myTimer.isReady() || !myTimer.isEnabled()) {
    Serial.println("Timeout!");
}
Таким образом после выхода таймаута таймер остановится и всё условие будет возвращать true до перезапуска таймера.
Согласен, иногда удобнее чтобы таймаут не однократно срабатывал, а сигналил постоянно. А иногда удобнее чтобы однократно. В этом минус библиотек, не всегда хватает универсальности и приходится костылить.
 

b707

★✩✩✩✩✩✩
4 Июн 2020
54
18
Почему кривая? Почему очередная кривая? Что-то конструктивное можно услышать?
Алекс, тема уже протухла давно, а тут Вы :)
Я же не написал "очередная кривая библиотека Гайвера" :) - а просто "очередная кривая"
Мало таких в инете, что ли?
Каждый новичок в какой-то момент бросается писать кучу библиотек на все случаи жизни - кнопки. таймеры. датчик температуры...
Качество у большинства этих библиотек, прямо скажем. так себе.

Считаю, что библиотеки для столь элементарных вещей, как таймер или кнопка - использовать не нужно. По крайней мере сторонние. Лучше написать их самому. Так и научищься. да и уверенности в качестве будет больше
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
566
@b707, использовать не нужно - скажи это новичкам. Иногда хочется всё таки быстрого создания проекта, а не нескольких ночей в попытках научиться ловить количество нажатий или удержаний с кнопки. "Лучше написать их самому" - такие люди на форум помощи не обращаются... А уверенности в качестве своего кода новичок не чувствует в принципе)
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
Так и научищься. да и уверенности в качестве будет больше
где логика? как можно научиться, если понятия не имееш о структуре написания программ

я вчера потратил 2 часа только на просмотр вебинара по реактивному программированию на пхп
круто звучит? есть еще такой фреймворк react js для написания веб приложений на яваскрипте

так вот, я вчера задумался, можно ли написать на пхп консольное приложение и не просто одноразовое, а чтобы оно работало как сервер и обслуживало плату по протоколу модбас + работало с базой данных и давало рест апи для веб приложения

я нашел библиотеку для работы с модбас на пхп, что уже звучит смешно, потому что пхп это для сайтов же и как ты ее приделаеш

но есть такая библиотека reactphp для написания серверных приложений, которые запускаются как тот же питон или нода жс, крутятся в памяти и выполняют свои задачи

а реактивным оказывается называется асинхронный код, куски которого выполняются по таймерам
оказывается то, что в программировании мк просто называется вызов по таймеру, то в мире веба это реактивность и та же нода жс на 95% состоит из такого кода, который является по сути колбеком

есть еще другой фреймворк, который работает по событиям и так же вызывает колбек код

а по сути весь этот reactphp и построен на "millis" и date(), которая возвращает количество секунд с 1970 года
и вертящегося в суперцикле кода, только все обернуто красиво

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

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

поэтому за типа простыми вещами на самом деле скрывается куча сложных вещей, которые не нужно разбирать и изобретать велик, нужно только научиться кататься на нем и получать удовольствие
 

b707

★✩✩✩✩✩✩
4 Июн 2020
54
18
я нашел библиотеку для работы с модбас на пхп, что уже звучит смешно, потому что пхп это для сайтов же и как ты ее приделаеш
тебе смешно, потому что ты еще не углубился в вопрос.
На самом деле на PHP можно писать что угодно, от десктопных приложений до серверов и систем обработки векторной графики...

остальное, прости, комментировать не буду... поток сознания какой-то
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
когда я интересовался этим вопросом (лет 10-15 назад), то было еще не можно
уже говорят о 8й версии и вроде реактивность там будет поддерживаться из коробки

только с 7й версии он стал достаточно быстро работать, а писать десктопное приложение на нем нет смысла, для этого шарп есть

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

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
у тебя озу не хватает, чтобы вместить столько инфы в буфер
хотя я думал, что понимать ответвления от темы это обычная норма человека, но кажется я ошибся

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


вот по модбасу

а тут предлогают вместо использования готовой библиотеки самому все писать и разбираться тем, кто даже библиотеку толком не может заюзать
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Для того библиотеки и используют, чтобы не изобретать велосипед заново и не тратить на это лишние часы
"Абсолютно, в жопу, правильно" (с)Криминальное чтиво в переводе Гоблина (кажысь этот фильмец)
Библиотека отличная, но я обнаружил пару неувязок, и нашел где " собака порылась".
Смотри в чём я напарился - сначала "в своих нужных местах" использовал *.start(); и думал что таймер запускается...и работает...и меняет всё сопутствующие флаги. Но ничего не происходило. И я начал вникать в твою библиотеку, смотрю - и вижу, что в функции *.start() только _state=true;
Дальше увидел, что основная отработка таймера находится в *.isReady();
Сообразил, что это аналог button.tick(); - который должен работать в лупе непрерывно и тогда у меня всё будет работать. Отсюда я и написал вот так:
C++:
void loop() {
Timer1.isReady();    //ВОТ ТУТ СОБАКА ПОРЫЛАСЬ!! Если её нет, то и параметр _state никто не меняет .
  if(Timer1.isEnabled()){
    Serial.println("isWork(true)");
    //******* и так далее..
  }
}
И не нужно ничего костылить, все твои функции работают на ура!(y)(y)(y)
Пример, что ты написал - по сути тоже самое, что я сделал, только ты isReady() положил в условии.

Давай подумаем - может добавить в библиотеку функцию типа tick(); Как будто её не хватает...:unsure:
Иначе выходит немного не логично. Просто написав *.start() таймер не запустится , пока чтение кода не дойдёт до isReady().
=============================================
Алекс, тема уже протухла давно, а тут Вы :)
Я же не написал "очередная кривая библиотека Гайвера" :) - а просто "очередная кривая"
Мало таких в инете, что ли?
Каждый новичок в какой-то момент бросается писать кучу библиотек на все случаи жизни - кнопки. таймеры. датчик температуры...
Качество у большинства этих библиотек, прямо скажем. так себе.

Считаю, что библиотеки для столь элементарных вещей, как таймер или кнопка - использовать не нужно. По крайней мере сторонние. Лучше написать их самому. Так и научищься. да и уверенности в качестве будет больше
Чего ты мажешься, как вошь под ногтем...обосрал гиганскую (хорошо выполненную) работу.
Идёт обсуждение конкретной библиотеки-и твой пост был понят однозначно.
Хочешь сказать что ты не юзаешь вообще никаких библиотек?? - если так , то это тупо и глупо даже с точки зрения потраченного времени, охото ебсти потренеровать мозги - выбор твой. Никто не осуждает. Но мериться хуями письками в программировании при каждом удобном случае не надо. Ибо когда мозг заливает чувство величия очень легко упустить суть и обосраться по полной программе.💩 Что, собсна, мы и пронаблюдали.

Автору спасибо, что ответил.🤜🤛
======================================================================
а тут предлогают вместо использования готовой библиотеки самому все писать и разбираться тем, кто даже библиотеку толком не может заюзать
Я ништяк заюзал, не гони волну😊😉
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
566
@Mix_man, так в примерах всё было) isReady() да, своеобразный "тик" для режима периода и таймаута, в каком режиме таймер был запущен - в таком isReady его будет ловить. Но isReady вернёт true только один раз и сразу сбросится, а я так понял тебе нужно постоянный сигнал и предложил через костыль с условием ИЛИ.
 

mezko

✩✩✩✩✩✩✩
10 Окт 2020
4
0
Всем привет. Я здесь новичок, только начинаю осваивать ардуино. Решил поставить себе задачу, так интереснее. Создаю гирлянду на 6 груп светодиодов, используя 6 ШИМ выходов ардуины. Планирую создать несколько эффектов, и управлять гирляндой с помощью кнопки.
Начал с простого - светодиоды должны по очереди плавно засветиться, потом некоторое время светить на полную яркость, потом плавно потухнуть, некоторое время не светить и потом цикл повторяется. Нужно всё сделать без использования функции delay, так как нужно опрашивать кнопку. Кое как удалось создать функции для плавного подъёма и снижения яркости, но создать задержку в состояниях 0 и 255 не получается никак, долго мучаюсь, и вижу, что уже сочинаяю какую-то пургу, посему прошу помощи у более опытных.
Вот код:
#include "GyverButton.h"
#include "GyverTimer.h"

//    Подключаю кнопку для управления гирляндой
GButton btn(2, HIGH_PULL, NORM_OPEN);
//    Объявляю таймеры для плавного загорания и затухания светодиода
GTimer riseDelay (MS);
GTimer fallDelay (MS);
//    Объявляю массив, который вмещает в себе пины подключения светодиодов (пины с ШИМ)
byte ledpin [] {3, 5, 6, 9, 10, 11};
//    Переменная яркости свечения светодиода
byte brightness = 0;
//    Переменная, указывающая величину изменения яркости за одну итерацию
byte brightness_amount = 5;
//    Максимальная яркость
byte brightness_max = 255;

void setup() {
  //    Устанавливаю задержку между итерациями увеличения/уменьшения якркости для плавного изменения яркости
  riseDelay.setTimeout (10);
  fallDelay.setTimeout (10);
  //    Запускаю порт для отладки
  Serial.begin (9600);
  //    Задаю режим работы пинов светодиодов на выход, проверяю рабоспособность каждого светодиода (чтоб исключить неконтакт на макетке)
  for (byte i = 0; i <= 5; i++) {
    pinMode (ledpin [i], OUTPUT);
    analogWrite (ledpin[i], 255);
    delay (150);
    analogWrite (ledpin[i], 0);
  }
}

void loop() {
  //   Плавно увеличиваю яркость первого светодиода
  rise (ledpin [0], brightness_amount, brightness_max);

      //Вот здесь я хочу использовать аналог функции delay, то есть удержать светодиод засвеченным заданное количество времени

  //    Запускаю таймер для функции снижения яркости светодиода
  fallDelay.start();
  //    Плавно снижаю яркость светодиода №1
  fall (ledpin [0], brightness_amount, brightness_max);

      //Вот здесь я хочу использовать аналог функции delay, то есть удержать светодиод отключённым заданное количество времени

  //    Запускаю таймер для функции увеличения яркости
  riseDelay.start();
}

//          ФУНКЦИЯ ПЛАВНОГО УВЕЛИЧЕНИЯ ЯРКОСТИ СВЕТОДИОДА НА ПИНЕ PIN С ШАГОМ BRI_AM,ОТ 0 ДО ВЕЛИЧИНЫ BRI_MAX
void rise (byte pin, byte bri_am, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости
  byte bri = 0;
  //    Проверяю, не достигла ли яркость максимума, при каждой итерации слежу за таймером и увеличиваю яркость на bri_am
  while (bri < bri_max) {
    if (riseDelay.isReady()) {
      bri = constrain (bri + bri_am, 0, bri_max);
      //    Если яркость достигла максимума, выходим из цикла
      if (bri >= bri_max) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      riseDelay.start();
    }
    //    Засвечиваем светодиод с текущим значением яркости
    analogWrite (pin, bri);
  }
}
//          ФУНКЦИЯ ПЛАВНОГО СНИЖЕНИЯ ЯРКОСТИ СВЕТОДИОДА НА ПИНЕ PIN С ШАГОМ BRI_AM, ОТ ВЕЛИЧИНЫ BRI_MAX ДО 0
void fall (byte pin, byte bri_am, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости, и присваиваю ей значение максимальной яркости
  byte bri = bri_max;
  //    Проверяю, не достигла ли яркость нуля, при каждой итерации слежу за таймером и снижаю яркость на bri_am
  while (bri >= 0) {
    if (fallDelay.isReady()) {
      bri = constrain (bri - bri_am, 0, bri_max);
      //    Если яркость достигла нуля, выходим из цикла
      if (bri <= 0) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      fallDelay.start();
    }
    analogWrite (pin, bri);
    //    Засвечиваем светодиод с текущим значением яркости
  }
}
 

poty

★★★★★★✩
19 Фев 2020
2,988
895
Посмотрите готовые проекты Гайвера (например, часы) и заодно пошерстите соседние ветки, например, эту. С линейным кодом независимое управление несколькими ветками не получится.
 
  • Лойс +1
Реакции: mezko

mezko

✩✩✩✩✩✩✩
10 Окт 2020
4
0
@poty, то есть вот так написать код строчка за строчкой не вариант? Вроде ж простая задача... Ну ничего, будем дерзать
 

poty

★★★★★★✩
19 Фев 2020
2,988
895
Для одного светодиода - нет проблем. Для нескольких светодиодов, если они управляются зависимо друг от друга (например, один после другого или при уменьшении яркости светодиода n увеличивается яркость светодиода n+1) - тоже нет проблем. Если алгоритм будет меняться или необходимо внести элемент случайности, а также, если зависимостей будет больше - пропорционально увеличивается сложность кода.
Если перевести код в идею: сработка таймера - действие, то можно увеличивать сложность эффектов практически не увеличивая сложность кода.
 
  • Лойс +1
Реакции: mezko

mezko

✩✩✩✩✩✩✩
10 Окт 2020
4
0
Кое как вышел из ситуации :) Но не так изящно как хотелось бы конечно
Сделал на основе функции плавного возростания яркости функцию ожидания, которая меняет яркость на 1 деление по своему таймеру
Вот собственно функция:
void waiting (byte pin, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости
  byte bri = bri_max - 1;
  //    Проверяю, не достигла ли яркость максимума, при каждой итерации слежу за таймером и увеличиваю яркость на bri_am
  while (bri < bri_max) {
    if (wait.isReady()) {
      bri = constrain (bri + 1, 0, bri_max);
      //    Если яркость достигла максимума, выходим из цикла
      if (bri >= bri_max) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      wait.start();
    }
    //    Засвечиваем светодиод с текущим значением яркости
    analogWrite (pin, bri);
  }
}
А вот весь код, может кому-то будет интересно
C++:
#include "GyverButton.h"
#include "GyverTimer.h"

//    Подключаю кнопку для управления гирляндой
GButton btn(2, HIGH_PULL, NORM_OPEN);
//    Объявляю таймеры для плавного загорания и затухания светодиода
GTimer riseDelay (MS);
GTimer fallDelay (MS);
GTimer wait (MS);
//    Объявляю массив, который вмещает в себе пины подключения светодиодов (пины с ШИМ)
byte ledpin [] {3, 5, 6, 9, 10, 11};
//    Переменная яркости свечения светодиода
byte brightness = 0;
//    Переменная, указывающая величину изменения яркости за одну итерацию
byte brightness_amount = 3;
//    Максимальная яркость
byte brightness_max = 255;

void setup() {
  //    Устанавливаю задержку между итерациями увеличения/уменьшения якркости для плавного изменения яркости
  riseDelay.setTimeout (15);
  fallDelay.setTimeout (15);
  wait.setTimeout (3000);
  //    Запускаю порт для отладки
  Serial.begin (9600);
  //    Задаю режим работы пинов светодиодов на выход, проверяю рабоспособность каждого светодиода (чтоб исключить неконтакт на макетке)
  for (byte i = 0; i <= 5; i++) {
    pinMode (ledpin [i], OUTPUT);
    analogWrite (ledpin[i], 255);
    delay (150);
    analogWrite (ledpin[i], 0);
  }
}
void loop() {
  byte i = 0;
  while ( i <= 5) {
    //   Плавно увеличиваю яркость первого светодиода
    rise (ledpin [i], brightness_amount, brightness_max);
    //    Запускаю таймер на ожидание
    wait.start ();
    //    Жду
    waiting (ledpin [i], brightness_max);
    //    Запускаю таймер для функции снижения яркости светодиода
    fallDelay.start();
    //    Плавно снижаю яркость светодиода №1
    fall (ledpin [i], brightness_amount, brightness_max);
    //    Запускаю таймер на ожидание
    wait.start ();
    //    Жду
    waiting (ledpin [i], 1);
    //    Запускаю таймер для функции увеличения яркости
    riseDelay.start();
    i++;
  }
}

//          ФУНКЦИЯ ПЛАВНОГО УВЕЛИЧЕНИЯ ЯРКОСТИ СВЕТОДИОДА НА ПИНЕ PIN С ШАГОМ BRI_AM,ОТ 0 ДО ВЕЛИЧИНЫ BRI_MAX
void rise (byte pin, byte bri_am, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости
  byte bri = 0;
  //    Проверяю, не достигла ли яркость максимума, при каждой итерации слежу за таймером и увеличиваю яркость на bri_am
  while (bri < bri_max) {
    if (riseDelay.isReady()) {
      bri = constrain (bri + bri_am, 0, bri_max);
      //    Если яркость достигла максимума, выходим из цикла
      if (bri >= bri_max) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      riseDelay.start();
    }
    //    Засвечиваем светодиод с текущим значением яркости
    analogWrite (pin, bri);
  }
}
//          ФУНКЦИЯ ПЛАВНОГО СНИЖЕНИЯ ЯРКОСТИ СВЕТОДИОДА НА ПИНЕ PIN С ШАГОМ BRI_AM, ОТ ВЕЛИЧИНЫ BRI_MAX ДО 0
void fall (byte pin, byte bri_am, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости, и присваиваю ей значение максимальной яркости
  byte bri = bri_max;
  //    Проверяю, не достигла ли яркость нуля, при каждой итерации слежу за таймером и снижаю яркость на bri_am
  while (bri >= 0) {
    if (fallDelay.isReady()) {
      bri = constrain (bri - bri_am, 0, bri_max);
      //    Если яркость достигла нуля, выходим из цикла
      if (bri <= 0) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      fallDelay.start();
    }
    analogWrite (pin, bri);
    //    Засвечиваем светодиод с текущим значением яркости
  }
}

void waiting (byte pin, byte bri_max) {
  //    Объявляю переменную, хранящую текущее значение яркости
  byte bri = bri_max - 1;
  //    Проверяю, не достигла ли яркость максимума, при каждой итерации слежу за таймером и увеличиваю яркость на bri_am
  while (bri < bri_max) {
    if (wait.isReady()) {
      bri = constrain (bri + 1, 0, bri_max);
      //    Если яркость достигла максимума, выходим из цикла
      if (bri >= bri_max) {
        break;
      }
      //    Запускаем таймер для следующей итерации
      wait.start();
    }
    //    Засвечиваем светодиод с текущим значением яркости
    analogWrite (pin, bri);
  }
}
Проще всего было бы использовать готовую библиотеку, например LEDFader, в которой уже всё это реализовано, но я думаю для начала стОит писать код "в лоб", чтоб чему-то научиться
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
359
566
полный аналог delay - while (!timer.isReady());. Но зачем?))
 
  • Лойс +1
Реакции: mezko

mezko

✩✩✩✩✩✩✩
10 Окт 2020
4
0
@AlexGyver, мне , к примеру, нужно, чтоб светодиод плавно засветился, секунду остался в состоянии полного свечения, затем плавно погас, и секунду не светил. Вроде всё просто, но для новичка не так уж и легко это реализовать без delay (1000). Спасибо за ответ, попробую.
P.S.: Я же могу оставить тело цикла while пустым?