Русский
Русский
English
Статистика
Реклама

Lvgl

Doom Boy ESP32. Вторая итерация

30.07.2020 02:22:19 | Автор: admin
Так и не дождавшись DoomWatch платы сделал новый заказ с доставкой Fedex. В этот раз развел платы в KiCad. Как ни странна, Kicad понравился даже больше Eagle AutoDesk



Основная цель была попробовать распаять чип esp32d0wdq6. Не сам готовый модуль, а именно отдельно микросхемой с отдельным Flash и PSRAM. Как это сделано и работает, с видеодемками, читаете и смотрите дальше

Здесь можно прочитать про первую итерация платы

Boot


Boot Log
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7076
load:0x40078000,len:14600
load:0x40080400,len:4160
0x40080400: _init at ??:?

entry 0x40080684
I (28) boot: ESP-IDF v4.2-dev-2243-gcf056a7d0-dirty 2nd stage bootloader
I (29) boot: compile time 18:51:57
I (30) boot: chip revision: 1
I (33) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (52) boot.esp32: SPI Speed: 40MHz
I (53) boot.esp32: SPI Mode: DIO
I (53) boot.esp32: SPI Flash Size: 8MB
I (56) boot: Enabling RNG early entropy source
I (62) boot: Partition Table:
I (65) boot: ## Label Usage Type ST Offset Length
I (73) boot: 0 factory factory app 00 00 00010000 000e8000
I (80) boot: 1 wifidata WiFi data 01 02 000fc000 00004000
I (88) boot: 2 wad unknown 42 06 00100000 004f4000
I (95) boot: End of partition table
I (99) boot_comm: chip revision: 1, min. application chip revision: 0
I (106) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x38f98 (233368) map
I (216) esp_image: segment 1: paddr=0x00048fc0 vaddr=0x3ffb0000 size=0x07058 ( 28760) load
I (230) esp_image: segment 2: paddr=0x00050020 vaddr=0x400d0020 size=0x86370 (549744) map
0x400d0020: _stext at ??:?

I (468) esp_image: segment 3: paddr=0x000d6398 vaddr=0x3ffb7058 size=0x04ec4 ( 20164) load
I (478) esp_image: segment 4: paddr=0x000db264 vaddr=0x40080000 size=0x00404 ( 1028) load
0x40080000: _WindowOverflow4 at /esp/v3.3.2/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730

I (479) esp_image: segment 5: paddr=0x000db670 vaddr=0x40080404 size=0x12b7c ( 76668) load
I (538) boot: Loaded app from partition at offset 0x10000
I (538) boot: Disabling RNG early entropy source
I (549) psram: This chip is ESP32-D0WD
I (551) spiram: Found 64MBit SPI RAM device
I (551) spiram: SPI RAM mode: flash 40m sram 40m
I (555) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (562) cpu_start: Pro cpu up.
I (566) cpu_start: Starting app cpu, entry point is 0x4008191c
0x4008191c: start_cpu0_default at /esp/v3.3.2/esp-idf/components/esp32/cpu_start.c:466

I (0) cpu_start: App cpu up.
I (1454) spiram: SPI SRAM memory test OK
I (1462) cpu_start: Pro cpu start user code
I (1462) cpu_start: Application information:
I (1462) cpu_start: Project name: esp32_doom
I (1466) cpu_start: App version: 085f21b-dirty
I (1472) cpu_start: Compile time: Jul 26 2020 18:51:49
I (1478) cpu_start: ELF file SHA256: 9166eca39a0109f9
I (1484) cpu_start: ESP-IDF: v4.2-dev-2243-gcf056a7d0-dirty
I (1491) heap_init: Initializing. RAM available for dynamic allocation:
I (1498) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (1504) heap_init: At 3FFCF628 len 000109D8 (66 KiB): DRAM
I (1511) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1517) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1524) heap_init: At 40092F80 len 0000D080 (52 KiB): IRAM
I (1530) spiram: Adding pool of 4096K of external SPI memory to heap allocator
I (1539) spi_flash: detected chip: generic
I (1543) spi_flash: flash io: dio
I (1548) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (1557) spiram: Reserving pool of 32K of internal memory for DMA/internal allocations


KiCad PCB


