Вопрос по нестандартному использованию millis()

blokerun2
Offline
Зарегистрирован: 27.01.2019

Помогите пожалуйста советом! Нужно реализовать следующую задачу. Запускать функции scan1(), scan2().... scanN() через определенное время используя функцию millis() или любой другой инструмент. Функций будет много (до 30), запускать нужно все через одинаковое время (не важно, в какой последовательности), и основное требование - переменная точки отсчета getData_Millis должна быть только одна! Конструкция приведенная ниже (упрощенная для наглядности) работает некорректно, идут пропуски запуска функций, то одной то другой



#define scan_Period 500 #define getData_Period 5000

uint32_t getData_Millis = 0;

uint32_t scan_Millis = 0;

void setup(){
Serial.begin(115200);
}

void loop(){

if (millis() - scan_Millis >= scan_Period){
scan_Millis = millis(); 
scan1();
scan2();

scanN(); }
}

void scan1(){

if (millis() - getData_Millis >= getData_Period){
Serial.println("Считали датчик1 ");
getData_Millis = millis();
}
}

void scan2(){

if (millis() - getData_Millis >= getData_Period){
Serial.println("Считали датчик2 ");
getData_Millis = millis();
}
}

void scanN(){
if (millis() - getData_Millis >= getData_Period){
Serial.println("Считали датчик3 ");
getData_Millis = millis();
}
}

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Собери в массив все указатели на функции. В loop() в одном месте проверяй не закончился ли нужный интервал и вызывай очередную функцию из массива. 

using pvfScanFunc = void(*)(void);  // тип pointer to void function 

pvfScanFunc ScanFuncArray[] = { scan1, scan2, scan3 ... scan50 };

const uint8_t SCAN_FUNC_ARRAY_SIZE = sizeof(ScanFuncArray) / sizeof(ScanFuncArray[0]);

uint8_t CurrentFuncIndex = 0;

 

blokerun2
Offline
Зарегистрирован: 27.01.2019

Спасибо большое !

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

А что нестандартного в таком использовании миллиса?

FoxJone
Offline
Зарегистрирован: 19.04.2019

Сентябрь на дворе, школьники домашку решают...

blokerun2
Offline
Зарегистрирован: 27.01.2019

ну и помог бы школьнику...

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Дак тебе и так сказали, что надо делать. Если нужен готовый код, давай пицот р. 

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

DetSimen пишет:

Дак тебе и так сказали, что надо делать. Если нужен готовый код, давай пицот р. 

Деда! Кончай демпинговать! Час работы программера от 20 до 40 баксов! На мелких проектах выше. Ты с такими ценами милостыню просить будешь.

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Logik пишет:

Ты с такими ценами милостыню просить будешь.

Дак я уже и так, не далее чем в мае, просил-побирался

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Logik пишет:

DetSimen пишет:

Дак тебе и так сказали, что надо делать. Если нужен готовый код, давай пицот р. 

Деда! Кончай демпинговать! Час работы программера от 20 до 40 баксов! На мелких проектах выше. Ты с такими ценами милостыню просить будешь.

стоит то он конечно стоит, но кто ему пенсионеру их даст, Дет реалист однако )))

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

Проси больше - все равно урежут ))

blokerun2
Offline
Зарегистрирован: 27.01.2019

Еще нашел удобный макрос для использования функции millis(). Использовать можно просто вставляя нужное время как аргумент.

EVERY_MS(Period) {
	// выполняемый код
	  }

//---------------Macros millis()------------
#define EVERY_MS(x) \
  static uint32_t tmr;\
  bool flag = millis() - tmr >= (x);\
  if (flag) tmr += (x);\
  if (flag)

 

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

Не надо искать "удобные макросы", почти все они написаны неграмотными помогальщиками типа гайвера. Вот и в этом строка 9 - бред

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

b707 пишет:
Не надо искать "удобные макросы", почти все они написаны неграмотными помогальщиками типа гайвера. Вот и в этом строка 9 - бред

