Здравствуйте дорогие фурмочане. Своя голова уже не понимает в какую сторону копать, поэтому прошу помощи более опытных, и не с замыленным глазом Опишу вкратце свой проект. собираю котел на отработанном масле с воздушным съёмом тепла. печь управляется двумя вентиляторами и масляным насосом. Первый вентилятор нагнетает воздух в камеру сгорания, второй обдувает саму камеру и снимает тепло с камеры и выдувает горячий воздух в помещение, и масляный насос для контролируемой подачи масла в камеру сгорания. мой интерфейс по нажатию на кнопку On Код (C++): void OnBtnClick(lv_event_t * e) { Serial.println("Нажата кнопка On"); timer_On_Start = lv_timer_create(timer_start, 100, NULL);//Создаем таймер и переходим в функцию timer_on через 100 мс } через 100 мс после нажатия должен запуститься таймер с вызовом функции Код (C++): void timer_start(lv_timer_t *timer_On_Start) { Serial.println("Функция timer_start"); Serial.println("Выполнение работы в режиме start"); digitalWrite(GREEN_PIN, LOW); // зажечь зеленый цвет digitalWrite(RED_PIN, HIGH); // потушить красный цвет digitalWrite(BLUE_PIN, HIGH); // потушить синий цвет lv_timer_del(timer_On_Start); // Удаляем текущий таймер после выполнения кода timerMedium = lv_timer_create(timer_medium, ta_time_medium, NULL); // После того как код выполнен создаем новый таймер предварительно удалив текущий. ta_time_medium это время по истечению которого новый таймер запустится } и еще 2 подобных режима который по вызову таймера переключаются автоматически и при нормальной работе проблем не возникает(если не нажимать кнопку off) Код (C++): void timer_medium(lv_timer_t *timerMedium) { Serial.println("Функция timer_medium"); bool switch_active = lv_obj_has_state(ui_SwitchSteepMedium, LV_STATE_CHECKED); // mode = switch_active ? 1 : 2; // проверяем состояние переключателя, если true присваиваем переменной mode значение 1, если false то значение 2 if (!switch_active) { Serial.println("Выполнение работы в режиме Medium"); digitalWrite(GREEN_PIN, LOW); // зажечь зеленый цвет digitalWrite(RED_PIN, HIGH); // потушить красный цвет digitalWrite(BLUE_PIN, LOW); // зажечь синий цвет timerMaximum = lv_timer_create(timer_maximum, ta_time_maximum, NULL); // Послее тоого как код выполнен создаем новый таймер предварительно удалив текущий }else{ Serial.println(" Код Medium не выполняется, переходим в режим максимум"); // Удаляем текущий таймер timerMaximum = lv_timer_create(timer_maximum, 200, NULL); // Послее тоого как код выполнен создаем новый таймер предварительно удалив текущий } lv_timer_del(timerMedium); // Удаляем текущий таймер //timerMedium = NULL; // Устанавливаем указатель на NULL } void timer_maximum(lv_timer_t *timerMaximum) { // Выполнение работы в режиме maximum Serial.println("Функция timer_maximum"); Serial.println("Выполнение работы в режиме Maximum"); digitalWrite(GREEN_PIN, HIGH); // потушить красный цвет digitalWrite(RED_PIN, HIGH); // потушить красный цвет digitalWrite(BLUE_PIN, LOW); // зажечь синий цвет lv_timer_del(timerMaximum); //timerMaximum = NULL; // Устанавливаем указатель на NULL } и самая проблематичная часть кода в которой и возникает проблема. эта функция вызывается при нажатии на кнопку off Код (C++): void OffBtnClick(lv_event_t * e) { // тут пишем код который включит вентиляторы на продувку камер, далее создаем таймер lv_timer_create с задержкой на 10 минут 10*60000. по истечению 10 минут запустится timer_off //в функции timer_off обнуляем значение вентиляторов и удаляем таймер // Выполнение работы в режиме продувка Serial.println("Нажата кнопка Off"); Serial.println("Выполнение работы в режиме Продувка"); //Включаем вентиляторы digitalWrite(BLUE_PIN,HIGH); //потушить синий цвет digitalWrite(RED_PIN,LOW); //Зажечь красный цвет digitalWrite(GREEN_PIN,HIGH); //потушить зеленый цвет if (timerMedium != NULL) { Serial.println( "timer medium deleted" ); lv_timer_del(timerMedium); // Удаляем таймер } else if (timerMaximum != NULL) { Serial.println( "timer maximum deleted" ); lv_timer_del(timerMaximum); // Удаляем таймер } timerOff = lv_timer_create(timer_off, ta_time_off, NULL); // Создаем новый таймер } если у меня возникнет необходимость по какой либо причине остановить работу печи в любой момент то необходимо удалить все текущие таймеры, для этого я проверяю какой таймер запущен и пытаюсь его удалить Код (C++): if (timerMedium != NULL) { Serial.println( "timer medium deleted" ); lv_timer_del(timerMedium); // Удаляем таймер } else if (timerMaximum != NULL) { Serial.println( "timer maximum deleted" ); lv_timer_del(timerMaximum); // Удаляем таймер } если я нажму кнопку on, и тут же нажму кнопку off то все отрабатывает отлично. ниже лог с монитора Нажата кнопка On Функция timer_start Выполнение работы в режиме start Нажата кнопка Off Выполнение работы в режиме Продувка timer medium deleted Функция timer_off таймер timerMedium запустился но не отработал, и в этот момент была нажата кнопка off обработчик этой кнопки OffBtnClick удалил таймер и программа успешно отработала, но стоит мне дождаться когда отработает таймер timerMedium и меня перекинет в функцию timer_medium и в этот момент я нажму на кнопку off я получаю следующее Нажата кнопка On Функция timer_start Выполнение работы в режиме start Выполнение работы в режиме Medium Нажата кнопка Off Выполнение работы в режиме Продувка timer medium deleted // хотя timer medium должен был удалиться сразу т.к код выполнился и в нем отработала функция Код (C++): lv_timer_del(timerMedium); // Удаляем текущий таймер и в это время создался новый таймер Код (C++): timerMaximum = lv_timer_create(timer_maximum, 200, NULL); и получаю такую ошибку. хотя все активные таймеры должны удалиться и должна отработать последняя функция Код (C++): void timer_off(lv_timer_t *timerOff) { Serial.println("Функция timer_off"); digitalWrite(RED_PIN, HIGH); // потушить красный цвет lv_timer_del(timerOff); // Удалить таймер после его выполнения } Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled. Core 1 register dump: PC : 0x40121075 PS : 0x00060830 A0 : 0x800dcd36 A1 : 0x3ffb20c0 A2 : 0x3ffcb4e8 A3 : 0xbaad5690 A4 : 0x3ffb4a3c A5 : 0x0000ff00 A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00000018 A9 : 0x3ffb20a0 A10 : 0x00000002 A11 : 0x3f435811 A12 : 0x00000002 A13 : 0x0000ff00 A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000010 EXCCAUSE: 0x0000001d EXCVADDR: 0xbaad5690 LBEG : 0x400868d5 LEND : 0x400868e5 LCOUNT : 0xfffffffb может быть кто то увидит проблему и тыкнет пальцем . я уже несколько дней пытаюсь решить данную проблему безуспешно
Продаются модули "экран + есп32 с установленной библиотекой". Типа такого - https://www.ozon.ru/product/esp32-s...luetooth-mcu-smart-display-screen-1266289481/
Это экосистема. Дисплеи на основе esp32, библиотеки под все среды разработки, визуальный редактор, которые делает заготовки кода. Довольно сложная среда, с разбегу не разобраться. Зато дешевле чем DWIN и тем более NEXTION. Я заказал такой дисплей на пробу.
У меня дисплей из этой же серии, только диагональю побольше. по факту пару свободный пинов, и I2C не запустить т.к на нем висит тач. по крайне мере у меня завести датчик температуры не получилось. пришлось подкидывать 2й МК с общением по serial
Я вообще планирую его использовать только как экран. Пусть передает сообщения главному контроллеру, а тот уже делает все что надо.
Вот, кому интересно, первые впечатления от экранчика ЛГБТ LVGL. Маленький, я думал будет крупнее. DWIN гораздо больше, даже самый мелкий. Бледненький, углы обзора небольшие, картинка плавает при небольших качаниях. Тестовая заливка работает довольно шустро, но не как на смартфоне, конечно, и не как на DWIN. То есть, пока понятно почему он дешевле. Преимущества перед DWIN наверное одно - можно делать анимацию из линий и примитивов, например графики движущиеся и тому подобное с меньшими ограничениями, т.к. DWIN работает почти полностью только с готовыми изображениями. Прошивать, как по мне, сложнее, исправлять или дорабатывать тем более. Поработаю с ним. конечно, но пока что перспектив для себя не вижу.