В KiCad как мне показалось все проще. На мой вкус конечно. Немного по другому чем в Eagle Autodesk. Главный плюс в том, что нет ограничения на размер платы если не хотите платить за лицензию. Напомню что в Eagle есть ограничение на размер 100x80мм для бесплатной разработки. Если плата больше надо платить годовую лицензию. По моему, есть также ограничение на количество слоев



Посмотреть 3D View в Eagle я так и не смог. Надо ставить Eagle Fusion 360. В Kicad это отдельный пункт меню. Хотя может я не там смотрел. В общем можно сказать перешел полностью на KiCad

Разделил все на модули, оставив на главной странице то что связано с ESP32 непосредственно. Сам чип и память


Ошибки


Рисовал плату в попыхах. В результате забыл вывести GPIO0. Подвел ее во внешний DAC как MCCLK, а вот вывести на кнопку режима загрузки забыл. Пришлось сдирать лак с дорожки для пайки вывода кнопки. Так же резистор в цепи кварца развел на XTAL_N а в мануале надо на XTAL_P. Повесил резистор несколько Ом, но можно было и перемычку кинуть

Не развелись резисторы Address и Reset для MCP23017. Чипу можно задать адрес I2C тремя выводами. 0x20h когда все три вывода на земле. Все потому что не указал FootPrint

На ошибку не обратил внимания
Error: Cannot add R10 (no footprint assigned).
Error: Cannot add R9 (no footprint assigned)


Перепутал i2C для ES8374. Бывает и такое. В принципе можно использовать переключив 21 -> 22 и 22 -> 21 выводы. Или перерезать дорожки и отскоблить лак, ну как это мы обычно делали с TX RX Uart (Грустный смайл)



На удивление запаяв ESP32 и FLASH плата завелась без каких то проблем. Но поставив SPRAM получил бесконечный reboot. Оказался банальный непропай по питанию. Вот бы я искал если ESP32 не припаялся!



Мультиплексор MCP23017


Предусмотрел возможность альтернативного опроса кнопок как через мультиплексор MCP23017 так и с помощью ЦАП. На резестивном делителе. Если нет возможности поставить мультиплексор можно задействовать внутренний ADC. По уровню напряжения на входе GPIO34 можно детектировать нажатие кнопки. Минус в том что невозможно опрашивать несколько кнопок одновременно. Плюс соответственно, что не надо дополнительной микросхемы. Только несколько резисторов

Мультиплексор имеет 2 порта по 8 выводов. Один порт, в нашем случае, можно сконфигурировать как выход и повесить на них светодиоды. Хотел предусмотреть мигание если жизни осталось меньше 20% или кончились патроны. Тогда можно будет играть без панели. Получилось реализовать. Остался один зеленый светодиод. Если в комнате нет врагов или в прямой видимости можно подсветить



Thread of the health and ammo indicator
void ledTask(void *arg){    while(1){            p = &players[cur_player];            if (p->mo != NULL && p->mo->health < 20) {                mcp23x17_set_level(&dev, 9, on);            } else {                mcp23x17_set_level(&dev, 9, true);            }            if(p->ammo[weaponinfo[p->readyweapon].ammo] < 5){              mcp23x17_set_level(&dev, 10, on);            } else {              mcp23x17_set_level(&dev, 10, true);            }            printf("p->ammo[am_clip] = %d\n", p->ammo[weaponinfo[p->readyweapon].ammo]);            if (p->mo != NULL) {                printf("p->mo->health = %d \n", p->mo->health);            }            printf("Ammo N = %d\n", weaponinfo[p->readyweapon].ammo);             on = !on;             vTaskDelay(1000/portTICK_PERIOD_MS);    }}



Аудио чип ES8374


Для звука, в качестве ЦАП и АЦП применил ES8374. Микросхема содержит встроенный усилитель низкой частоты ~ 1.25 Ватт. Она поддерживается Espressif Audio Development Framework из коробки. В маленьком корпусе QFN-28 получаем Моно ЦАП, АЦП для микрофона и УНЧ с поддержкой SDK. То что надо для такого устройства


Запустил BT Speaker из примера pipeline_bt_sink

