Параллельные задачи исключают любые циклы?
- Войдите на сайт для отправки комментариев
Пнд, 27/01/2020 - 07:25
Есть два участка программы которые должны работать параллельно. По отдельности они выполняют свои функции на отлично. Решил использовать библиотеку <Thread.h>, но она исключает delay. Тогда решил использовать millis для задержек. Сделал, но в части кода есть цикл do while, во время выполнения которого все равно ничего другого не работает. Неужели нельзя написать более-менее сложную программу с несколькими потоками вычислений?
Программа меряет Вольтаж и усредняет за промежуток времени, после записывает на флешку (пока не выводит, т.к. настраиваю через монитор порта).
Moderator : пожалуйста, вставьте код правильно (возможно, новым сообщением в тему),
если ты задачу опишешь внятно, да код вставишь правильно, то мошт чо и придумаеца.
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Неужели нельзя написать более-менее сложную программу с несколькими потоками вычислений?
Неужели нельзя написать более-менее сложную программу с несколькими потоками вычислений?
Можно... наверное.
Дурдуина с несколькими потоками вычислений??? Поржал!
Сделал, но в части кода есть цикл do while, во время выполнения которого все равно ничего другого не работает. Неужели нельзя написать более-менее сложную программу с несколькими потоками вычислений?
можно, но от цикла while , скорее всего, придется отказаться. Все это отлично пишется на одних миллис, без всяких потоков
Спасибо, извините, первый день тут
и где вы "переписали на миллис"? Сплошные делеи в коде, такое никакими потоками не вылечить
Сплошные делеи в коде, такое никакими потоками не вылечить
Я пытался сделать потоки с делеями на специально для этого предназначенном языке - получил эпичный облом :-(
Потоки с делеями есть на rtos. Которая прожорлива по памяти, но для мелких задач помещается в уно.
да, это старый участок кода, сейчас поделюсь миллис, но он не доделан. Вторая часть кода отключена, т.к. проблема в первом участке, т.к. пока крутится do while ничего другого не происходит. Суть - есть два потока - один записывает данные вольтметра (фоторезистор стоит напротив светодиода, а между ними протекает жидкость, которая со временем пропускает все меньше света (загрязняется), и когда напряжение достигает нижнего порога Uslovie_otkr происходит открытие клапана, который эту жидкость разбавляет уже до верхнего предела Uslovie_zakr) на SD с усреднением за установленный параметрами период времени Vremya_izmereniya_min с установленным шагом Kolichestvo_izmereniy. Второй поток поверяет вольтаж уже чаще и если он меньше нижнего порога Uslovie_otkr то начинает усреднять вольтаж - 100 измерений с задержкой 100 мс. Если условие уже усредненного значения вольтажа все еще меньше Uslovie_otkr, то программа запускает открытие клапана на 5 секунд, ждет 10 секунд (пока идет перемешивание), затем опять измеряет вольтаж, усредняет его и опять сравнивает условие уже этого усреднения с Uslovie_zakr, если оно выполняется, то выходит из цикла. По сути пол получается пилообразный график.
Кроме лупа и прочих циклов, в ардуине, и не только, существуют функции, заглядывать в них разрешается из любого места.
Artas - конкретно в ваши обьяснения я не вчитывался, но по коду могу рассказать. что вам нужно изменить.
Если вы хотите работать в несколько потоков на однопроцессорной системе, все длинные циклы. где программа проводит десятки секунд - все эти while и for - должны быть безжалостно выкинуты. Программу надо кардинально переписать.
Общий принцип - возьмем для примера ваш цикл for. который делает 100 измерений с интервалом 100мс. У вас в программе он написан в блокирующем стиле - то есть программа заходит в цикл и сидит в нем, пока не сделает все измерения - то есть 100 * 0.1 сек = 10 сек. По меркам мира электроники 10 сек - это вечность.
Вместо цикла делаем так: - пишем коротенькую процедуру, которая делает один замер (а не 100!) и без всяких задержек заканчивает работу, позволяя программе перейти к работе с другим потоком. Делаем что-то во втором потоке, а через 100мс (отмеряем с помощью миллис )- снова заходим в процедуру и снова делаем один замер. И так, пока не сделаем все 100 измерений.
естесственно, второй поток, все ваши бесконечные while - тоже должен быть переписан так, чтобы система делала одно короткое действие и выходила из процедуры в основной цикл.
таким образом можно делать параллельно и два дела. и три, больше... и без всяких тяжелых библиотек типа Threads или RTOS- которые, в общем-то - работают ровно на том же принципе переключения
Вместо цикла делаем так: - пишем коротенькую процедуру, которая делает один замер (а не 100!) и без всяких задержек заканчивает работу, позволяя программе перейти к работе с другим потоком. Делаем что-то во втором потоке, а через 100мс (отмеряем с помощью миллис )- снова заходим в процедуру и снова делаем один замер. И так, пока не сделаем все 100 измерений.
Естественно, второй поток, все ваши бесконечные while - тоже должен быть переписан так, чтобы система делала одно короткое действие и выходила из процедуры в основной цикл.
Действительно помогло, Спасибо. Мне, как человеку, который занимается этим ок. месяца было очень трудно, странно, что нет никаких реально работающих библиотек. В общем с кучей костылей все работает, спасибо большое)
Действительно помогло, Спасибо. Мне, как человеку, который занимается этим ок. месяца было очень трудно, странно, что нет никаких реально работающих библиотек. В общем с кучей костылей все работает, спасибо большое)
Конечно, когда уже есть готовый код и надо весь перекорежить - это непрсото. А вот если сразу писать в этом стиле - будет легче, и костылей не понадобится.