не всё так однозначно, если бы не Гайвер я бы и не узнал что в IDE есть плоттер )))

kalapanga
Онлайн
Зарегистрирован: 23.10.2016

blokerun2 пишет:

Еще нашел удобный макрос для использования функции millis(). Использовать можно просто вставляя нужное время как аргумент.

Попробуйте сами использовать Ваш макрос в коде два раза. Макросы ведь для этого нужны?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

blokerun2 пишет:

Еще нашел удобный макрос 

А теперь попробуйте этот удобный макрос использовать

1. дважды в одном коде.
2. в цикле.

Я уж не говорю про совершенно верное замечание из #12

v258
Онлайн
Зарегистрирован: 25.05.2020

ua6em пишет:

не всё так однозначно, если бы не Гайвер я бы и не узнал что в IDE есть плоттер )))

Как написал один из иностранцев под одним из его видео (сорри, вольный перевод по памяти )) - "хороший блогер, никакой программист" )))

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

b707 пишет:
типа гайвера.
Почему "типа"? Оно и есть в чистом виде - https://alexgyver.ru/lessons/time/

v258
Онлайн
Зарегистрирован: 25.05.2020

Но он там честно предупреждает )))

Единственное ограничение: нельзя вызывать макрос больше одного раза в одном и том же блоке кода, это приведёт к ошибке =) 

Но кто эти инструкции читает?... )

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

v258 пишет:

Но он там честно предупреждает )))

Единственное ограничение: нельзя вызывать макрос больше одного раза в одном и том же блоке кода, это приведёт к ошибке =) 

Но кто эти инструкции читает?... )

1. А кому тогда нахрен нужен такой макрос? И тем более, что исправить так, чтобы было можно - как два пальца.

2. А про то, что он сработает только 1 раз и то отсчитает время не от вызова, а от включения питания там тоже написано?

Не защищайте безграмотный бред - ставите себя в неловкое положение.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Не защищайте безграмотный бред - ставите себя в неловкое положение.

Зато тема есть, в песочницу, Пишем макросы правильно, прямо на основе кода Гайвера и сделать.

PS помню стрельбы, первым стреляет Замполит, после его стрельбы общее построение и,
капитан...сейчас показал Вам, как не надо стрелять )))

 

v258
Онлайн
Зарегистрирован: 25.05.2020

ЕвгенийП пишет:

2. А про то, что он сработает только 1 раз и то отсчитает время не от вызова, а от включения питания там тоже написано?

Минуточку. Не в защиту, а для самообразования - а почему только один раз? Разве макрос при компиляции не будет заменен кодом? Т.е. вот это 

{
  EVERY_MS(x)
  {
  // здесь код
  }
}

будет заменено вот этим?

{
  static uint32_t tmr;\
  bool flag = millis() - tmr >= (x);\
  if (flag) tmr = millis();\
  if (flag)
  {
  // здесь код
  }
}

И если да, то почему сработает один раз? И если нет - то тоже почему? ))

sadman41
Offline
Зарегистрирован: 19.10.2016

А напишите вот так в исходнике

static uint32_t tmr;
static uint32_t tmr;

и откомпилируйте.

А почему от включения... потому что на старте tmr = 0.

v258
Онлайн
Зарегистрирован: 25.05.2020

sadman41 пишет:

А напишите вот так в исходнике

static uint32_t tmr;
static uint32_t tmr;

и откомпилируйте.

Это понятно. Но речь таки об однократном использовании в блоке

sadman41 пишет:

А почему от включения... потому что на старте tmr = 0.

Это первое срабатывание. А почему оно будет только одно? Вот что меня заинтересовало

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

v258 пишет:

Это первое срабатывание. А почему оно будет только одно? Вот что меня заинтересовало

Виноват, не заметил строки 

if (flag) tmr = millis();\

Datak
Offline
Зарегистрирован: 09.10.2014

b707 пишет:
Не надо искать "удобные макросы", почти все они написаны неграмотными помогальщиками типа гайвера. Вот и в этом строка 9 - бред