Взял в настройках борду lyrat_v4_3. Исправил кодек на AUDIO_CODEC_ES8374_DEFAULT_HANDLE
Настроил порты GPIO
esp_err_t get_i2s_pins(i2s_port_t port, i2s_pin_config_t *i2s_config){    AUDIO_NULL_CHECK(TAG, i2s_config, return ESP_FAIL);    if (port == I2S_NUM_0 || port == I2S_NUM_1) {        i2s_config->bck_io_num = GPIO_NUM_18;        i2s_config->ws_io_num = GPIO_NUM_26;        i2s_config->data_out_num = GPIO_NUM_27;        i2s_config->data_in_num = GPIO_NUM_35;    } else {        memset(i2s_config, -1, sizeof(i2s_pin_config_t));        ESP_LOGE(TAG, "i2s port %d is not supported", port);        return ESP_FAIL;    }    return ESP_OK;}

И выкинул инициализацию audio_board_key_init и audio_board_led_init. По правильному надо определять свою кастомную плату

Гироскоп L3GD20


Решил добавить гироскоп L3GD20. Интересная особенность, что его можно подключить как SPI или I2C устройство. R27, R28 в случае подключения по I2C задают адрес
// L3GD20H addresses
#define L3GD20H_I2C_ADDRESS_1 0x6a // SDO pin is low
#define L3GD20H_I2C_ADDRESS_2 0x6b // SDO pin is high
На GitHub есть библиотека l3gd20h-esp-idf


Таким образом на I2C имеем 3 устройства. Управление ADC-DAC ES8374, кнопки на MCP23017 и собственно L3GD20. Запустил все три

i2cdetect
i2c-tools> i2cdetect
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: 10 -- -- -- -- -- -- --
20: -- -- 24 -- -- -- -- --
30: -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- --
60: -- -- -- -- -- 6a -- --
70: -- -- -- -- -- -- -- --


Но почемуто L3GD20 не отдает координаты. WHO_AM_I корректо отвечает 0xd4. углы не меняются. У меня нет конденсатора С1 10nF, попытался поставить который нашел самый близкий 100nF. Думал пусть хотя бы врет, но похоже не запускается внутрений преобразователь. И это важно

i2cdump
i2c-tools> i2cdump -c 0x6a
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: b6 5e 81 fc 05 50 31 83 c4 f9 85 d0 48 c6 00 d4 ?^???P1?????H?.?
10: 1a 15 16 ea c0 b9 4f 72 07 d8 a1 21 a1 00 14 02 ??????Or???!?.??
20: 07 00 00 80 00 00 0c 00 1a 00 13 00 16 00 00 20 ?..?..?.?.?.?..
30: 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 .........?..
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


Дисплей 18 pin ILI9341




Рассчитал ток подсветки так. Требуется 90mA. Поскольку падение на открытом транзисторе ~0.7V питание для светодиодов подсветки 3.3V 0.7V = 2.6V. И по закону Ома 2.6V / 0.090A = 28.8 Ohm. Поставил 47 Ohm. Получилось немного темновато. Надо будет уменьшить сопротивление


Также развел Touch XPT2046TS. SPI выводы повесил параллельно дисплею. XPT_CS выведен отдельным выводом. Есть сомнение что заработает. Если бы дисплей не завелся, сделал бы эксперименты. Для приставки он не особо нужен. Взял из примера



Демки


Запустил демо LVGL. В настройках примера пробовал выставлять 40MHz для шины SPI. Пример заработал немного быстрее чем на видео



А вот Doom запустился и стабильно работал только на 32MHz. Хотя 26MHz для ILI9341 уже считается разгон
spi_device_interface_config_t devcfg={        .clock_speed_hz=26000000,               //Clock out at 26 MHz. Yes, that's heavily overclocked.        .mode=0,                                //SPI mode 0        .spics_io_num=PIN_NUM_CS,               //CS pin        .queue_size=NO_SIM_TRANS,               //We want to be able to queue this many transfers        .pre_cb=ili_spi_pre_transfer_callback,  //Specify pre-transfer callback to handle D/C line    };




Заключение


Портов ввода вывода ESP32 не всегда хватает чтобы нафаршировать по максимуму. В этом плане STM32 выглядит привлекательнее. Но у нее нет встроенной поддержки Wi-Fi

В заключении отмечу, что на устройстве можно запустить Nintendo эмулятор ESP32-NESEMU, a Nintendo Entertainment System emulator for the ESP32
Я заказал Game Console с Али. Интересно будет посмотреть что там внутри. Возможно тоже ESP32



Обсуждение и советы жду в комментариях
Подробнее..

ESP32 LVGL и круглый дисплей

25.03.2021 16:19:55 | Автор: admin

В прошлом году, после выхода видео про дисплей GC9A01 на канале "Электроника в объективе", я решил, что обязательно должен что-то на нем собрать, да еще и с использованием графической библиотеки LVGL. Заказал 2 таких дисплея, один на отладочной плате, второй отдельно только дисплей со шлейфом.

Так как я не очень люблю когда все соединено на проводах или макетных платах, (постоянно что-то отваливается), и хотелось какое-то законченное устройство в корпусе, решил поискать подходящий вариант и уже под него делать плату, ничего из стандартных корпусов для РЭА найти не удалось. Думал уже делать в виде съемной конструкции для своей отладочной платы на ESP32, но потом нашел подходящий вариант, (из под консилера :) ), он идеально подходил под мою задумку, был круглый открывающийся и имел прозрачное окно в размер дисплея. решено было делать плату под него.

