Распределение нагрузки на Arduino

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Здравствуйте. Выкладывать 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, цикл пройдёт ровно за секунду.
Morroc
Offline
Зарегистрирован: 24.10.2016

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

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

andreykrasnodar пишет:

чтобы "размазать" (оптимизировать) нагрузку, при timer == 10 выполняю одну функцию, timer == 20 - вторую и так далее, пока таймер не достигнет 99.

микроконтроллер - однозадачная система. Если он занят, его загрузка 100%. если свободен - 0% Поэтому нет абсолютно никакой разницы, выполняете ли вы задачи кусочками по 100 мс с переключениями или последовательно одну за другой. Точнее есть - первый способ медленнее, так как добавляются еще накладные расходы на переключение между потоками.

Так что главный вопрос, который возникает при чтении вашего сообщения - зачем все это?

Morroc
Offline
Зарегистрирован: 24.10.2016

Я что то такое делал не для мк, но чтобы пиковой загрузки не было когда звезды неудачно сойдутся, правда там БД и этот пик блокировки таблиц вызывает. Для ардуины может быть чтобы экранчик обновлять регулярнее ? )

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Смотрите, у меня 2 вида функций.

Вычисления и регулировка выполняются 50 раз в секунду, другие функции - раз в секунду. Например, мне нужно, чтобы каждую секунду обновлялась информация на экране о температурах, весе, давлении, времени (что логично), обновлялся график на экране, то есть, я привязан к этим двум временным отрезкам.

Если процессор загружать, как тут выразились, на 100% всеми задачами сразу (поочерёдно), то выполнение одних, "тяжёлых "задач может отсрочить выполнение других.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Концепцию меняй. 

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

andreykrasnodar пишет:

Если процессор загружать, как тут выразились, на 100% всеми задачами сразу (поочерёдно), то выполнение одних, "тяжёлых "задач может отсрочить выполнение других.

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

1) те, которые должны выполнятся строго в определенные моменты времени

2) те, которым время не важно, лишь бы они выполнялись не реже(или не чаще) определенного интервала

3) все прочие

Первые запускаешь с наивысшим приоритетом по таймеру, вторые между ними по интервалу, третьи - в свободное от первых и вторых время

А устраивать "карусель" всех задач с интервалом в 100мс - это бессмысленная возня

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Спасибо. Надо будет почитать о приоритетах в Arduino.

P.S. Там всего 2 вида функций - 1 и 2, второй вид работает только в определённые (редкие, но важные) моменты.

Morroc
Offline
Зарегистрирован: 24.10.2016

В Ардуино приоритетов нет, сам придумывай. 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Я правильно понимаю, что первые - по прерыванию таймера, вторые - просто в цикле?

Morroc
Offline
Зарегистрирован: 24.10.2016

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

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Всем спасибо, пошёл изучать таймеры и прерывания.

rkit
Offline
Зарегистрирован: 23.11.2016

andreykrasnodar пишет:

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

И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.

kalapanga
Offline
Зарегистрирован: 23.10.2016

andreykrasnodar пишет:

Всем спасибо, пошёл изучать таймеры и прерывания.

Вы всё-таки, длительности своих функций изучите (измерьте). Без конкретных цифр совсем не факт, что Вам необходима какая-то оптимизация. И обдумайте необходимость той или иной точности в действиях. Например, на мой взгляд, абсолютно пофиг - будет информация на экране обновляться строго раз в секунду или +- десятая.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

kalapanga пишет:

Вы всё-таки, длительности своих функций изучите (измерьте). Без конкретных цифр совсем не факт, что Вам необходима какая-то оптимизация.

Вот потому и написал

andreykrasnodar пишет:

просто код без данных не будет значить ничего

Если я просто напишу

//некоторое вычисление
Serial.print("250 байт текста");

то вероятно, что это даже с учётом скорости 115200 не даст выполниться функции, которая должна выполняться 50 раз в секунду. Я верно мыслю? Если да, то  уже стоит перейти на прерывания по таймеру.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

rkit пишет:

andreykrasnodar пишет:

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

И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.

В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

andreykrasnodar пишет:

rkit пишет:

andreykrasnodar пишет:

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

И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.

В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?

Тут вообще непонятно, зачем идеальная точность по времени опроса датчиков и (тем более) вывода данных на экран?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

v258 пишет:

andreykrasnodar пишет:

rkit пишет:

andreykrasnodar пишет:

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

И в чем вопрос? Делай два таймера - один на 20 мс, другой на секунду.

В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?

