как и чем заменить delay в коде?

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

Здравствуйте,как можно заменить delay

 

 

#include "Adafruit_NeoPixel.h"
#define LED_COUNT 14
#define LED_PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);



void setup() {
 strip.begin();
 
}

void loop() {
    for (int i = 0; i < LED_COUNT; i++)
  {
    strip.setPixelColor(i, strip.Color(55,55,55));
    strip.show();
    delay(80);   
    strip.setPixelColor(i, strip.Color(0,0,0));
    strip.show();
  }
  
  for (int i = 12;  i > 0; i--)
  {
    strip.setPixelColor(i, strip.Color(55,55,55));
    strip.show();
    delay(80);
    strip.setPixelColor(i, strip.Color(0,0,0));  
    strip.show();
  }
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А зачем?

bwn
Offline
Зарегистрирован: 25.08.2014

Конкретно в вашем, никак.

И присоединюсь к предыдущему вопросу.
 

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

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

Ardrey
Offline
Зарегистрирован: 13.09.2019

А если использовать проверку timegettime() в цикле? Не должно блокировать выполнение программы.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Может так

#include "Adafruit_NeoPixel.h"
#define LED_COUNT 14
#define LED_PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
uint32_t pausa;
bool plus_minus = 1;
uint8_t i=0;

void setup() {
  strip.begin();

}

void loop() {

  if (millis()-pausa>=80)
  {
    pausa = millis();
    if (plus_minus)
    {
      if (i<LED_COUNT)	i++;
      else plus_minus = !plus_minus;
    }
    if (!plus_minus)
    {
      if (i > 0)	i--;
      else plus_minus = !plus_minus;
    }
    strip.setPixelColor(i, strip.Color(0,0,0));
    strip.show();
    strip.setPixelColor(i, strip.Color(55,55,55));
    strip.show();
  }
}

 

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

Главный вопрос, не как, а чем можно его заменить

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

olegnezhelskiy007 пишет:
Главный вопрос, не как, а чем можно его заменить

Заменить можно много чем. Главный вопрос - зачем?

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

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

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

Заработала так как мне надо после того, как поменял местами 29-30 и 31-32 строки. Спасибо большое

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Вы, похоже не поняли моего поста.

Вот Вы считаете, что

olegnezhelskiy007 пишет:
Главный вопрос, не как, а чем можно его заменить

Открываем Ваш первый пост и читаем

olegnezhelskiy007 пишет:
Здравствуйте,как можно заменить delay

И больше там нет ни одной буквы. Т.е. "главный вопрос" Вы почему-то не задали! Забыли? В общем, на Ваш вопрос я ответил, но это оказалось не то. Учитесь задавать вопросы.

И, да, кстати, главный вопрос вовсе не в том как и на что менять. Главный вопрос - зачем.

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

На вопрос зачем отвечал уже, а правильный вопрос в названии темы

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

olegnezhelskiy007 пишет:
это один из режимов работы адресной светодиодной ленты, хочу сделать переключение режимов с помощью кнопки, но из-за delay переключение не работает. Как только удаляю delay, переключение начинает работать, но сам режим работает не правильно

В приведенном коде работы с кнопками нет.

 

 

inspiritus
Онлайн
Зарегистрирован: 17.12.2012

yaled или yeld ?

Я полагал, что йелд только в esp есть

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

правильно yield, но у ЕП просто delay набарот написан. 

И да, yield есть и в Ордуино, просто она описана "слабой" (weak)  функцией.

http://arduino.ru/forum/programmirovanie/sobytiinoe-programmirovanie-pri-pomoshchi-slabykh-funktsii-pozdnego-svyazyvan

nik182
Offline
Зарегистрирован: 04.05.2015

И вызывается на каждом круге delay - самое то обработчик кнопок повесить и delay кнопки тормозить не будет и будет выполняться.

svm
Offline
Зарегистрирован: 06.11.2016

Вместо делея можно написать свою функцию которая будет следить за кнопкой, указанное время. Если кнопка не нажималась, то будет просто задержка. Типа этого: http://arduino.ru/forum/proekty/universalnyi-arduino-probnik?page=5#comment-477987 строки 161-178. Вызывается в 71 строке. Правда там в ней смысла большого нет, но планировалось использовать вместо делея.

olegnezhelskiy007
Offline
Зарегистрирован: 13.09.2019

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

olegnezhelskiy007 пишет:
Код для работы с кнопкой уже написан, и там все правильно, но из-за присутствия delay в данном участке кода, кнопка работает некорректно

"данный участок кода" - это даже не лепет грудничка. Это бред шизофреника! ;)) (это юмор, обижаться или нет - чисто твой выбор).

метод show не надо вызывать после каждого чиха. Он вообще предназначен для вызова один раз за условный "кадр". Чаще всего 50-60 раз в секунду.

Чтобы "слушать кнопку" нужно полностью переписать логику эффекта:

1. В сценарии эффекта ты продумываешь скорость смены кадров. Чтобы ненароком не вызвать эпилептический припадок у случайного зрителя ;)) смена кадров должна быть на постоянной скорости. На каждый кадр ты продумываешь изменение ленты - что включится, что выключится, что цвет поменяет.

2. как в примере "блин без делей", ты ожидаешь  время смены кадра и быстренько меняешь задающий массив ленты и вызываешь "show" - то есть "показать" его.

3. точно так же в loop() ты вызываешь проверку состояния кнопки, обработку дребезга и всё остальное, включая перемену эффекта или его параметров.

---------------

так положено писать код для контроллеров. Как только тебе требуется совместить несколько разнородных алгоритмов для разных задач, то необходимо КАЖДЫЙ переписать в неблокирующий вид. То есть так, чтобы в loop() производились короткие действия без, делей().

Есть ещё подход с использованием yield(). Когда один, главный, алгоритм можно не переписывать, но проследить, что между делеями нет искусственных задержек. На деле это способ для скучающих профи, а не для новичков.

leks
Offline
Зарегистрирован: 22.10.2017

olegnezhelskiy007 пишет:
Код для работы с кнопкой уже написан, и там все правильно, но из-за присутствия delay в данном участке кода, кнопка работает некорректно

Вроде все уже подсказали, а воз и ныне там. Вместо delay(); ставим везде delay_(); - это функция, использующая "миллис". В неё, внутрь, вставляем свой код кнопки. И всё.

 

leks
Offline
Зарегистрирован: 22.10.2017
 ////  ФУНКЦИИ ОПИСАНИЕ // вместо задержки времени через delay  ///////////////////////////////////////
void delay_(int T1)
{
long Y=millis();
flag_B=1;
 while(millis()-Y<T1) 
  {
  if(flag_B==1){funkz_moise_ISPOL ();if(mstat!=8){flag_B=1;}}//если мышь побескоили 
  }
}
 ///////////////////////////////////////////////////////////////////////////////////////////////////////

Например так, только вместо мыши условия для кнопки.

b707
Offline
Зарегистрирован: 26.05.2017

leks - это не решение, а костыль... хотя на костыле кое-как можно ходить...

Ardrey
Offline
Зарегистрирован: 13.09.2019

Ну нифига себе вы с инкапсуляцией обращаетесь! В функцию суете что-то, что будет работать индивидуально. И каждый раз переписывать код? Итальянцы любят спагетти, а индусы - спагетти код.

1. Использовать таймер, который генерирует события (тики) независимо и не подвешивая всю систему.

void my_sleep(int Seconds)
{
    clock_t Start;
    Start=clock();
    while((clock()-Start)/CLK_TCK<=Seconds);
}

//или timegettime() или ещё что вместо clock

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

sadman41
Offline
Зарегистрирован: 19.10.2016

На кой ему тики? Для того, чтобы пользоваться технологией с выделением времени нитям через системный таймер - нужно хорошо понимать, как будут синхронизироваться части вычислительного процесса.

И нарезать ничего не надо тоже. Есть дешёвый и эффективный приём с "blink без delay" - он гораздо лучше и линейно ложится в голову начинающего, вполне справляясь с 90% любительских задач.

leks
Offline
Зарегистрирован: 22.10.2017

b707 пишет:

leks - это не решение, а костыль... хотя на костыле кое-как можно ходить...

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

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

wdrakula пишет:
это способ для скучающих профи
На редкость точная формулировка. Реально это реализовать ... в общем новички тут рядом не проходили.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

sadman41 пишет:

гораздо лучше и линейно ложится в голову начинающего

При условии наличия этой самой головы.

Ardrey
Offline
Зарегистрирован: 13.09.2019

Ну да. Вместо цикла в скетче использовать собственно loop изящнее.

Единственный минус - loop может быть долгим у замороченных программ. Дискрет получится большим.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ardrey пишет:

Единственный минус - loop может быть долгим у замороченных программ. Дискрет получится большим.

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

Ardrey
Offline
Зарегистрирован: 13.09.2019

Код программы не обязательно сложен из-за несовершенства программиста. Вполне может быть сложная задача. А простые задачи решать на ардуино накладно. Для этого есть устройства попроще.

Насчёт тумбочки - спасибо. А я всё думал, где у меня голова запропастилась!?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

wdrakula пишет:
это способ для скучающих профи
На редкость точная формулировка. Реально это реализовать ... в общем новички тут рядом не проходили.

а тут других и нет, другие они по ГИТхабам свои темы пилят

b707
Offline
Зарегистрирован: 26.05.2017

Ardrey пишет:

Код программы не обязательно сложен из-за несовершенства программиста. Вполне может быть сложная задача.


"Совершенство программиста" в том и заключается, чтобы описывать сложные задачи простым кодом. Навалять Луп в полторы тыщи строк любой дурак сможет, а ты вот уложись в сотню, да чтоб любому было понятно, что какая строка делает

inspiritus
Онлайн
Зарегистрирован: 17.12.2012

wdrakula пишет:

Есть ещё подход с использованием yield().

ИМХО-Когда в есп йелд применяется в собствееном коде это создаёт точки , в которых  обработчику вайфай позволяется выполнять служебные процедуры, дабы кодом не подвесить основной функционал есп-шки.

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

или я совсем неправ?

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

В Arduino yield() - пустая weak функция. Достаточно переопределить её своей собственной и начать жестко вешать весь рантайм.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

inspiritus пишет:

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

Что сами надурите, то и будет

rush
rush аватар
Offline
Зарегистрирован: 21.05.2019

а библиотекой ни как SmartDelay foo2(2000000UL);?