ЕвгенийП пишет:
Я уж не говорю про совершенно верное замечание из #12

Строка 9 - это вот.

if (flag) tmr += (x);

Очень было бы интересно узнать, чего в ней, всё-таки, бредового. Раз уж замечание про бредовость вызвало такое пятикратное плюсование. ))

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Datak пишет:

Строка 9 - это вот.

if (flag) tmr += (x);

Очень было бы интересно узнать, чего в ней, всё-таки, бредового.

Вот тока не надо снова!!! Если ты серьёзно написал, то прочти пожалуйста тему (до достижения дзена)!

http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis

Datak
Offline
Зарегистрирован: 09.10.2014

Написал серьёзно. И утверждаю что эта строчка к переполнению не имеет никакого отношения.

Не знаю кто такой Гайвер, но чувствую, он тут для всех вроде красной тряпки для быка. ))

Мне по барабану разные Гайверы, но в данном случае строчка правильная, и абсолютно по делу.

-------

От себя могу предложить такую версию макроса

#define EVERY_MS(X) for( static uint32_t T = millis( ); millis( ) - T >= (X); T += (X) )

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

В ардуиновском случае будет точно, если не перенастраивать флаги компилятора используемые по умолчанию.

void loop( )
{
  EVERY_MS( 1000 )
  {
    Serial.print( "=1000=" );
    digitalWrite( LED, !digitalRead( LED ) );
  }  
  
  EVERY_MS( 1150 ) Serial.println( "=1150=" );
}

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Datak пишет:

Не знаю кто такой Гайвер, но чувствую, он тут для всех вроде красной тряпки для быка. ))

Мне по барабану разные Гайверы, но в данном случае строчка правильная, и абсолютно по делу.

Просвещу )))

Вот Вам барабан ...это я о 1,84 млн подписчиков

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Datak пишет:

Написал серьёзно. И утверждаю что эта строчка к переполнению не имеет никакого отношения.

Не знаю кто такой Гайвер, но чувствую, он тут для всех вроде красной тряпки для быка. ))

Мне по барабану разные Гайверы, но в данном случае строчка правильная, и абсолютно по делу.

-------

От себя могу предложить такую версию макроса

#define EVERY_MS(X) for( static uint32_t T = millis( ); millis( ) - T >= (X); T += (X) )

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

В ардуиновском случае будет точно, если не перенастраивать флаги компилятора используемые по умолчанию.

void loop( )
{
  EVERY_MS( 1000 )
  {
    Serial.print( "=1000=" );
    digitalWrite( LED, !digitalRead( LED ) );
  }  
  
  EVERY_MS( 1150 ) Serial.println( "=1150=" );
}

 

Ты токашто заслужил высокое звание "Человек-дурак". Теперь у тебя здесь привилегии. 

Datak
Offline
Зарегистрирован: 09.10.2014

DetSimen пишет:

Ты токашто заслужил высокое звание "Человек-дурак". Теперь у тебя здесь привилегии. 

Дет, спасибо. Заслужить такую высокую оценку от тебя - особенно почётно! 

Upper
Offline
Зарегистрирован: 23.06.2020

Он завтра проспится, может поймет, что сам дурь написал. Но ему можно у него давно здесь привилегии. Он ведь модератор.

Green
Offline
Зарегистрирован: 01.10.2015

Upper пишет:

Он ведь модератор.


Причём здесь ЭТО! Неужто не понятно что дважды EVERY_MS() в одном блоке не прокатит!
Вот поэтому он и каличный макрос. Костыль!
А for здесь ВООБЩЕ не к месту!

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Datak пишет:

Очень было бы интересно узнать, чего в ней, всё-таки, бредового. 

Вам правда интересно? Или так, потрепаться? Если интересно могу пояснить и привести пример, когда из-за этого всё валится. Если же Вы это просто для поддержания разговора, то ... в лом. Устал я сегодня.

Upper
Offline
Зарегистрирован: 23.06.2020

Green пишет:

Upper пишет:

Он ведь модератор.