Тут вообще непонятно, зачем идеальная точность по времени опроса датчиков и (тем более) вывода данных на экран?

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

Про экран не столь принципиально, но всё же, если через 5 минут у вас на секундометре не 300 сек, а 299, это напрягает.

Morroc
Offline
Зарегистрирован: 24.10.2016

Ну если с секундомером не проверять, то не думаю ) Само же время правильное, просто на секунду позже прорисуется сразу 301, например. Ну хотя да... такое может напрягать.

andreykrasnodar пишет:

то вероятно, что это даже с учётом скорости 115200 не даст выполниться функции, которая должна выполняться 50 раз в секунду. Я верно мыслю? 

Угу

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

andreykrasnodar пишет:

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

Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))

andreykrasnodar пишет:

Про экран не столь принципиально, но всё же, если через 5 минут у вас на секундометре не 300 сек, а 299, это напрягает.

Т.е. вы считаете время по количеству обновлений экрана? Это пять!!!!!

Вам реально нужно пересмотреть архитектуру своего прилохения ))

Morroc
Offline
Зарегистрирован: 24.10.2016

v258 пишет:

Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))

Возможно оно само как то реагирует

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Morroc пишет:

v258 пишет:

Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))

Возможно оно само как то реагирует

Возможно. Но, сдается мне, ТС взвалил на себя неподъемную ношу - для решения таких ответственных задач у него явно не хватает квалификации

ЗЫ: он таки заявил, что процессов всего два - опрос датчиков и вывод информации на экран

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Morroc пишет:

v258 пишет:

Странно, датчики опрашиваются с частотой 50 герц, а данные на экран выводятся раз в секунду. Тут и захочешь, отреагировать не успеешь ))

Возможно оно само как то реагирует

Оператор не успеет нажимать кнопки с точностью в 20 мсек и принимать решения за тот же PID-регулятор. Странно, что это другим непонятно. А вот информацию обновлять можно и раз в секунду. Хотя, можно и 5 раз, но точно не 50.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

v258 пишет:

Возможно. Но, сдается мне, ТС взвалил на себя неподъемную ношу - для решения таких ответственных задач у него явно не хватает квалификации

Не хватает - я же не профессионал. Но по мере выполнения работы набираюсь знаний.

Morroc
Offline
Зарегистрирован: 24.10.2016

А, понятно, тоже подумал про PID-регулятор.

rkit
Offline
Зарегистрирован: 23.11.2016

andreykrasnodar пишет:

В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?

А кто сказал что-то про прерывания. Твой код - таймер.

Morroc
Offline
Зарегистрирован: 24.10.2016

Ну если прям капец как критично этот PID 50 раз в секунду регулировать, то придется, наверное, научиться в прерывания. 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

rkit пишет:

andreykrasnodar пишет:

В том, что до сегодняшнего дня я ничего не знал о прерываниях по таймеру. И тут параллельный вопрос - зачем второй таймер, если можно использовать millis()?

А кто сказал что-то про прерывания. Твой код - таймер.

Мой код - не точный таймер. Ибо 

if (millis() - myTimer >= 10) {
  myTimer = millis();
  Serial.print("privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet privet ");
}

подозреваю, не выведет 100 раз за секунду сообщение в порт.

 

 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Morroc пишет:

Ну если прям капец как критично этот PID 50 раз в секунду регулировать, то придется, наверное, научиться в прерывания. 

Там кроме PID ещё и управление SSR, которому точность в 0.02 сек. критична.

kalapanga
Offline
Зарегистрирован: 23.10.2016

andreykrasnoda, хорошо, а Вы хоть проверили, сколько времени выполняется та функция, которую Вы собрались 50 раз в секунду вызывать? А то всё у Вас как-то "вероятно" да "подозреваю"... Оно успеет? А то ведь за её вызовами можно и совсем ничего в порт не вывести, никакие таймеры не спасут.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

kalapanga пишет:

andreykrasnoda, хорошо, а Вы хоть проверили, сколько времени выполняется та функция, которую Вы собрались 50 раз в секунду вызывать? А то всё у Вас как-то "вероятно" да "подозреваю"... Оно успеет? А то ведь за её вызовами можно и совсем ничего в порт не вывести, никакие таймеры не спасут.

Не думаю, что она вообще заслуживает внимания. Там получение данных с "аналогового" пина, небольшое вычисление и "дёрганье ногами", уж 16 мгц за глаза хватит.

