мы все же о разном говорим, как мне кажется. millis() вы предлагаете использовать для формирования неких тиков и флагов, которые в loop() обрабатываются и выполняется какой-то функционал. а я millis() хочу использовать для вычисления требуемой задержки, причем в цикле while(), где эта задержка вертится, переходить на другую задачу. next_task() я же не зря привел в тексте
Можно есть без вилки или без палочек. Но с инструментами удобнее. Нет?
скорее всего да. я мог бы, конечно, все процедуры инициализации и измерения (по каждому датчику) запускать последовательно и делать максимально требуемую задержку. Но код будет тяжелым и неприятным в этом случае.
с интересом понаблюдаю за темой
Тяжесть и неприятность кода определяются автором, но не методом. Зуб даю!
Попытаюсь сформулировать другими словами то, что Вам тут уже давно пытаются объяснить.
Вы неправильно проектируете программу.
Вот подумайте сами: если Вам, скажем, нужно сварить 3 блюда, причем у каждого свое время приготовления, Вы что, до готовности первого нее можете поставить на варку второе?
Опишите словами последовательность своих действий. Вот точно так же опишите словами, что должен делать микроконтроллер. По-русски.
Если опять непонятно, могу порекомендовать следующее:
- Внимательно разобрать пример blink without delay.
- Добавить в код второй светодиод со своей (некратной первому) частотой мигания.
- Так же добавить третий светодиод (с частотой некратной первым двум).
- когда добъетесь работы этой конструкции - переходите к своим датчикам.
я вас понял. надо менять концепцию написания программы. и разделять этапы работы с каждым датчиком (скажем от задержки до задержки). это все то, что очевидно, но от чего я всячески пытался уйти.
Еще раз - эта конструкция ничем не отличается от delay()
Семафоры в однопоточном приложении? Мсье знает толк в извращениях
Могу только присоединиться к коллеге @Estorsky и сказать - валяйте.
Мне кажется, вы уже доказали тупиковость этого пути, когда пришли к выводу о необходимости добавить к миллис еще какой-то планировщик.
Еще немного продвинувшись вперед, вы убедитесь, что и планировщик не в состоянии решить вашу проблему.
Но если не хотите никого слушать - дело ваше.
почему? У вас однопоточный контроллер. Выполнять две задачи одновременно он все равно не сможет, какую ОС на него не навали.
Единственный вариант - разделение времени между задачами. Чтобы деать это эффективно, задачу надо разбить на небольшие подзадачи.
Именно так и работают все ОС, кстати.
при работе с каждым датчиком есть несколько задержек: после подачи питания, после инициализации, сброса, старта измерения. чтобы не занимать процессорное время на выполнение delay(), мне надо разделять работу с каждым датчиком на функциональные составляющие или этапы (между этими delay()) и выполнять их в одном потоке (или цикле, loop(), например), а наступление каждого следующего этапа контролировать по сравнению с текущим millis(). А хотелось бы уйти от всего этого. Разместить инициализацию и измерение по каждому датчику в своем потоке (задаче), переписав функцию delay() таким образом, чтобы при входе в нее передавалось управление на другой поток, пока эта задержка не истекла по времени.
вы повторяетесь. Вы все это уже писали. Не хотите идти стандартным путем - никто вас не держит, выдумывайте и пробуйте. Но сами.
То что вы хотите, называется RTOS. Но городить RTOS ради трех датчиков - глупость. И кроме того, ваш код все равно придется переписывать. Ваши циклы while - не подойдут в любом случае.
А вы настойчивый. Про конечные автоматы прочитали? Вам неоднократно намекнули про Блинк-без-дилэй. Он прекрасно работает с КА. Это закрывает вашу задачу на 146%
Да, читаю про автоматы. Концепцию в общем понял, буду переделывать
Я бы уточнил, городить это не умея пользоваться алюминиевой ложкой - глупость в кубе
Да я даже не имею в виду ТС.
На мой взгляд применимость РТОС на контроллерах уровня Уно-Нано, да и Мега тоже - очень под вопросом. Просто потому что задачи, где РТОС мог бы показать свои преимущества - банально не помещаются в эти контроллеры
(личное мнение, на общность не претендую)
Вы упорно пытаетесь натянуть сову на не не предназначенную для этого поверхность. Я дал вам ссылку на диспетчер задач. Никаких манипуляций с миллис там делать не нужно, отсчет интервалов - задача диспетчера. Ваше дело - накидать ему задач. Которые в общем случае должны выглядеть так:
- Первый запуск задачи - включение питания датчика;
- Второй запуск задачи - инициализация датчика;
- Третий запуск задачи - получение данных с датчика;
- Четвертый запуск задачи - отключение питания датчика и остановка задачи.
Интервалы для задач можете определять по своему усмотрению, можете менять интервалы в ходе выполнения и т.д.
Как внутри задачи определить, какой по счету это запуск и, соответственно, какое действие выполнить, сможете сообразить?
ЗЫ: момент, когда диспетчер сообщит, что количество активных задач равно нулю можно считать сигналом к переходу ко сну
ТС, дорогой. А почему бы тебе не взять контроллер, на котором есть FreeRTOS? ЕСП32, любой Арм? Цена почти такая же ± 100р. И там ты напишешь именно так, как хочешь.
Не уверен, что это легче, но если ты не хочешь учить автоматы, то учи потоки и мьютексы.
Это уже всплывало, вроде.
В рамках предложенной мною выше аналогии Вы пытаетесь:
- Поставить на плиту одно блюдо, включить под ним огонь.
- Выставить будильник и идти спать.
- Проснуться по будильнику и снять блюдо с огня.
4, 5, 6. То же самое для второго блюда.
7, 8, 9. То же для третьего.
Теперь Вы решили, что это слишком долго и думаете как-то преобразовать процесс, чтобы сэкономить время, но при этом категорически не хотите как-то преобразовывать группу 1-3 и в частности отказываться от сна.
Т.е. поставить все три блюда на огонь и следить за часами для Вас никак не вариант.
Не знаю, имеете ли Вы такой опыт, но существуют разные подходы к организации программы, грубо говоря, “как в DOS” и “как в Windows”. Вы готовы говорить о каких угодно атрибутах, существующих исключительно в многозадачных ОС, но при этом сохранить основную структуру Вашей программы “как в DOS”. Вам самому не кажется это странным?
По сути программирование микроконтроллеров осуществляется в концепции “как в Windows”, и не нужно пытаться этому препятствовать.