Причём здесь ЭТО! Неужто не понятно что дважды EVERY_MS() в одном блоке не прокатит!
Вот поэтому он и каличный макрос. Костыль!
А for здесь ВООБЩЕ не к месту!

Я скомпилировал и запустил. - работает.

Запускал в симуляторе Atmel Studio 7. Поэтому времена задержек маленькие, чтобы не ждать. Переменные i и к для контроля значений при отладке. В Arduino IDE компилируется без ошибок. Но если заливать скетч, то надо поменять задержки на 1000 и 2000

 

#include <Arduino.h>

#define EVERY_MS(X) for( static uint32_t T = millis( ); millis( ) - T >= (X); T += (X) )

volatile int i, k, m;

void setup() {

   Serial.begin(115200);
}

void loop() {
  EVERY_MS( 1 )
  {
	  i = T;
	  Serial.print( "1" );
	  
  }
  EVERY_MS( 2 ) 
  {
	k=T;
	Serial.print( "2" );
  }
}

 

Datak
Offline
Зарегистрирован: 09.10.2014

ЕвгенийП пишет:

Вам правда интересно? Или так, потрепаться? Если интересно могу пояснить и привести пример, когда из-за этого всё валится. Если же Вы это просто для поддержания разговора, то ... в лом. Устал я сегодня.

Так, в целом - да, сегодня свободный день, поэтому потрепаться. Но не посраться, а потрепаться именно по делу.

Просто всегда режут слух заявления типа "бред", если они никак не объясняются и ничем не подкрепляются. 

Я понимаю, что никто не идеален, и каждый может ошибаться. Поэтому даже не стал спорить с тем что "бред", а просто сказал, что мне так не кажется. И попросил разъяснить, если я что-то не увидел.

Вот например wdracula мне сразу ответил, почему считает код бредом. Ему показалось, что там ведётся упорная борьба с переполнением millis( ), про которую, да, говорено уже тыщщу раз. Я же, в свою очередь, написал что строка, обсуждаемая, совсем не про то. Ну, будет у него время/желание - посмотрит внимательней, и наверно со мной согласится. А может и переубедит меня - кто знает. ))

ЕвгенийП, ситуацию "когда из-за этого всё валится" - да наверно можно придумать. Я и не говорил что в том первоначальном варианте всё идеально. Но всё же, согласитесь, между "бред" и "не идеально" есть разница, вот я о чём.

Примеры посмотреть интересно - но это, разумеется, по Вашему желанию, если устали не очень сильно.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Понимаете, ошибка - ошибке рознь. В строке о которой шла речь (девятой), происходит увеличение неинициализированной переменной (это, кстати, очень характерно для гивера, он часто так делает).  Такие ошибки я считаю бредом, хотя, это, конечно, вопрос терминологии.

В результате, полюбуйтесь, что получается в весьма штатной, совсем не "надуманной" ситуации

//---------------Macros millis()------------
#define EVERY_MS(x) \
  static uint32_t tmr;\
  bool flag = millis() - tmr >= (x);\
  if (flag) tmr += (x);\
  if (flag)

void setup (void) {
	Serial.begin(57600);
	//
	// Здесь идёт инициализация разных модулей, которая требует времени
	// Поставим задержку для того, чтобы сыммитировать эту инициализацию
	delay(500);
}

void loop(void) {
	static int counter = 0; // отработает только 10 раз, чтобы не засирать бесконечно экран
	
	static uint32_t oldMillis = millis();
	EVERY_MS(100) {
		if (counter++ < 10) {
			// Печатаем значение millis и длительность последнего интервала
			Serial.print(millis());
			Serial.print(" - ");
			Serial.println(millis() - oldMillis);
			oldMillis = millis();
		}
	}
}

Куда пропали первые пять интервалов? Вот туда и пропали - ждали пока миллис до 500 дорастёт.

Datak
Offline
Зарегистрирован: 09.10.2014

Upper пишет:

В Arduino IDE компилируется без ошибок. Но если заливать скетч, то надо поменять задержки на 1000 и 2000

