• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь МНОГОПОТОЧНОСТЬ

Krivoryk400854

New member
У меня есть код. и в нем есть цыкл
Код:
byte raz = 200;
while (--raz != 0)
      {
        digitalWrite(16, LOW);
        delay(100);
        digitalWrite(16, HIGH);
        delay(100);
      }
но когда выполнятся цыкл, то веб-сервер перестает отвечать. Тоесть страницы не грузятся, пока цыкл не закончится. КАК ЦЫКЛ ЗАПУСТИТЬ В НОВОМ ПОТОКЕ ЧТОБЫ ОН НЕ МЕШАЛ РАБОТЕ ОСНОВНОГО?
 

nikolz

Well-known member
У меня есть код. и в нем есть цыкл
Код:
byte raz = 200;
while (--raz != 0)
      {
        digitalWrite(16, LOW);
        delay(100);
        digitalWrite(16, HIGH);
        delay(100);
      }
но когда выполнятся цыкл, то веб-сервер перестает отвечать. Тоесть страницы не грузятся, пока цыкл не закончится. КАК ЦЫКЛ ЗАПУСТИТЬ В НОВОМ ПОТОКЕ ЧТОБЫ ОН НЕ МЕШАЛ РАБОТЕ ОСНОВНОГО?
А у Вас многопоточная система?
 

nikolz

Well-known member
У меня есть код. и в нем есть цыкл
Код:
byte raz = 200;
while (--raz != 0)
      {
        digitalWrite(16, LOW);
        delay(100);
        digitalWrite(16, HIGH);
        delay(100);
      }
но когда выполнятся цыкл, то веб-сервер перестает отвечать. Тоесть страницы не грузятся, пока цыкл не закончится. КАК ЦЫКЛ ЗАПУСТИТЬ В НОВОМ ПОТОКЕ ЧТОБЫ ОН НЕ МЕШАЛ РАБОТЕ ОСНОВНОГО?
обработку пинов надо делать по прерыванию на худой конец по таймеру
 

MihaNN52

Member
Давай я напишу. Помню местные ребята мне так же разжовывали)) Приходится возвращать.
У контроллера есть внутренний таймер работы.
Он считает сколько прошло миллисекунд с момента старта.
Это очень удобная вещь чтобы что то делать с интервалами или в определенное время.
Получить время можно с помощью функции millis();
Например
Serial.print("Millis:");
Serial.println(millis());
delay(200);
Увидишь вывод времени в миллисекундах каждые 200мс
Чтоб что то делать с интервалом нужно.
Кудато записать время. Например long time_1 = 0;
Узнать текущее время, вычесть из него время когда мы последний раз сохраняли время( изначально это 0 long time_1 = 0;) и сравнить с интервалом.
И так.
if(millis() - time_1 > 5000){// Если текущее время - ранее сохраненное время > 5сек
time_1 = millis();// сохраняем новое время в переменную
// что то делаем
}
Первый раз сработает когда millis() будет больше 5000 т.к time_1 = 0;
Второе срабатывание когда будет больше 10000 и т.д

В итоге каждые 5000мс будет один раз выполнятся условие.

Далее можно использовать millis() разнообразно. Например произошло какое то событие.
Сохраняем в переменную время time_2= millis();
И нам надо через 2 минуты что то сделать. Например мы включили насос и надо его выключить.
if(millis() - time_2 > 120000){
//выключаем насос
}

Можно выводить время работы в виде часов

void TimePrint()
{
int time=millis()/1000;
if (time/60/60<10) { Serial.print ("0"); }
Serial.print (time/60/60);
Serial.print (":");
if (time/60%60<10) { Serial.print ("0"); }
Serial.print ((time/60)%60);
Serial.print (":");
if (time%60<10) { Serial.print ("0"); }
Serial.println (time%60);
}

Значения long могут переполнятся но вряд ли вас это побеспокоит в ближайшие пол года т.к ваше устройство без перезагрузки вряд ли проживет и пару дней)))
 

pvvx

