Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

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

Тема в разделе "Общие вопросы по esp8266", создана пользователем Krivoryk400854, 8 апр 2018.

  1. Krivoryk400854

    Krivoryk400854 Новичок

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

    nikolz Гуру

    Сообщения:
    4.715
    Симпатии:
    452
    А у Вас многопоточная система?
     
  3. NeoroN

    NeoroN Читатель

    Сообщения:
    150
    Симпатии:
    22
    Неверный код. Не надо так делать.
     
  4. nikolz

    nikolz Гуру

    Сообщения:
    4.715
    Симпатии:
    452
    обработку пинов надо делать по прерыванию на худой конец по таймеру
     
  5. MihaNN52

    MihaNN52 Новичок

    Сообщения:
    78
    Симпатии:
    1
    есть пример блинка без delay посмотри его внимательно
     
  6. Cuper

    Cuper Новичок

    Сообщения:
    61
    Симпатии:
    1
    Используйте millis(). У меня похожая проблема была.
     
  7. Krivoryk400854

    Krivoryk400854 Новичок

    Сообщения:
    7
    Симпатии:
    0
    Насколько я знаю у ESP8266mod есть многопоточность. но я не знаю как его использовать
     
  8. Krivoryk400854

    Krivoryk400854 Новичок

    Сообщения:
    7
    Симпатии:
    0
    Можно пример?
     
  9. Krivoryk400854

    Krivoryk400854 Новичок

    Сообщения:
    7
    Симпатии:
    0
    А пример кода можно?
     
  10. Krivoryk400854

    Krivoryk400854 Новичок

    Сообщения:
    7
    Симпатии:
    0
    А как надо?
     
  11. MihaNN52

    MihaNN52 Новичок

    Сообщения:
    78
    Симпатии:
    1
    смотри примеры блинк без делей. Сразу не вьедешь, не переживай. Но есть много статей на эту тему.
    upload_2018-4-10_22-30-37.png
     
    Последнее редактирование: 10 апр 2018
  12. MihaNN52

    MihaNN52 Новичок

    Сообщения:
    78
    Симпатии:
    1
    Давай я напишу. Помню местные ребята мне так же разжовывали)) Приходится возвращать.
    У контроллера есть внутренний таймер работы.
    Он считает сколько прошло миллисекунд с момента старта.
    Это очень удобная вещь чтобы что то делать с интервалами или в определенное время.
    Получить время можно с помощью функции 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 могут переполнятся но вряд ли вас это побеспокоит в ближайшие пол года т.к ваше устройство без перезагрузки вряд ли проживет и пару дней)))
     
  13. tretyakov_sa

    tretyakov_sa Moderator Команда форума

    Сообщения:
    982
    Симпатии:
    151
    А еще, посмотрите примеры к библиотеке Ticker.
     
  14. pvvx

    pvvx Активный участник сообщества

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

    Krivoryk400854 Новичок

    Сообщения:
    7
    Симпатии:
    0
    Так я так и не получил ответ на главный вопрос. Есть ли многопоточность? цыкл - это был как пример.
     
  16. tretyakov_sa

    tretyakov_sa Moderator Команда форума

    Сообщения:
    982
    Симпатии:
    151
    А нужна ли многопоточность? Например я в своей прошивке использую Toshik/TickerScheduler
    Разные задачи выполняются через определенное заданное время. Очереди задач нет. Приоритетов нет. Для вашего примера я предложил простой способ. Все очень сильно будет зависит от конкретной задачи.
    Сам не использовал, но есть RTOS. Нужна ли она вам, вам решать.
    https://esp8266.ru/esp8266-freertos/
    Немного о программировании ESP8266 на C под FreeRTOS
     
    Последнее редактирование: 12 апр 2018
  17. MihaNN52

    MihaNN52 Новичок

    Сообщения:
    78
    Симпатии:
    1
    Да в нет ни какой многопоточности. В одно время делается одно действие. Немного развязывает прерывания и DMA если есть, тут его нет.
     
  18. pvvx

    pvvx Активный участник сообщества

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

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

    Grem_line Читатель

    Сообщения:
    57
    Симпатии:
    10
    Судя по тому, что ESP8266 работает под FreeRTOS, то многопоточность должна там быть.
    Поищи документацию на эту операционку.
    Сударь, многопоточность легко реализуется и на одном ядре. При этом, несмотря на то, что в одно время делается одно действие, одновременно могут обрабатываться сотни потоков (тредов).
    В задачах реального времени потоки чаще всего находятся в ожидании событий - прерываний по завершению операций с аппаратурой, от таймера и т.п. В это время вполне себе могут выполняться другие потоки. Я уже не говорю о карусельном планировании, которое, впрочем, в задачах реального времени лучше не использовать.
     
    =AK= и tretyakov_sa нравится это.
  20. nikolz

    nikolz Гуру

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

Поделиться этой страницей