Помогите разобраться с задержками

antidote

✩✩✩✩✩✩✩
16 Фев 2022
11
0
Всем привет, делаю управление кулером с помощью ШИМ. С программированием Ардуино не знаком, код местами делался методом научного тыка)))
Кароче логика такая должна быть: при нажатии на кнопку должен перебираться массив скважности ШИМ, и светодиод должен в качестве индикатора моргать при первой скорости один раз, при второй два и ид. Эта индикация у меня раз в две секунды происходит. На данный момент код работает, но пришлось вставить костыль в виде стандартной задержки, иначе тот же цикл for пролетает за раз. Но при данной задержке уже на максимальной скважности кулер работает некорректно. Помогите избавиться от задержки.

C++:
#include <TimerMs.h>;

TimerMs onLED(200, 1, 1);
TimerMs offLED(400, 1, 1);
TimerMs pauseLED(2000, 1, 1);

int pwm_out = 0;
int btn = A2;
int ledPin = A1;

byte out[] = {63, 127, 190, 255};
int i = 1;

int buttonState = 0;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  Serial.begin(9600);
  pinMode(pwm_out, OUTPUT);
  pinMode(btn, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  analogWrite(pwm_out, out[0]);
}

void ledIndicate(int x) {
  if (pauseLED.tick()) {
    for (int n = 0; n < x*2; n++) {
      if (onLED.tick()) {
        digitalWrite(ledPin, (n % 2) == 0);
        // Serial.println(digitalRead(ledPin));
        onLED.resume();
        delay(150);
      }
    }
  pauseLED.start();
  }
}

void loop() {
  ledIndicate(i);
  Serial.println(out[i-1]);
  int reading = digitalRead(btn);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {
        i++;
        if (i > 4) i = 1; analogWrite(pwm_out, out[i-1]);
      }
    }
  }
  lastButtonState = reading;
}
 

Nikanor

★★✩✩✩✩✩
1 Окт 2020
178
51
у вас в логике программы полная каша.
сначала научитесь кнопкой менять переменную.
для этого цикл for нафиг не нужон.
 

andyparker

✩✩✩✩✩✩✩
14 Окт 2020
18
1
Для неблокирующего моргания светодиодом можно ввести 3 переменные: количество вспышек, переменную-таймер и bool-флаг моргания. Неблокирующая задержка имеет следующий вид:
C++:
if (millis() - led_delay >= *delay is ms*) {
    // do something
    led_delay = millis();
}
Для ограничения моргания в одну полную итерацию переменная bool будет изменяться на true при нажатии кнопки. При true функция моргания работает, за каждую итерацию вычитая 1 из количества морганий. Когда количество морганий станет равным 0, флаг ставится в false и функция ждет следующего нажатия кнопки как установка флага в true.
 

antidote

✩✩✩✩✩✩✩
16 Фев 2022
11
0
@andyparker, так сейчас итак у меня неблокирующее моргание и количество морганий можно выбирать. Проблема в том, что цикл этот пролетает даже с 4 вспышками безо всяких задержек, поэтому пришлось добавить паузу в 150 обычным delay(). Но вообще может я чет не понимаю.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
478
137
Но при данной задержке уже на максимальной скважности кулер работает некорректно. Помогите избавиться от задержки.
Задержка не должна влиять на работу кулера. Алгоритм у вас с принципиальными ошибками, но на работу кулера это влиять не должно. Как именно "некорректно" работает кулер?
 

antidote

✩✩✩✩✩✩✩
16 Фев 2022
11
0
@Bruzzer, обороты то падают, то нарастают на максималке. Смотрел вывод в терминал сигнала на пине, при задержке он останавливается вроде, думаю поэтому и фигня такая.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
478
137
@antidote,
Понятней не стало. Отчего обороты, то падают то нарастают, вы ничего не нажимаете, а они меняются? Как у вас подключен мотор?