"EVERY_N_MILLISECONDS"

c

Одним из примеров FastLED, который я видел, было использование кода, который выглядит следующим образом:

EVERY_N_MILLISECONDS( 300 ) { transition_step(); }

Я скопировал его и успешно использовал в том же контексте, но понятия не имею, что это такое и как оно работает.

Поиск в Google не находит никаких ссылок вообще нигде.

Я все еще новичок в C, но для меня это выглядит как Определение - все в верхнем регистре - это определено где-то в библиотеке FastLED?

, 👍6


3 ответа


Лучший ответ:

5

Да, он определен в библиотеке FastLED. Это макрос препроцессора, который при компиляции заменяется блоком кода:

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

Если вы хотите попытаться расшифровать все это, это находится в файле lib8tion.h в библиотеке FastLED.

,

Отличный ответ, спасибо Маенко. Если это так сложно, то я почти наверняка не смогу расшифровать его без большой головной боли, в основном я хотел быть уверенным, что не неправильно понимаю что-то фундаментальное в языке. Я предполагаю, что я не могу сделать так, чтобы эта вещь появлялась дважды, если она определяет функции...?, @Lefty

Вы случайно не знаете, блокирует ли он или просто NOP, если таймер еще не сработал?, @hashier


3

Как сказал @Majenko, он определен в библиотеке FastLED http://fastled.io/. Существует также EVERY_N_SECONDS.

Для использования этих функций нет необходимости вызывать какую-либо другую функцию FastLED в цикле выполнения (например, FastLED.delay ()).

include <FastLED.h>

void loop() {
   ....
   EVERY_N_MILLISECONDS( <mseconds> ) { 
     <your timed code here>; 
   }

   EVERY_N_SECONDS( <seconds> ) { 
     <your timed code here>; 
   }
}
,

2

Это макрос, который обертывает код, который вы помещаете в него, чтобы он запускался только на основе временного интервала, который вы ему передаете. Цель этого состоит в том, чтобы позволить запускать код на основе таймера без необходимости блокировать основной loop(). Когда код компилируется, он оборачивается другим кодом, который определяет, как должен выполняться код внутри него.

Допустим, вы хотите запускать метод каждые 100 мс. Простой подход был бы следующим:

// loop() запускает код внутри него снова и снова со скоростью, основанной на
// how fast the microprocessor runs - specifically how long it takes 
// для процессора, чтобы пройти через код внутри него.
void loop(){

doMethod();
delay(100);

checkForButtonInput();

} 

Проблема здесь в том, что во время delay () функция delay() по своей конструкции занимает все процессорное время в течение 100 мс, и поэтому checkForButtonInput() не может проверить ввод, так как программа в настоящее время застревает внутри функции delay() до тех пор, пока не пройдет 100 мс.

EVERY_N_MILLISECONDS( <mseconds>) {} - это ответ здесь, и вы можете думать, что он работает, чтобы добавить код к вашему коду следующим образом (хотя это не совсем точно):

void loop() {
   EVERY_N_MILLISECONDS( 100 ){
  //псевдокод
  //if ( прошло 100 мс с тех пор, как мы в последний раз делали doMethod() ) {
      doMethod();
      // время сброса с момента выполнения doMethod() до 0
  //}
  //else {
  // продолжайте...
  //}
  }
  checkForButtonInput();
} 

поэтому, если не прошло 100 мс с тех пор, как мы в последний раз были в коде EVERY_N_MILLISECONDS, то мы просто двигаемся дальше, и поэтому checkForButtonInput() вызывается как можно чаще, и входы не будут пропущены.

,