Активный участник сообщества
Значения long могут переполнятся но вряд ли вас это побеспокоит в ближайшие пол года т.к ваше устройство без перезагрузки вряд ли проживет и пару дней)))
Чтобы не переполнилось никогда, используйте unsigned long.
Пример: millis() - old_time > 2
0x0000001 - 0xffffffff = 2, где millis() за время перешел через 0.
 

tretyakov_sa

Moderator
Команда форума
Так я так и не получил ответ на главный вопрос. Есть ли многопоточность? цыкл - это был как пример.
А нужна ли многопоточность? Например я в своей прошивке использую Toshik/TickerScheduler
Разные задачи выполняются через определенное заданное время. Очереди задач нет. Приоритетов нет. Для вашего примера я предложил простой способ. Все очень сильно будет зависит от конкретной задачи.
Сам не использовал, но есть RTOS. Нужна ли она вам, вам решать.
https://esp8266.ru/esp8266-freertos/
Немного о программировании ESP8266 на C под FreeRTOS
 
Последнее редактирование:

MihaNN52

Member
Так я так и не получил ответ на главный вопрос. Есть ли многопоточность? цыкл - это был как пример.
Да в нет ни какой многопоточности. В одно время делается одно действие. Немного развязывает прерывания и DMA если есть, тут его нет.
 

pvvx

Активный участник сообщества
Да в нет ни какой многопоточности. В одно время делается одно действие. Немного развязывает прерывания и DMA если есть, тут его нет.
Многопоточность — Википедия :
Многопоточность (как доктрину программирования) не следует путать ни с многозадачностью, ни с многопроцессорностью, несмотря на то, что операционные системы, реализующие многозадачность, как правило, реализуют и многопоточность.

Подобие DMA у процессора ESP8266 есть, как и у ESP-32. На ESP8266 очень ограниченное и без описания. Есть пару примеров только с I2S.
 

Grem_line

New member
Так я так и не получил ответ на главный вопрос. Есть ли многопоточность?
Судя по тому, что ESP8266 работает под FreeRTOS, то многопоточность должна там быть.
Поищи документацию на эту операционку.
Да в нет ни какой многопоточности. В одно время делается одно действие.
Сударь, многопоточность легко реализуется и на одном ядре. При этом, несмотря на то, что в одно время делается одно действие, одновременно могут обрабатываться сотни потоков (тредов).
В задачах реального времени потоки чаще всего находятся в ожидании событий - прерываний по завершению операций с аппаратурой, от таймера и т.п. В это время вполне себе могут выполняться другие потоки. Я уже не говорю о карусельном планировании, которое, впрочем, в задачах реального времени лучше не использовать.
 

nikolz

Well-known member
Судя по тому, что ESP8266 работает под FreeRTOS, то многопоточность должна там быть.
Поищи документацию на эту операционку.

Сударь, многопоточность легко реализуется и на одном ядре. При этом, несмотря на то, что в одно время делается одно действие, одновременно могут обрабатываться сотни потоков (тредов).
В задачах реального времени потоки чаще всего находятся в ожидании событий - прерываний по завершению операций с аппаратурой, от таймера и т.п. В это время вполне себе могут выполняться другие потоки. Я уже не говорю о карусельном планировании, которое, впрочем, в задачах реального времени лучше не использовать.
На одном процессоре многопоточность лишь тормозит вычисления.
Но так как механизм многопоточности реализуется в OC, то можно его реализовать и на одном процессоре, но потоки при этом будут исполнятся последовательно.
Для параллельного исполнения нужны дополнительные ядра либо процессоры.
Т е параллельное исполнение - это параллельная работа нескольких процессоров(ядер).
----------------
Чтобы исключить простаивание процессора используется механизм прерываний и колбеков.
При этом достигается большее быстродействие так как не тратится время для бессмысленного переключения процессора между потоками.
--------------------
Вот тут доходчиво для дуринщиков пояснили:
ESP8266-12F multi-threading / scheduler, with Arduino IDE - Everything ESP8266
 
Сверху Снизу