Распределение нагрузки на Arduino
- Войдите на сайт для отправки комментариев
Пнд, 11/04/2022 - 13:16
Здравствуйте. Выкладывать 1000 строк кода не вижу смысла - ну кто станет копаться, в то же время, покопавшись, станет понятно, что просто код без данных не будет значить ничего. Поэтому максимально упрощу вопрос: как на практике оптимизируют нагрузку на не такой уж мощный процессор?
Теперь подробнее, что сделал я. У меня в цикле известная многим конструкция на millis
if (millis() - myTimer >= 10) { myTimer = millis(); timer++; ...... ...... }
ну и чтобы "размазать" (оптимизировать) нагрузку, при timer == 10 выполняю одну функцию, timer == 20 - вторую и так далее, пока таймер не достигнет 99.
Верно ли я поступаю?
Как всегда, есть нюанс: при определённых условиях количество выполняемых функций возрастает - это и получение данных с "аналоговых" портов и их обработка и получение данных с тензодатчиков и отправка данных в serial-порт. Стал подозревать (это именно субъективно), что ардуино сильно загружен и цикл проходит не за секунду, а за, скажем, 1.05 сек.
Стоит ли делать замер каждого времени выполнения каждого действия?
Например (упрощу задачу) есть 10 функций, каждой из которых мы отводим 100 мсек. Выполнение всех 10 функция я назову полным циклом. Отправка килобайта данных в порт занимает 0.15 сек, а значит, весь полный цикл выполнится за 1.05 сек вместо 1 сек. Если отвести на следующую функцию не 100 мсек, а 50, цикл пройдёт ровно за секунду.
Нельзя впихать невпихуемое. Вам критично чтобы этот процесс в секунду укладывался ? А то не совсем понятно в чем печалька, ну размазываете по времени и ладно.
чтобы "размазать" (оптимизировать) нагрузку, при timer == 10 выполняю одну функцию, timer == 20 - вторую и так далее, пока таймер не достигнет 99.
микроконтроллер - однозадачная система. Если он занят, его загрузка 100%. если свободен - 0% Поэтому нет абсолютно никакой разницы, выполняете ли вы задачи кусочками по 100 мс с переключениями или последовательно одну за другой. Точнее есть - первый способ медленнее, так как добавляются еще накладные расходы на переключение между потоками.
Так что главный вопрос, который возникает при чтении вашего сообщения - зачем все это?
Я что то такое делал не для мк, но чтобы пиковой загрузки не было когда звезды неудачно сойдутся, правда там БД и этот пик блокировки таблиц вызывает. Для ардуины может быть чтобы экранчик обновлять регулярнее ? )
Смотрите, у меня 2 вида функций.
Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду. Например, мне нужно, чтобы каждую секунду обновлялась информация на экране о температурах, весе, давлении, времени (что логично), обновлялся график на экране, то есть, я привязан к этим двум временным отрезкам.
Если процессор загружать, как тут выразились, на 100% всеми задачами сразу (поочерёдно), то выполнение одних, "тяжёлых "задач может отсрочить выполнение других.
Концепцию меняй.
Если процессор загружать, как тут выразились, на 100% всеми задачами сразу (поочерёдно), то выполнение одних, "тяжёлых "задач может отсрочить выполнение других.
тебе нужно распределить задачи в три группы -
1) те, которые должны выполнятся строго в определенные моменты времени
2) те, которым время не важно, лишь бы они выполнялись не реже(или не чаще) определенного интервала
3) все прочие
Первые запускаешь с наивысшим приоритетом по таймеру, вторые между ними по интервалу, третьи - в свободное от первых и вторых время
А устраивать "карусель" всех задач с интервалом в 100мс - это бессмысленная возня
Спасибо. Надо будет почитать о приоритетах в Arduino.
P.S. Там всего 2 вида функций - 1 и 2, второй вид работает только в определённые (редкие, но важные) моменты.
В Ардуино приоритетов нет, сам придумывай.
Я правильно понимаю, что первые - по прерыванию таймера, вторые - просто в цикле?
Все упирается в тайминги, надо расписывать, вдруг есть задача на 50мс и другая, которую надо выполнять за 50мс дважды - тут уже все непросто, можно в таймере.
Всем спасибо, пошёл изучать таймеры и прерывания.
Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду.
И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.
Всем спасибо, пошёл изучать таймеры и прерывания.
Вы всё-таки, длительности своих функций изучите (измерьте). Без конкретных цифр совсем не факт, что Вам необходима какая-то оптимизация. И обдумайте необходимость той или иной точности в действиях. Например, на мой взгляд, абсолютно пофиг - будет информация на экране обновляться строго раз в секунду или +- десятая.
Вы всё-таки, длительности своих функций изучите (измерьте). Без конкретных цифр совсем не факт, что Вам необходима какая-то оптимизация.
Вот потому и написал
просто код без данных не будет значить ничего
Если я просто напишу
то вероятно, что это даже с учётом скорости 115200 не даст выполниться функции, которая должна выполняться 50 раз в секунду. Я верно мыслю? Если да, то уже стоит перейти на прерывания по таймеру.
Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду.
И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.
В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?
Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду.
И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.
В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?
Тут вообще непонятно, зачем идеальная точность по времени опроса датчиков и (тем более) вывода данных на экран?
Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду.
И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.
В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?
Тут вообще непонятно, зачем идеальная точность по времени опроса датчиков и (тем более) вывода данных на экран?
Ну вот такая система, где опрос и реакция важны: не успеешь отреагировать, получишь неточный результат.
Про экран не столь принципиально, но всё же, если через 5 минут у вас на секундометре не 300 сек, а 299, это напрягает.
Ну если с секундомером не проверять, то не думаю ) Само же время правильное, просто на секунду позже прорисуется сразу 301, например. Ну хотя да... такое может напрягать.
то вероятно, что это даже с учётом скорости 115200 не даст выполниться функции, которая должна выполняться 50 раз в секунду. Я верно мыслю?
Угу
Ну вот такая система, где опрос и реакция важны: не успеешь отреагировать, получишь неточный результат.
Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))
Про экран не столь принципиально, но всё же, если через 5 минут у вас на секундометре не 300 сек, а 299, это напрягает.
Т.е. вы считаете время по количеству обновлений экрана? Это пять!!!!!
Вам реально нужно пересмотреть архитектуру своего прилохения ))
Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))
Возможно оно само как то реагирует
Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))
Возможно оно само как то реагирует
Возможно. Но, сдается мне, ТС взвалил на себя неподъемную ношу - для решения таких ответственных задач у него явно не хватает квалификации
ЗЫ: он таки заявил, что процессов всего два - опрос датчиков и вывод информации на экран
Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))
Возможно оно само как то реагирует
Возможно. Но, сдается мне, ТС взвалил на себя неподъемную ношу - для решения таких ответственных задач у него явно не хватает квалификации
Не хватает - я же не профессионал. Но по мере выполнения работы набираюсь знаний.
А, понятно, тоже подумал про PID-регулятор.
В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?
А кто сказал что-то про прерывания. Твой код - таймер.
Ну если прям капец как критично этот PID 50 раз в секунду регулировать, то придется, наверное, научиться в прерывания.
В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?
А кто сказал что-то про прерывания. Твой код - таймер.
Мой код - не точный таймер. Ибо
подозреваю, не выведет 100 раз за секунду сообщение в порт.
Ну если прям капец как критично этот PID 50 раз в секунду регулировать, то придется, наверное, научиться в прерывания.
Там кроме PID ещё и управление SSR, которому точность в 0.02 сек. критична.
andreykrasnoda, хорошо, а Вы хоть проверили, сколько времени выполняется та функция, которую Вы собрались 50 раз в секунду вызывать? А то всё у Вас как-то "вероятно" да "подозреваю"... Оно успеет? А то ведь за её вызовами можно и совсем ничего в порт не вывести, никакие таймеры не спасут.
andreykrasnoda, хорошо, а Вы хоть проверили, сколько времени выполняется та функция, которую Вы собрались 50 раз в секунду вызывать? А то всё у Вас как-то "вероятно" да "подозреваю"... Оно успеет? А то ведь за её вызовами можно и совсем ничего в порт не вывести, никакие таймеры не спасут.
Не думаю, что она вообще заслуживает внимания. Там получение данных с "аналогового" пина, небольшое вычисление и "дёрганье ногами", уж 16 мгц за глаза хватит.
P.S. Не стал сильно мудрить, нашёл готовую библиотеку (MsTimer2) и на её основе стал вызывать нужную мне функцию 50 раз в секунду. Получился грубый аналог многозадачности.
Скетч скомпилировался, а вот тестировать в реальных условиях буду уже позже, там не всё так просто.
Да кто его знает: разобрал, загрузил новый скетч - работает отлично. Собственно, вопрос закрыт. Спасибо всем, я узнал новую для себя вещь и теперь самые важные для меня функции работают с наивысшим приоритетом, отображение на экране - это уже вторично, можно и потерпеть, если вдруг ресурсов не хватит.
Кстати, попутно вопрос. Может, есть где таблица для понимания времени работы функций:
- дёрганье ногой на цифровом пине
- получение данных с аналогового пина
- Получение данных с HX711
- отправка байта в serial
?
- отправка байта в serial
берешь скорость сериал в бодах и делишь примерно на 10 - это будет скорость в байтах в секунду. Отсюда нетрудно вычислить время отправки одного байта.
По всем остальным функциям проще померить с помощью микрос или миллис
- отправка байта в serial
берешь скорость сериал в бодах и делишь примерно на 10 - это будет скорость в байтах в секунду. Отсюда нетрудно вычислить время отправки одного байта.
По всем остальным функциям проще померить с помощью микрос или миллис
На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит. Где-то наткнулся на статью, в которой человек пишет, что на практике просто дёрганье ногой (digitalWrite в цикле loop) - процесс ну оооочень длительный.
Эх... придётся измерять.
На форуме есть тема, где всё уже измерено.
На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит.
у тебя с математикой совсем плохо? Если мы говорим про СКОРОСТЬ, то чтобы учесть "что там дополнительно происходит" - скорость надо именно делить, а не умножать.
Судя по всему, ты не понял, как надо считать. Еще раз внимательно прочитай, что я написал выше - а потом посчитай время печати одного байта на скорости Сериал 115200 и напиши в конференцию.
Даже на скорости 9600 бод за сек можно кбайт отправить по уарт в фоновом режиме. При буфере 64 байта например, грузим в него сначала до 64 байт, а через 60 мс (за это время будет отправлено ~ 60 байт) грузим в него еще 60 байт. Отправка будет происходить на аппаратном уровне, не загружая процессор. И так постоянно следить, чтоб сумма еще неотправленых байт в передающем буфере и вновь загружаемых не превышала 64 байта.
Не смог найти.
На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит.
у тебя с математикой совсем плохо? Если мы говорим про СКОРОСТЬ, то чтобы учесть "что там дополнительно происходит" - скорость надо именно делить, а не умножать.
Судя по всему, ты не понял, как надо считать. Еще раз внимательно прочитай, что я написал выше - а потом посчитай время печати одного байта на скорости Сериал 115200 и напиши в конференцию.
Нет, я всё отлично понял ещё в школе и даже выше писал свои выкладки - сколько времени потребуется для отправки 250 байт на 115200. Но это лишь ТЕОРИЯ.
Но это лишь ТЕОРИЯ.
А ты в теорию не веришь?
Ну тогда возьми ардуину и померяй, это займет минут десять на все твои вопросы. Куда быстрее. чем писать в форум
Я ахреневаю. Первая ссылка по поиску по форуму на слово время
http://arduino.ru/forum/obshchii/vremya-vypolneniya-otdelnykh-komand-ard...
Не думаю, что она вообще заслуживает внимания. Там получение данных с "аналогового" пина, небольшое вычисление и "дёрганье ногами", уж 16 мгц за глаза хватит.
Ну, вообще-то просто "получение данных с "аналогового" пина" само по себе занимает почти 2000 тактов процессора. А "небольшие вычисления" запросто могут потянуть по несколько сотен тактов на каждую элементарную арифметическую операцию.
Кстати, попутно вопрос. Может, есть где таблица для понимания времени работы функций:
- дёрганье ногой на цифровом пине
- получение данных с аналогового пина
- Получение данных с HX711
- отправка байта в serial
?
Выше ссылку уже привели, но что касается Serial, то в зависимости от обстоятельств это время может различаться на несколько порядков.
По поводу опроса датчиков - нужно смотреть их библиотеки, в разных может быть по разному. Но проще всего - измерить самому.
Ну, вообще-то просто "получение данных с "аналогового" пина" само по себе занимает почти 2000 тактов процессора. А "небольшие вычисления" запросто могут потянуть по несколько сотен тактов на каждую элементарную арифметическую операцию.
То есть, менее миллисекунды в сумме - и правда, не заслуживает оно внимания.