ESP, IoT Два рандома и millis

Kirbox

✩✩✩✩✩✩✩
12 Май 2022
4
0
Доброго дня!
Подскажите, пожалуйста как можно реализовать подобный код
C++:
long randTime;        
long grandMin = 500;  
long grandMax = 3500;
long prandMin = 10;
long prandMax = 300;
BLYNK_WRITE(V4)
{
  while (param.asInt() == HIGH){
  randTime = random(grandMin, grandMax);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(randTime);
  randTime = random(prandMin, prandMax);
  digitalWrite(LED_BUILTIN, LOW);
  delay(randTime);
}
}
без использования delay, чтобы можно было прервать выполнение по значению param.asInt() == LOW ?
с использованием millis что-то не получается, ESP перезагружается через несколько секунд
 

poty

★★★★★★✩
19 Фев 2020
2,989
895
А что Вы код с delay выложили? Выкладывайте код с проблемой, написанный с millis. Гадать что Вы там наворотили здесь некому.
 

Kirbox

✩✩✩✩✩✩✩
12 Май 2022
4
0
@poty, извините, не хотел пугать безобразием

C++:
unsigned long gtiming;
unsigned long ptiming;
long randTime;          
long grandMin = 500;    
long grandMax = 3500;
long prandMin = 10;
long prandMax = 300;
BLYNK_WRITE(V4)
{
  while (param.asInt() == HIGH){
    randTime = random(grandMin, grandMax);
    if (millis() - gtiming > randTime) {
      gtiming = millis();
      digitalWrite(LED_BUILTIN, LOW);
    }
    randTime = random(prandMin, prandMax);
    if (millis() - ptiming > randTime) {
      ptiming = millis();
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }
}
 

Сотнег

★★★★★★★
15 Янв 2020
4,121
1,438
@Kirbox,
loop(){
BLYNK_WRITE(V4){
myflag = param.asInt() == HIGH;
}
if (myflag){
randTime = random(grandMin, grandMax);
digitalWrite(LED_BUILTIN, mylevel);
mylevel = !mylevel;
delay(randTime);
myflag = param.asInt() == HIGH;
}
}
 

Kirbox

✩✩✩✩✩✩✩
12 Май 2022
4
0
В общем, может, кому-то пригодится. Вот чего примерно хотел добиться:
Моргание светодиодом с рандомно меняющимися интервалами во включенном и выключенном состоянии.
Причем интервал рандома включенного и выключенного состояния настраиваются отдельно.
Эффект замыкающей лампы, как в фильмах ужастиках.
C++:
uint32_t tmr1;
uint32_t tmr2;
long per1;
long per2;         
long grandMin = 100;     
long grandMax = 2500;
long prandMin = 100;
long prandMax = 500;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, INPUT);
}

void loop() {
  if (digitalRead(5)){
      if (millis() - tmr1 >= per1){
    tmr1 = millis();
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(4, HIGH);
    per1 = random(prandMin, prandMax);
  }
  if (millis() - tmr2 >= per2){
    tmr2 = millis();
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(4,LOW);
    per2 = random(grandMin, grandMax);
    }
  }
}
 

poty

★★★★★★✩
19 Фев 2020
2,989
895
@Kirbox, у Вас оба интервала (горения и выключения) обрабатываются всегда, независимо от состояния. Это, тем не менее, не должно приводить к перезагрузкам.
Вторая неточность - разные типы данных, используемые в сравнении. Тоже вряд ли к перезагрузке должно приводить, но может потенциально приводить к "замораживанию" состояния светодиода.
Ну, и отсутствие инициализации переменных...
Должно быть примерно так:
C++:
#define     grandMin    100
#define     grandMax    2500
#define     prandMin    100
#define     prandMax    500
#define        keyPin        5
#define        LED2Pin        4

uint32_t timer, period;
boolean is_on, is_pressed

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
  pinMode(keyPin, INPUT);
  is_on = false;                        // выключаем LEDs
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(LED2Pin,LOW);
  is_pressed = false;                    // кнопка не нажата
}

void loop() {
  if (digitalRead(keyPin)){
    if (!is_pressed) {                    // нажали кнопку только что
      is_pressed = true;
      is_on = true;                        // включаем LEDs на рандомный интервал
      period = random(grandMin, grandMax);
      digitalWrite(LED_BUILTIN, is_on);
      digitalWrite(LED2Pin, is_on);
    }
    if (millis() - timer >= period) {    // рандомный интервал закончился
      timer = millis();
      is_on = !is_on;                    // меняем статус LEDs
      digitalWrite(LED_BUILTIN, is_on);
      digitalWrite(LED2Pin, is_on);
                                          // вычисляем новый интервал
      if (is_on) period = random(grandMin, grandMax);
      else period = random(prandMin, prandMax);
    }
  } else if (is_pressed) {                // кнопка только что отжата
    is_pressed = false;
    is_on = false;                        // выключаем LEDs
    digitalWrite(LED_BUILTIN, is_on);
    digitalWrite(LED2Pin, is_on);
  }
}
Код не проверен!