Основные требования по устройству были: чип ESP32 так же для перспективы заложил драйвер RS-485 и слот для microSD карточки, так же хотелось иметь возможность питать все от usb и в перспективе иметь возможность подать внешнее питание. Так как разъем все равно ставить, хотелось сразу иметь возможность и программировать esp32 без дополнительных подключений. Но количество свободного места оказалось крайне мало, ставить CP2102 было дороговато, а CH340 с ее габаритами и кварцем не хотелось. Случайно увидел что есть компактная микросхема CH340N SOIC-8, преобразователь USB-UART с минимальной обвязкой в корпусе SOP-8. Ее и решено было использовать.

Так как на одной плате все не помещалось, разделил на две, верхняя ESP32 и дисплей, снизу питание, microSD слот, драйвер RS485 и USB-UART преобразователь. Для связи между нижней и верхней платой решил использовать гибкий плоский шлейф FFC и коннекторы FPC с шагом 0.5. Готовых шлейфов под размер и количество линий в наличии не было, решил делать из широкого и длинного шлейфа, думал что не получится разделить, но оказалось что это возможно. Для удешевления заказа объединил две платы в одну, с последующим удалением перемычки между ними, такая компоновка позволяет использовать верхнюю плату и под другие проекты с выводом информации на дисплей.

Общий вид печатной платы

Прикинув все размеры компонентов, решил уменьшить толщину платы до минимально возможного размера без увеличения стоимости, заказал с толщиной 0,6мм с зеленой маской. При такой толщине их можно резать чуть ли не ножницами, разделение на 2 платы заняло пару минут. Как оказалось не обошлось и без "косяков", перепутал выводы micro-USB разъема, разместил зеркально, пришлось резать дорожки и переделывать, после залил лаком. Так же вывод Reset дисплея соединил не с портом общего назначения, а с сигналом разрешения работы EN, в принципе на работе это не отразилось, но нет возможности сброса экрана из программы. Вся остальная схема запустилась без проблем, прошивается через micro-USB, через этот же разъем можно подключаться по Modbus например используя Modbus poll/mbslave, задействовал линии rx и tx которые идут на драйвер ADM3485 и они же используются при программировании.

Для создания проекта использовал ESP-IDF и порт LVGL. Данный пример содержит множество готовых драйверов дисплеев и примеры большинства виджетов библиотеки LVGL. Так как дисплей не имеет тачскрина, то мне были интересны примеры вывода графики в виде различных манометров и других, заточенных под круглые дисплеи, виджетов. Пример из библиотеки мне не очень понравился, хотелось использовать что-то более реалистичное, так как сам дисплей позволяет выводить довольно качественную картинку, решил использовать готовые подложки, их необходимо подготовить под разрешение 240x240, в принципе можно использовать любые подходящие, единственное перед конвертацией в графическом редакторе необходимо убрать стрелки, так как стрелка будет управляться отдельно из программы. Варианты стрелок так же можно подготовить в разном стиле и цвете, для разных подложек. Стрелка должна быть симметрична, так как из программы она будет вращаться относительно центра дисплея. Вся подготовленная под размер экрана графика конвертируется через сервис imageconverter в .с файл, который затем подключается в программе. Самый простой пример для манометра содержит два объекта, сама подложка она статическая и стрелка- изменяющийся объект.

img0 = lv_img_create(lv_scr_act(), NULL);//фон манометраlv_img_set_src(img0, &man5);lv_obj_align(img0, NULL, LV_ALIGN_CENTER, 0, 0);//стрелка, угол 60lv_img_set_angle(s6, 600);