Для проверки задержки лучше взять некратные - результат будет выглядеть интереснее.

Datak
Offline
Зарегистрирован: 09.10.2014

ЕвгенийП пишет:
происходит увеличение неинициализированной переменной (это, кстати, очень характерно для гивера, он часто так делает)

Инициализированной нулём, если не ошибаюсь. Хотя, да, меня такое использование переменных тоже коробит, и я всегда в тексте инициализирую явно все переменные, даже глобальные.

Кроме тех, для которых начальное значение действительно не важно. 

ЕвгенийП пишет:
Такие ошибки я считаю бредом, хотя, это, конечно, вопрос терминологии.

В результате, полюбуйтесь, что получается в весьма штатной, совсем не "надуманной" ситуации

Спасибо, теперь хотя бы понятно, о чём речь.

Но профессионалы говорят - "это не баг, это фича!". ))

Программа отработала именно так, как её написали. Где же тут что порушилось?

И если уж считать что ошибка есть, то она не в той "бредовой" строке, а здесь.

static uint32_t tmr;

Изменяем - и всё работает уже по-другому.

#define EVERY_MS(x) \
  static uint32_t tmr = millis();\
  bool flag = millis() - tmr >= (x);\
  if (flag) tmr = millis();\
  if (flag)

Но точно ли мы хотели по-другому?

А если мы, например, пишем какие-нибудь большие настенные часы, и должны увеличивать счётчик секунд именно в соответствии с количеством прошедших секунд?

Должны ли мы пропустить несколько интервалов, из-за того что какое-нибудь, допустим, чтение даллас-температуры провисело неизвестно сколько времени, не возвращая управление в основной loop( )? Или всё же лучше эти интервалы приплюсовать, хоть и с опозданием?

Нет, это фича, однозначно. И очень полезная, кстати - она позволяет отсчитывать интервалы без накопления погрешности. То есть, видите сами - погрешность для каждого отдельного интервала есть - а накопления нет.  И в среднем, за время выполнения программы (1 секунда) мы имеем ожидаемые десять 100-миллисекундных тиков.

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

Datak пишет:

Должны ли мы пропустить несколько интервалов, из-за того что какое-нибудь, допустим, чтение даллас-температуры провисело неизвестно сколько времени, не возвращая управление в основной loop( )? Или всё же лучше эти интервалы приплюсовать, хоть и с опозданием?

Нет, это фича, однозначно. И очень полезная, кстати - она позволяет отсчитывать интервалы без накопления погрешности. То есть, видите сами - погрешность для каждого отдельного интервала есть - а накопления нет.  И в среднем, за время выполнения программы (1 секунда) мы имеем ожидаемые десять 100-миллисекундных тиков.

про "фичу" это вы Гайверу расскажите... он любит прикрывать свои косяки подобными росказнями

У него есть замечательная библиотека GyverTimer. В первой версии он отсчитывал интервалы вот этим способом:

  static uint32_t tmr = millis();
  bool flag = millis() - tmr >=interval;
  if (flag) tmr = millis();\

но так как писать код у него не очень получается, нередко выходило, что выполнения кода в ЛУП длилось больше интервала и таймер начинал отставать. Это особенно забавно, когда Алекс использует эту библиотеку для отсчета времени в часах (проект "Часы-метеостанция") - народ массово начал жаловаться. что часы почему-то отстают на несколько минут в сутки.

Тогда он написал вторую версию - ту за которую вы тут копья ломаете, где последняя строчка такая


  if (flag) tmr +=x:

часы теперь не отстают, но так как проблемы с кодом в Луп остались теми же - теперь народ жалуется, что таймер срабатывает неравномерно :)

Что характерно - после исправления GyverTimer-а с первой версии на вторую Алексу не пришло в голову заменить библиотеку в старых проектах - поэтому "Часы-метеостанция" как отставали. так и отстают. Почему - да потому что Гайвер не имеет  понятия о принципах повторного использования кода и в каждый свой проект вкладывает копии всех используемых библиотек, вместо того чтоб включать только ссылки. Таким образом, отслеживать акутуальность кода библиотекв каждом проекте становится невероятно сложно - вот он и не отслеживает...

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Datak пишет:

Программа отработала именно так, как её написали. 

Все программы так работают. Вы знаете хоть одно исключение?

Datak пишет:

Где же тут что порушилось?

Заказанные интервалы не отработали. Вы считаете. что это не порушилось? Ну, значит, не порушилось.

Datak пишет:

Нет, это фича, однозначно. 

Этот расскажите кому-нибудь другому. Я точно знаю чем отличается фича от бага - первая документирована, а второй - нет.

Пассажа про накопление погрешности я не понял вовсе. Каким там боком накопление ... это выходит за рамки моей понималки.

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Ладно, Datak, со званием я несколько погорячился, прошу прощения.

Но, люди, призываю вас, забудьте про дефайны и макросы вместе с Си, как страшный сон, в 80% случаев они работают не так, как вы планировали.  А у новичков - в 146% случаев.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

Ладно, Datak, со званием я несколько погорячился, прошу прощения.

Но, люди, призываю вас, забудьте про дефайны и макросы вместе с Си, как страшный сон, в 80% случаев они работают не так, как вы планировали.  А у новичков - в 146% случаев.

до макросов я еще не дорос, а вот что не так с дефайнами, а то использую

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

ua6em пишет:

до макросов я еще не дорос, а вот что не так с дефайнами, а то использую

Используй лучше constexpr. На худой конец простой const. На размер кода это никак не влияет, а с типами они тебе лохануться не дадуть.  

Не зря ж в твоём теперь FT879D.h нет ни одного #define.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

DetSimen пишет:

ua6em пишет:

до макросов я еще не дорос, а вот что не так с дефайнами, а то использую

Используй лучше constexpr. На худой конец простой const. На размер кода это никак не влияет, а с типами они тебе лохануться не дадуть.  

Не зря ж в твоём теперь FT879D.h нет ни одного #define.

мои дефайны за рамки байта не распространяются )))
кстати, хотел энкодер за прерывание PCINT зацепить, ан нет, компилятор орёт - повторное определение в библиотеке CustomSoftwareSerial, впрямую не увидел, но она подтягивает Interrupt.h видимо там и как тут не быть )))

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

ua6em пишет:

мои дефайны за рамки байта не распространяются )))

Вот тут-то и засада!

Green
Offline
Зарегистрирован: 01.10.2015

Upper пишет:

Я скомпилировал и запустил. - работает.

Моя реплика относилась к другому (Гайверовскому) макросу EVERY_MS. Касательно 

#define EVERY_MS(X) for (static uint32_t T = millis(); millis() - T >= (X); T += (X))
 

здесь, с виду, всё нормально.
За исключением того, что первое выполнение произойдёт сразу, а не через Х.

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:

мои дефайны за рамки байта не распространяются )))

Вот тут-то и засада!

" нам учитель задаёт с иксами задачу..."
 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

ЕвгенийП пишет:

Вот тут-то и засада!

а вот так считается более корректным?

#define pinLed (byte)5

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Green пишет:
 

#define EVERY_MS(X) for (static uint32_t T = millis(); millis() - T >= (X); T += (X))
 

здесь, с виду, всё нормально.
За исключением того, что первое выполнение произойдёт сразу, а не через Х.

Почему?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

andycat пишет:

а вот так считается более корректным?

#define pinLed (byte)5

Я бы ещё внешние скобки добавил - здоровая привычка. Но идейно это всё равно менее правильно, чем 

static constexpr byte printlen = 5;

В данном конкретном случае как бы разницы и нет, но если говорить об использовании таких конструкций вообще, то есть много ситуации, когда сразу описать нужный тип выгоднее, чем писать преобразование.

Хотя, сам я часто использую дефайны - привычки, формировавшиеся десятилетиями, не так легко вытравить. А вот начинающим советовал бы не привыкать.