P.S. Не стал сильно мудрить, нашёл готовую библиотеку (MsTimer2) и на её основе стал вызывать нужную мне функцию 50 раз в секунду. Получился грубый аналог многозадачности.

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

 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Да кто его знает: разобрал, загрузил новый скетч - работает отлично. Собственно, вопрос закрыт. Спасибо всем, я узнал новую для себя вещь и теперь самые важные для меня функции работают с наивысшим приоритетом, отображение на экране - это уже вторично, можно и потерпеть, если вдруг ресурсов не хватит.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Кстати, попутно вопрос. Может, есть где таблица для понимания времени работы функций:

- дёрганье ногой на цифровом пине

- получение данных с аналогового пина

- Получение данных с HX711

- отправка байта в serial

?

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

andreykrasnodar пишет:

- отправка байта в serial

берешь скорость сериал в бодах и делишь примерно на 10 - это будет скорость в байтах в секунду. Отсюда нетрудно вычислить время отправки одного байта.

По всем остальным функциям проще померить с помощью микрос или миллис

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

- отправка байта в serial

берешь скорость сериал в бодах и делишь примерно на 10 - это будет скорость в байтах в секунду. Отсюда нетрудно вычислить время отправки одного байта.

По всем остальным функциям проще померить с помощью микрос или миллис

На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит. Где-то наткнулся на статью, в которой человек пишет, что на практике просто дёрганье ногой (digitalWrite в цикле loop) - процесс ну оооочень длительный.

Эх... придётся измерять.

nik182
Offline
Зарегистрирован: 04.05.2015

На форуме есть тема, где всё уже измерено.

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

andreykrasnodar пишет:

На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит.

у тебя с математикой совсем плохо? Если мы говорим про СКОРОСТЬ, то чтобы учесть "что там дополнительно происходит" - скорость надо именно делить, а не умножать.

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

Pyotr
Offline
Зарегистрирован: 12.03.2014

Даже на скорости 9600 бод за сек можно кбайт отправить по уарт в фоновом режиме. При буфере 64 байта например, грузим в него сначала до 64 байт, а через 60 мс (за это время будет отправлено ~ 60 байт) грузим в него еще 60 байт. Отправка будет происходить на аппаратном уровне, не загружая процессор. И так постоянно следить, чтоб сумма еще неотправленых  байт в передающем буфере и вновь загружаемых не превышала 64 байта.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

nik182 пишет:
На форуме есть тема, где всё уже измерено.

Не смог найти.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

На скорости 115200 это прям молнеиносно. Но, думаю, на практике там не только делить не придётся, а ещё и умножить надо, т.к. неизвестно, что там дополнительно на низком уровне происходит.

у тебя с математикой совсем плохо? Если мы говорим про СКОРОСТЬ, то чтобы учесть "что там дополнительно происходит" - скорость надо именно делить, а не умножать.

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

Нет, я всё отлично понял ещё в школе и даже выше писал свои выкладки - сколько времени потребуется для отправки 250 байт на 115200. Но это лишь ТЕОРИЯ.

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

andreykrasnodar пишет:

Но это лишь ТЕОРИЯ.

А ты в теорию не веришь?

Ну тогда возьми ардуину и померяй, это займет минут десять на все твои вопросы. Куда быстрее. чем писать в форум

nik182
Offline
Зарегистрирован: 04.05.2015

Я ахреневаю. Первая ссылка по поиску по форуму на слово время
http://arduino.ru/forum/obshchii/vremya-vypolneniya-otdelnykh-komand-ard...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

andreykrasnodar пишет:

Не думаю, что она вообще заслуживает внимания. Там получение данных с "аналогового" пина, небольшое вычисление и "дёрганье ногами", уж 16 мгц за глаза хватит.

Ну, вообще-то просто "получение данных с "аналогового" пина" само по себе занимает почти 2000 тактов процессора. А "небольшие вычисления" запросто могут потянуть по несколько сотен тактов на каждую элементарную арифметическую операцию.

andreykrasnodar пишет:

Кстати, попутно вопрос. Может, есть где таблица для понимания времени работы функций:

- дёрганье ногой на цифровом пине

- получение данных с аналогового пина

- Получение данных с HX711

- отправка байта в serial

?

Выше ссылку уже привели, но что касается Serial, то в зависимости от обстоятельств это время может различаться на несколько порядков.

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

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

andriano пишет:

Ну, вообще-то просто "получение данных с "аналогового" пина" само по себе занимает почти 2000 тактов процессора. А "небольшие вычисления" запросто могут потянуть по несколько сотен тактов на каждую элементарную арифметическую операцию.

 

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