Задание для стрелки выдается в отдельной задаче вызываемой с требуемым периодом:

static void update_time(void *arg){//    get_time(); //получить значение часов, минут, секундcur_time_s++;//    lv_img_set_angle(  lvHour, cur_time_h*30*10);//    lv_img_set_angle(  lvMinute, cur_time_m*6*10);    lv_img_set_angle(  lvSecond, cur_time_s*6*10);//задание угла для секундной стрелки}

Минимальный шаг задания 0,1, окружность разделена на 3600 частей. В зависимости от выбранной подложки можно рассчитать min и max задание в пределах шкалы. Остается преобразовать полученное значение от датчика в угол задания. Для демонстрации часов происходит управление тремя стрелками, достаточно поднять на ESP32 NTP сервер и получить текущее значение часов. минут, секунд (в моем примере NTP сервис не запущен) Для того, чтобы каждый раз не корректировать файлы стрелок под выбранный циферблат их можно масштабировать:

//удлинить минутную стрелкуlv_img_set_zoom(lvMinute, 340);

В примере продемонстрирован минимальный набор для запуска на дисплее, в самой библиотеке представлены примеры всех виджетов, большинство из которых имеет смысл на дисплеях с тачскрином. Ранее я проверил данную библиотеку на 7" дисплее с сенсорным тач контроллером.

Из недостатков можно отметить "тормознутость" на больших диагоналях из-за невозможности выделить полноценный буфер под полное разрешение экрана, особенно это проявляется при обновлении всего экрана, когда происходит скроллинг или открытие другого таба. Для простых кнопочных интерфейсов эта проблема не так актуальна, так как обновляется только область кнопки. Для представленного дисплея с разрешением 240x240 проблема не так заметна, но при использовании нескольких подложек сильно увеличивается размер прошивки. Пока вижу вариант загрузки графики с SD карты или использования ESP32 с памятью psram и размещением в ней графики или буфера. На моих платах интерфейс spi дисплея и sd карты разведены на одних и тех же пинах и, насколько я знаю, пока не удалось заставить их работать в тандеме, есть отдельные упоминания о работе но я пока не проверял. Если у кого-то есть работающий пример напишите в комментариях. Так же я пока не пробовал использовать память psram для размещения буфера дисплея, без этого памяти остается не так много. В чипе который используется ее нет, но она есть в чипе ESP32-WROVER на второй плате к которой можно подключить дисплей от Adafruit 4,3" , Waveshare 7" и данный круглый через переходник со шлейфом.

Общий вид отладочной платы

Дальше планирую проверить подключение по Modbus и можно использовать как небольшую панель для чтения параметров из внешних устройств. Так же на самой плате возле выводов модуля сделаны полигоны для возможности подключения датчиков, например ds18b20 или влажности/давления, внутри их размещать смысла нет, так как при закрытом корпусе там довольно жарко, но можно вывести наружу через отверстие. Так же можно организовать mqtt и получать данные с удаленного датчика. Наконец, есть еще bluetooth который я даже не включал, но думаю и там есть множество применений. Далее видео получившегося устройства с демонстрацией разных вариантов экранов.

Уже перед подготовкой статьи, решил проверить как будут выводиться картинки с сайтов где продаются эти дисплеи, на первом фото как раз одна из часто используемых фотографий, камера плохо передает изображение с экрана, в живую смотрится очень натурально.

Схему не привожу, так как ее у меня нет, плата разводилась "на лету" за чашкой чая вечером, обвязку для микросхем можно взять в pdf, esp32 так же позволяет переназначать все пины используемые в проекте. Для запуска примеров достаточно взять ESP32-DevKitC и плату с экраном GC9A01. Пины используемые в моем проекте: MOSI-12 CLK-14 CS-23 DC-22. SPI лучше использовать на пинах по умолчанию, тогда его можно будет запускать на "максималках", у меня первая плата была разведена не так и эту я оставил для совместимости проектов.

Перечень основных элементов:

  • ESP-WROOM-32

  • ADM3485EARZ-REEL7

  • CH340N

  • AMS1117

  • FPC SC 0.5MM 14P CB

  • 12PIN SPI TFT LCD GC9A01

Мой демо проект на github в папке components/image конвертированные файлы подложек для экранов.

Тут более свежие версии библиотеки с примерами.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru