MILLIS in the function FOR

StoneTL
Offline
Зарегистрирован: 22.08.2018
 for (int i = 0; i <= i; i++) {
        analogWrite( LED1, i );
        delay(10); // ставим задержку для эффекта
}

Как обойтись без "delay(10);" ? Потому что таких разных кусков с for, много. и нужно чтобы он не тормозил код. Какие есть способы добиться того же эффекта, в данном случае плавное нарастания яркости?

Многие писали уже, никак. Но что -то не верится что прям никак. Может через while? Но у меня не получилось.

 

Очень буду признателен. уже замучился с этим. Все ведь наверняка легко.

vk007
Offline
Зарегистрирован: 16.06.2015

StoneTL пишет:

Все ведь наверняка легко.

Легко. Стоит только разобраться и осознать, как работать с millis().

MaksVV
Offline
Зарегистрирован: 06.08.2015

По простому не используйте фор. делать примерно так

bool _for  = 0;             // флаг запуска цикла "как бы фор"
int _i = 0;                 // счетчик "как бы цикла фор"
uint32_t prevMillis = 0;    // для таймера "delay без delay"
#define _delay  50          // величина таймера "delay без delay", мс

#define brightness 255      

void setup() {

pinMode (10, OUTPUT);   // пин например светодиода
analogWrite (10, 0);    // сначала светодиод выключим 
 
 _for = 1;   // запускаем "как бы цикл фор" (делайте это там, где вам нужно, для примера я сделал здесь, в setup )
 _i = 0;     // после чего здесь же не забываем счетчик в нужное значение взвести

}

void loop() {


if (_for && millis()-prevMillis>_delay)
      {
      if (_i == brightness) _for = 0;   // когда достигли нужного эффекта, выходим из "как бы фор"
     _i++;                              // увеличиваем счетчик (добавляем яркость света)
      analogWrite (10, _i);             // устанавливаем яркость светодиода в соответсвии со счетчиком
           
      prevMillis = millis();
      }  

}

 

StoneTL
Offline
Зарегистрирован: 22.08.2018

Спасибо. Попробую.

StoneTL
Offline
Зарегистрирован: 22.08.2018

Получилось, то что я хотел. Спасибо большое)

Igoreck
Offline
Зарегистрирован: 01.03.2017

MaksVV пишет:

По простому не используйте фор. делать примерно так

bool _for  = 0;             // флаг запуска цикла "как бы фор"
int _i = 0;                 // счетчик "как бы цикла фор"
uint32_t prevMillis = 0;    // для таймера "delay без delay"
#define _delay  50          // величина таймера "delay без delay", мс

#define brightness 255      

void setup() {

pinMode (10, OUTPUT);   // пин например светодиода
analogWrite (10, 0);    // сначала светодиод выключим 
 
 _for = 1;   // запускаем "как бы цикл фор" (делайте это там, где вам нужно, для примера я сделал здесь, в setup )
 _i = 0;     // после чего здесь же не забываем счетчик в нужное значение взвести

}

void loop() {


if (_for && millis()-prevMillis>_delay)
      {
      if (_i == brightness) _for = 0;   // когда достигли нужного эффекта, выходим из "как бы фор"
     _i++;                              // увеличиваем счетчик (добавляем яркость света)
      analogWrite (10, _i);             // устанавливаем яркость светодиода в соответсвии со счетчиком
           
      prevMillis = millis();
      }  

}

 

Скажите, а по достижении конечной итерации ++255, что бы переходило в обратно в минусовую и до нуля --0.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Igoreck пишет:

Скажите, а по достижении конечной итерации ++255, что бы переходило в обратно в минусовую и до нуля --0.

Тогда лучше вместо булева флага _for использовать целое приращение счетчика цикла, которое в зависимости от обстоятельств могло бы принимать значения -1, 0 или 1.

Logik
Offline
Зарегистрирован: 05.08.2014

Igoreck пишет:

MaksVV пишет:

По простому не используйте фор. делать примерно так

bool _for  = 0;             // флаг запуска цикла "как бы фор"
int _i = 0;                 // счетчик "как бы цикла фор"
uint32_t prevMillis = 0;    // для таймера "delay без delay"
#define _delay  50          // величина таймера "delay без delay", мс

#define brightness 255      

void setup() {

pinMode (10, OUTPUT);   // пин например светодиода
analogWrite (10, 0);    // сначала светодиод выключим 
 
 _for = 1;   // запускаем "как бы цикл фор" (делайте это там, где вам нужно, для примера я сделал здесь, в setup )
 _i = 0;     // после чего здесь же не забываем счетчик в нужное значение взвести

}

void loop() {


if (_for && millis()-prevMillis>_delay)
      {
      if (_i == brightness) _for = 0;   // когда достигли нужного эффекта, выходим из "как бы фор"
     _i++;                              // увеличиваем счетчик (добавляем яркость света)
      analogWrite (10, _i);             // устанавливаем яркость светодиода в соответсвии со счетчиком
           
      prevMillis = millis();
      }  

}

 

Скажите, а по достижении конечной итерации ++255, что бы переходило в обратно в минусовую и до нуля --0.

надо миллис обнулить ;)

ПС. шото давно никто не пытался...

Igoreck
Offline
Зарегистрирован: 01.03.2017

Прошу Вас, указать что я не так делаю для обратного гашения ШИМ.

1. При переходе с максимального ШИМ на уменьшения, виден провал!

2. Когда заканчивается итерация на уменьшения, то она зацикливается!

bool _for  = 0;             // флаг запуска цикла "как бы фор"
int _i = 0;                 // счетчик "как бы цикла фор"
uint32_t prevMillis = 0;    // для таймера "delay без delay"
#define _delay  50          // величина таймера "delay без delay", мс
bool flag = 0;
#define brightness 255

void setup() {
  Serial.begin(9600);

  pinMode (10, OUTPUT);   // пин например светодиода
  analogWrite (10, 0);    // сначала светодиод выключим

  _for = 1;   // запускаем "как бы цикл фор" (делайте это там, где вам нужно, для примера я сделал здесь, в setup )
  _i = 0;     // после чего здесь же не забываем счетчик в нужное значение взвести

}

void loop() {
  // Serial.println();

  if ((flag == 0 && _for) && millis() - prevMillis > _delay)
  {
    analogWrite (10, _i);             // устанавливаем яркость светодиода в соответсвии со счетчиком
    prevMillis = millis();
    _i++;                              // увеличиваем счетчик (добавляем яркость света)
  }
  if (_i == brightness)
  {
    flag = 1;
    _for = 1;
    _i = 0;
  }
  if ((flag == 1 && _for) && millis() - prevMillis > _delay)
  {
    analogWrite (10, _i);
    prevMillis = millis();
    _i--;
  }
  if (brightness == 0)
  {
    flag = 0;
    _for = 1;
    _i = 0;
  }

}

 

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

Igoreck пишет:

1. При переходе с максимального ШИМ на уменьшения, виден провал!

так вы сами после максимума ШИМ сразу резко ставите ноль

Цитата:
2. Когда заканчивается итерация на уменьшения, то она зацикливается!

Потому что условие в строке 40 никогда не выполняется (и не может выполнится в принципе)

 

интересно, вы этот код сами писали? Судя по вопросам, вы не особо понимаете, как он работает

 

Igoreck
Offline
Зарегистрирован: 01.03.2017

b707 пишет:

Igoreck пишет:

1. При переходе с максимального ШИМ на уменьшения, виден провал!

так вы сами после максимума ШИМ сразу резко ставите ноль

Цитата:
2. Когда заканчивается итерация на уменьшения, то она зацикливается!

Потому что условие в строке 40 никогда не выполняется (и не может выполнится в принципе)

 

интересно, вы этот код сами писали? Судя по вопросам, вы не особо понимаете, как он работает

 

Спасибо. Буду стараюсь.

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

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

volatile uint8_t i = 0;
bool reverse;

void setup() {
}

void loop() {
  delay(15);
  analogWrite(LED_BUILTIN, i);
  analogWrite(3, i);
  if (!reverse) {
    i++;
  } else{
    i--;
  }
  if(i==255 || i==0)reverse = !reverse;
}

 

или неблокирующий код:
 

#define pause 15
volatile uint8_t i = 0;
bool reverse;
uint32_t old_millis;
void setup() {
}

void loop() {
  analogWrite(LED_BUILTIN, i);
  analogWrite(3, i);
  // delay(15);
  if (millis() - old_millis >= pause) {
    if (!reverse) {
      i++;
    } else {
      i--;
    }
    if (i == 255 || i == 0)reverse = !reverse;
    old_millis = millis();
  }
}

 

Igoreck
Offline
Зарегистрирован: 01.03.2017

ua6em пишет:

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

volatile uint8_t i = 0;
bool reverse;

void setup() {
}

void loop() {
  delay(15);
  analogWrite(LED_BUILTIN, i);
  analogWrite(3, i);
  if (!reverse) {
    i++;
  } else{
    i--;
  }
  if(i==255 || i==0)reverse = !reverse;
}

 

или неблокирующий код:
 

#define pause 15
volatile uint8_t i = 0;
bool reverse;
uint32_t old_millis;
void setup() {
}

void loop() {
  analogWrite(LED_BUILTIN, i);
  analogWrite(3, i);
  // delay(15);
  if (millis() - old_millis >= pause) {
    if (!reverse) {
      i++;
    } else {
      i--;
    }
    if (i == 255 || i == 0)reverse = !reverse;
    old_millis = millis();
  }
}

 

Спасибо, но я как новичок, хотел сам к этому дойти.

Как смешно бы это не выглядело.