мигает слишком быстро

Unoss

✩✩✩✩✩✩✩
18 Ноя 2023
1
0
попробовал сделать библиотеку посмотрел видео вроде всё понял написал код попробовал, но не работает. точнее работает но не так как надо светодиод вместо того чтобы моргать просто светит очень тускло вот полный код
C++:
bool delayStoped;
bool aTimerBool;

void aDelay(uint32_t aTime) {
  bool asj92ef4r;
  if (millis() >= aTime && asj92ef4r == 0) {
    dxfa2se = millis();
    delayStoped = 1;
    asj92ef4r = 1;
  }
}

void aTimer(uint32_t aTime2) {
  uint32_t dxfa2se;
  if (millis() - dxfa2se >= aTime2) {
    dxfa2se = millis();
    aTimerBool = 1;
  }
}
и вот ещё

C++:
#include "aTimerLib.h"
bool blink1;
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  aTimer(1000);
  if (aTimerBool == 1) {
    blink1 = !blink1;
    digitalWrite(13, blink1);
    aTimerBool = 0;
  }
}
 

poty

★★★★★★✩
19 Фев 2020
3,179
928
@Unoss, в коде куча ошибок, в частности, локальные переменные не инициализируются перед их применением. Также писать библиотеку, зависящую от определённых в ней локальных переменных - плохой тон.
 

asaitov

✩✩✩✩✩✩✩
16 Янв 2024
10
3
Чтобы просто заработало, можно добавить ключевое слово static перед uint32_t dxfa2se;, но как уже сказали выше, качество кода не на высоте. И вот почему.

Функцию aTimer нельзя будет использовать для разных таймеров, так как она использует глобальную переменную aTimerBool и не понятно, к какому таймеру ее значение относится. Название функций и переменных просто плохое - не понятно, что они означают. Вообще, правильно выбранные названия - это залог успеха, они вносят ясность, внушают оптимизм и пользователь библиотеки обязательно скажет тебе за это спасибо. Функция aDelay вообще не используется и не понятно, зачем нужна.

Попробуем улучшить твою библиотеку. Во-первых, поменяем название функции aTimer. Для этого зададим вопрос: что она делает? По идее, она проверяет, не прошел ли определенный промежуток времени со времени последнего срабатывания таймера, и если прошёл, то считаем, что таймер снова сработал. Теперь надо перевести это на английский и постараться, чтобы получилось не слишком длинно. Я плохо придумываю названия, поэтому пусть будет trigger_if_passed.

Дальше, так как мы хотим знать, сработал ли снова таймер, то пусть она возвращает bool.

И наконец, если мы хотим, чтобы можно было использовать в программе несколько таймеров, нужно указать, какой таймер мы имеем в виду. Таким образом, мы получаем функцию
C++:
bool trigger_if_passed(uint32_t interval, timer_t *timer);
Что такое timer_t? Это тип, в котором мы будем хранить информацию о таймере. Почему мы передаем в функцию ссылку на таймер timer_t *timer, а не сам таймер? Потому что при передаче в функцию таймера создается его локальная копия, что делает невозможным его изменение внутри функции.

Пришло время определить timer_t. О таймере нам нужно знать только время его последнего срабатывания (достаточно uint32_t), поэтому можно определить его как typedef uint32_t timer_t;. Но если таймер должен срабатывать через одинаковые промежутки времени, то лучше размер этих промежутков сделать свойством таймера и хранить в нем. Тогда таймер можно определить как
C++:
typedef struct {
  uint32_t last_trigger_time; // время последнего срабатывания
  uint32_t interval; // интервал
} timer_t;

// Тогда объявление функции можно переписать так. Я поменял заодно название, оно мне показалось лучше.
bool timer_is_triggered(timer_t *timer);
Теперь можно реализовать функцию timer_is_triggered.
C++:
bool timer_is_triggered(timer_t *timer) {
  uint32_t now = millis(); // текущее время
  if (timer->last_trigger_time + timer->interval > now) { // если со времени последнего срабатывания прошло больше, чем `interval`
    timer->last_trigger_time = now; // обновляем время последнего срабатывания
    return true;
  } else {
    return false;
  }
}
Тут можно заметить, что timer->last_trigger_time + timer->interval почти все время будет одинаковым и по сути означает время следующего срабатывания триггера, поэтому чтобы не делать каждый раз это вычисление, можно хранить его вместо времени последнего срабатывания. Итого получаем
timer_lib.h:
typedef struct {
  uint32_t next_trigger_time;
  uint32_t interval;
} timer_t;

bool timer_is_triggered(timer_t *timer) {
  uint32_t now = millis();
  if (timer->next_trigger_time > now) {
    timer->next_trigger_time = now + timer->interval;
    return true;
  }
  return false;
}
И пример использования:
C++:
#include "timer_lib.h"

timer_t led_timer;

void setup() {
  led_timer = {
    .next_trigger_time = 0,
    .interval = 1000
  };
  // прочая инициализация
}

void loop() {
  if (timer_is_triggered(&led_timer)) { // если таймер сработал
    // меняем состояние светодиода
  }
}
Чтобы сделать код еще лучше, можно воспользоваться средствами языка C++ и объявить таймер как класс, но это уже другая история.
 
  • Лойс +1
Реакции: Unoss