Комментарии 65
я ещё только собираюсь брать быка за рога, но тоже смутила перспектива программировать ESP32 из Arduino IDE, как самая рекомендуемая. искал варианты. ещё советуют VS Code, но к поделкам на Electron'е у меня тоже мало доверия, несмотря на то, что VS Code очень хвалят.
хотелось что-то вроде привычных Atmel Studio, Visual Studio.
спасибо вам за содержательную и полезную во многих смыслах статью.
Для vs code есть PlatformIO, очень удобно.
Посмотрите platformio. Она позволяет генерировать все необходимые настройки для разных ide и редакторов (например clion, vscode начинают просто работать без каких либо расширений), и полезной фичей будет взрослая работа с пакетами ( как pip или npm)
void calculate_water_temp(void *pvParameters)
{
while (true)
{
if (heating_mode != 3)
{
max_water_temp = map(temp_outside, -30, -10, 85, 50);
}
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
А как к ней обратится? Есть какой то отдельный метод? У нас ведь нет хэндла для idle задачи.
Так таймер должен контролировать не работу Idle, а зависание задач. Каждая критичная (имеющая дело с внешней средой) задача должна сообщить ему, что не зависла в ожидании данных или готовности аппаратуры.
Для очень критичных приложений можно организовать контроль времени цикла каждой задачи, но это потребует организации двойного ватчдога — программного, с независимым счетчиком времени для каждой задачи, и аппаратного, контролирующего работу программного.
В любом случае очень здорово.
Пожалуй, только вопросы:
1) Увидев «FreeRTOS» и «Blynk» в одном флаконе, я сначла подумал, что Blynk будет использоваться не как «черный ящик», а через API. Не было нужды, все и так прекрасно работает?
Просто сталкиваюсь с проблемами при пропадании Интернета — реконнекты Блинка блокируют все чуть ли не на пол минуты. Не будет ли глюков, если шедулер будет многократно аварийно завершать такие попытки (при гудках и т.п.)?
Я для отладки просто на роутере блокировал данному хосту Интернет, и через несколько раз наичналась нестабильность.
2) Насколько отладчик экономит время при написании таких не слишком больших задач по сравнению с обычной отладочной печатью в serial?
На бесплатном PlatformIO под VScode, насколько я понял, аппаратная отладка становится доступной только при оформлении платной подписки.
По вопросам:
1) Проблем нет, всё просто работает. К API Blynk я обращался из кода, для пробы, там ничего сложного, но зачем? :) Что могу сказать по отсутствию инета и реконнектам Blynk, бывает что я забываю заплатить за инет и плата работает без инета, вроде всё в порядке, но я не проверял в это время сработку сигнализации, что бы таски с гудками и морганием работали. На днях попробую поставить дом на охрану и выключить роутер.
2) Если честно, то не очень то и экономит, может процентов на 10 побыстрее. :) Но сам процесс с использованием отладчика мне нравится больше. Тут дело в том, что в отладке ESP32 средствами VisualGDB не поддерживаются так называемые «живые переменные», это когда можно смотреть значения переменных не останавливая контроллер. Т.е. нужно поставить точку останова, что бы посмотреть, если бы эта фича поддерживалась, было бы прям удобно и быстрее.
unsigned long // счетчики таймеров для:
WifiLoopTime = millis(), // проверки wifi
BlynkLoopTime = 0; // проверки коннекта к серверу blynk
setup()
WiFi.mode(WIFI_STA);
WiFi.begin();
WiFi.setAutoReconnect(true);
Blynk.config("***************", IPAddress(***********), 8442);
Blynk.connect(1666); // 5sec
loop()
if (WiFi.status() == WL_CONNECTED)
{
if (Blynk.connected())
Blynk.run();
else
if (millis()> BlynkLoopTime+20000)
{
BlynkLoopTime=millis();
Blynk.connect(1666);
}
httpServer.handleClient();
}
else
{
if (millis()> WifiLoopTime+20000)
{
Serial.println("WI-FI Not connected");
WiFi.mode(WIFI_OFF);
Serial.println("WI-FI disconnecting");
WiFi.begin();
Serial.println("WI-FI connecting.");
WifiLoopTime=millis();
}
else
if (millis()> Seconds+1000)
{
Seconds=millis();
Serial.print(".");
}
}
Также не нашел, как в smart_home_2019.ino подцепляются таски (tasks_functions.ino).
Или на гитхабе только кусочки проекта? Можете пояснить?
Также не нашел, как в smart_home_2019.ino подцепляются таски (tasks_functions.ino).В конце функции setup() ряд вызовов функций xTaskCreate()
Вряд ли это зарезериврованное имя файла.
Ну да ладно, у вас среда разработки другая. У меня ж вообще не .ino, а main.c главный файл…
Все равно много интересного увидел.
Ну да ладно, у вас среда разработки другая.Это не у меня, а у автора. Я ардуиновскими и околоардуиновскими софтверными инструментами не пользуюсь. Полагаю, что часть «магии» просто скрыта от пользователя, ведь подключить заголовочники можно и через опции командной строки компилятора (для gcc и g++ это -include).
Но, ссылку на метод для рестарта, который был изначально в из tasks_functions.ino, в smart_home_2019.ino не было видно, пришлось перенести этот метод в smart_home_2019.ino.
А вот ESP8266 такого нет. Там xCreateTask И прочие радости неизвестны, что меня и смутило.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"
TaskHandle_t loopTaskHandle = NULL;
#if CONFIG_AUTOSTART_ARDUINO
bool loopTaskWDTEnabled;
void loopTask(void *pvParameters)
{
setup();
for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop();
}
}
extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}
#endif
Здесь же видно, что для задачи по умолчанию выделяется всего 8192 (байт? слов? — в разных источниках по разному) стека. И это далеко не весь доступный контроллеру стек — у меня на одном контроллере дополнительно запущено еще с десяток задач и все работает.
В общем, при программировании ESP32 под ArduinoIDE без FreeRTOS вообще никак.
Я как раз очень сильно заморачивался, как сделать, чтобы и Blynk использовать, и чтобы определенные действия даже без Блинка (и вообще без Интернета) работали (по расписанию).
Похоже, что использование планировщика FreeRTOS как раз то, что мне нужно.
Но зачем такая точность, почему все время зимой не держать 85 градусов (а летом 70) — тоже не очень понимаю.
Еще можно аналогию провести с «почему инверторный кндиционер лучше обычного».
Одно дело большой гистерезис (разница температур между включением и выключением), а другое — плавное регулирование мощности.
Возможно здесь изменение температуры — такой аналог управления мощностью?
Но котел все равно ведь вкл/выкл сам делает…
Ну т.е. разве что избежать слишком частых включений/выключений, что имеет некоторый смысл.
А человеку, может, было интересно сделать из говна и палок термостат, да еще и иметь возможность получить некую инфографику. При этом, он не знает, что ему далее может потребоваться, что будет лишним, а что он захочет добавить.
Почему автор измеряет температуру на улице — а почему нет? Если у него получается регулировать так температуру, то и хорошо. Хотя, как по мне, задача подогнать параметры регулятора так гораздо сложнее.
Да и ваша «инфографика» по счетам за отопления — гораздо менее показательна. У нас тут зима на зиму не приходится. Прошлая была очень теплой, раза три снег всего выпадал. А вот три года назад, как выпал, так и не стаял. Как бы это на счетах отразилось?
Вообще, статья то про RTOS на esp32. Крутилка для котла тут как пример.
При подключении отладчика Windows устанавливает на него неподходящие драйвера, которые необходимо поменять с помощью программы Zadig, там всё просто, не буду описывать.
Странно у меня все из коробки заработало с этой платой. Вам пришлось переустанавливать драйвера?
Спасибо за статью. Очень вовремя!
Не более как неделю запустил в ещё пока строящемся доме отопление от котла. Котел умеет как eBUS, так и простой вход З/Р.
Установщики предлагали систему EktoControl (11к), но я в ней не увидел необходимости.
Имеется в наличии пара wemos d1 mini pro (v1.1), один ds18b20, решил как раз на этих выходных попробовать сделать управление для котла.
На си писал давно, но тулинг меня начал убивать :) может я просто зря решил не хватать Ардуино, а попытаться использовать NonOS / RTOS SDK.
Попробовал по их инструкциям, надо сделать в Windows кучу софта, ок. Не завелось. Попробовал CLion + esp8266 plugin. Ну вроде что-то работало, но подсказки кода нет.
Сейчас рабочий вариант нашел только VSCode + PlatformIO на основе NonOS. Но расстраивает свежее сообщение в гитхабе, что NonOS всё.
VSCode + PlatformIO на основе NonOS
А почему не VSCode + PlatformIO на основе Ардуино?
[env:ttgo-t1]Удобного шедулера в NonOS все равно нет. В чем ее прелесть? А так — куча ардуионовских библиотек подходит…
platform = espressif32
board = ttgo-t1
framework = arduino
Сейчас вижу, что, скорее всего, был неправ.
А с ограничением на таски пока не столкнулся. В целом хочу сделать достаточно простую вещь — временами опрашивать 18b20, по формуле считать когда вкл/выкл котёл, дёргать реле, а заодно отправлять всё измеренное и произошедшее по mqtt.
Так как в доме не живу, а зимой даже планирую некоторое время его не посещать, хотелось бы знать, что там всё ОКъ — скорее всего куплю самый-самый дешёвый 3g-модем (покрытие норм) с раздачей Wi-Fi.
Время создания: Sun, 08 Dec 2019 05:17:43 -0800
Тема: [platformio/platform-espressif8266] Support for ESP-IDF style ESP8266_RTOS_SDK
Several days ago Espressif has deprecated NonOS SDK
Support Policy for ESP8266 NonOS
Starting from December 2019,
We will not add any new features to the ESP8266 NonOS SDK.
We will only fix critical bugs in the ESP8266 NonOS SDK.
Самодельный Nest получился.
А зачем днём поддерживать +20 если дома никого нет?
ИМХО +16 достаточно, и повышать к желаемой температуре ко времени прихода домой.
Тоже присматриваюсь freertos на esp32. Сейчас работает похожий проект (для гаража сделал), связка: дома — esp32+LoRa и srm32+lora Переодически вылазят какие-то фантомы в данных (раз в сутки или в 2-e), все сделано через loop. Спасибо за реальный пример rtos — сяду перелопачивать!
В домашних условиях уже сутки без косяков. Сейчас код вылизываю — есть еще куда стремиться. И буду портировать на atmega16 (наковырял кучу, валяются без дела)
Смотрите в сторону crc-16 modbus, заточено по мк. Зашил все в свой протокол, появилась возможность вычислять "уровень сигнала" и ошибок в данных ноль (за неделю). Модули на родных пружинках через 3 ж/б стены (80 байт данных), в среднем 10-15 раз в минуту в обе стороны на 300 метров, без проблем!
Freertos у меня не было, потому как в загашнике валялись только платы arduino uno.
Реализовал на этом проект поливалки с парой датчиков влажности, дисплеем, кнопками для задания уровней срабатывания датчиков. Потом добавил часы реального времени и управление досветкой растений в зависимости от длинны суток, включалась она утром и вечером. Хотел даже написать статью, но писать статьи для меня сложнее чем писать код. Если вдруг кому то интересно, то проект лежит здесь.
И да, писать в arduino ide — сущий ад, проще один раз прикрутить qt creator.
Итак, при использовании FreeRTOS функция setup играет роль функции main, точки входа в приложение, в ней создаются FreeRTOS tasks (далее таски)...
Я правильно понимаю, что вы пользуетесь тем, что arduino-esp32 фреймворк запускает одновременно функции setup() и loop() как единственную задачу во FreeRTOS, судя по коду main.cpp фреймворка?
void loopTask(void *pvParameters)
{
setup();
for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop();
if (serialEventRun) serialEventRun();
}
}
extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}
Причем эта единственная задача имеет по умолчанию стек 8192.
Правильно ли я далее понимаю, что новые таски, которые вы создаете в setup(), расходуют ресурсы головного таска? Или во FreeRTOS не может быть подтасков, и задачи созданные в любом месте и из любой задачи уравниваются друг с другом и расходуют только единые ресурсы процессора?
Я прошу заранее простить, если вопрос непрофессионален. Только начинаю разбираться с ESP32, и вообще пытаюсь настроить окружение, чтобы использовать Arduino.h как компоненту для ESP-IDF, но тут еще те проблемы…
Или во FreeRTOS не может быть подтасков, и задачи созданные в любом месте и из любой задачи уравниваются друг с другом и расходуют только единые ресурсы процессора— это происходит именно так. Таск можно запустить из другого таска, он будет «равноценный» всем остальным, созданным в setup. Ресурсы у него будут свои, стек и процессорное время.
Интересно вы залезли в main, я там даже не был. Не ожидал что там так просто всё реализовано.
Отвечу на вопрос Глюки ESP32:
Проблема в том что при включении проседает питание (как пример висит конденсатор)
Решаеться очень просто: Надо прицепить конденсатор ~10uf между EN и GND.
Будет загружаться стабильно
Подружить Arduino и Esp-IDF, смотри пример github.com/Yurik72/esphapcontroller
уже подружено :)
Ну или для любителей Arduino IDE visual studio IDE
Пример библиотеки для Arduino но все задачи написаны через Free RTOS
github.com/Yurik72/ESPHap
Подзадачи и процессорное время:
Тут могу добавить что у ESP32 два ядра процессора (0 и 1)
Как правило на 1 работает Wifi и 0 по умолчанию работает для того же Arduino
(loop)
Но можно вешать свои задачи на любое ядро через
xTaskCreatePinnedToCore… и задавать приоритеты
На разных ядрах действительно выполняються задачи паралельно
Примеры можете глянуть в ссылках выше
Помониторь линию 3V3, от нее ESP32 питается. Тоже ловил подобный глюк. Он происходит из-за того, что происходит просадка по питанию (оказывается, для питания ESP32 AMS1117-3.3 слабоват), и ESP32 перезагружается из-за Brownout detector was triggered. Частично решить проблему поможет установка дополнительного конденсатора по линии 3V3, перманентно — питание подавать непосредственно на 3V3 через импульсную (к примеру, MP1584 или Mini360, последнюю лучше выбрать с набором напряжений) понижайку, настроенную на соответствующее напряжение.
И это, такую систему я бы посоветовал подключать через Ethernet, было бы классно, если бы и Blynk через него работал. Единственное — RMII для ethernet-модуля использует 9 пинов, из них 6 нельзя переназначить.
А какие плюсы у Ethernet? Вроде и через WiFi работает достаточно хорошо + проводов не надо от маршрутизатора к ESP, можно ставить где захочешь.
Плюс у Ethernet в надежности канала связи. При подключении WiFi возможны отвалы соединения по разным причинам (помехи, много клиентов, зашумленность эфира, да и тупо точка доступа уставшая). Если роутер/точка доступа для таких устройств в подвале, под них отдельная сетка и сигнал достаточно хороший приходит, тогда норм. Ну или если устройство перемещается. В остальных случаях лучше Ethernet, не пожалеть портов и пинов)))
А ты мониторишь отвалы устройства?
ESP32 + Arduino Core + FreeRTOS + Blynk = дом с зачатками разума