• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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
 
Сверху Снизу