ESP32 Урок 52. RMT. WS2812B. Лента на умных светодиодах RGB. Инициализация



Продолжаем работать с модулем RMT (Remote Control) и с сегодняшнего урока мы попытаемся с использованием данного модуля поработать со светодиодной лентой, состоящей из цепочки адресных светодиодах WS2812B.

Как именно управлять такими светодиодами, мы знакомы давно из курса уроков по контроллерам STM32, поэтому нам будет намного проще организовать алгоритм работы и с применением контроллера ESP32. Только управляющие импульсы мы будем отправлять с применением модуля RMT. Почему именно RMT, думаю, и так понятно без объяснений. Дело в том, что если применять задержки, то планировщик операционной системы FreeRTOS по окончанию задержки может запустить совершенно другой код из параллельной задачи и мы рискуем получить неточные тайминги.

Светодиодную ленту мы подключим подобно тому, как мы это делали в уроке 119 по STM32. Только в качестве сигнальной ножки порта у нас будет выступать ножка GPIO4. К данной ножке мы также подключим логический анализатор, чтобы следить за процессом передачи данных. Питать мы ленту будем также от DC-DC преобразователя, так как максимальной силы тока стабилизатора платы может не хватить.

В результате получим вот такую схему

 

 

 

Пока не будем подключать питание ленты, а также отладочную плату к компьютеру, так как нам придется писать очень много кода, а займёмся проектом, который сделан из проекта урока 4 с именем BUTTON01 и назовём его WS2812_INIT.

Откроем наш проект в Espressif IDE и внесём изменения в файл конфигурации Kconfig.projbuild.

Так как кнопка нам не нужна, то у нас не будет данного пункта меню. После изменения файл приобретёт следующий вид

 

 

Также создадим в каталоге проекта файл sdkconfig.defaults следующего содержания

 

 

Удалим полностью весь код из функции app_main файла main.c, а выше добавим функцию конфигурации ленты, также пока пустотелую

 

 

Вызовем данную функцию из функции app_main

 

 

В каталоге main проекта создадим заголовочный файл main.h следующего содержания

 

 

Вернёмся в main.c и удалим подключения заголовочных файлов, а подключим наш новый заголовочный файл main.h

 

 

Создадим ещё один заголовочный файл led_strip.h пока следующего содержания

 

 

Подключим данный файл в main.h

 

 

Создадим также файл led_strip.c, в котором также подключим наш заголовочный файл

 

 

Не забываем также данный файл подключить в CMakeLists.txt

 

set(COMPONENT_SRCS "main.c" "led_strip.c")

 

Пересоберём проект, перейдём в файл led_strip.h и добавим два перечислимых типа, один для формата пикселя, другой для моделей адресных светодиодов

 

 

Добавим структуру для свойств ленты

 

 

Назначение каждого поля понятно из комментариев.

В файле main.c в функции configure_led объявим переменную типа нашей структуры и инициализируем некоторые её поля

 

 

Мы инициализировали ножку и максимальное количество светодиодов в ленте. Остальные поля выставились по умолчанию в 0.

 

 

Вернёмся в файл led_strip.h и добавим ещё одну структуру для инициализации свойств канала RMT

 

 

Здесь также назначения полей описаны в комментариях.

Объявим структуру с функциями для управления лентой и одноимённый тип для неё

 

 

Выше объявим тип указателя на тип такой структуры

 

 

Вернёмся в main.c и объявим такой указатель

 

 

В функции configure_led объявим переменную также типа структуры свойств RMT и инициализируем только одно поле с разрешающей способностью

 

 

Перейдём в файл led_strip.c и добавим функцию инициализации нового устройства

 

 

В заголовочном файле создадим прототип на данную функцию и затем в функции configure_led файла main.c вызовем её

 

 

В файле led_strip.c также объявим структуру со свойствами ленты

 

 

В функции led_strip_new_rmt_device объявим указатель на тип данной структуры

 

 

Ниже объявим метку и напишем код. На данный код мы будем переходить в случае определённых ошибок

 

 

Выше метки произведём выход с положительным результатом, так как если мы сюда дошли, то у нас ошибок нет

 

 

Объявим глобальный символьный массив для лога

 

 

Вернёмся в функцию led_strip_new_rmt_device  и проверим на валидность входные аргументы

 

 

Конструкция ESP_GOTO_ON_FALSE проверяет на TRUE результат выражения в первом аргументе. Если FALSE, то происходит переход по метке, обозначенной в третьем аргументе, переменной ret (это предопределенное имя) присваивается значение из второго аргумента, а также в терминал выводится сообщение из пятого аргумента.

 

 

Далее проверим аналогичным способом поле led_pixel_format

 

 

Вычислим количество бит на пиксель

 

 

Запросим память под буфер

 

 

Проверим, что память выделилась

 

 

Объявим глобально разрешающую способность RMT по умолчанию

 

 

Вернёмся в функцию led_strip_new_rmt_device и объявим переменную, которой присвоим значение разрешающей способности

 

 

Объявим переменную и присвоим ей значение частоты RMT по умолчанию

 

 

А если частота был определена отдельно при конфигурировании, то присвоим её значение нашей переменной

 

 

Также нам нужен будет размер блока памяти. Объявим также глобально данную величину

 

 

Вернёмся в функцию led_strip_new_rmt_device и объявим переменную, которой присвоим величину блока памяти

 

 

А если величина блока была определена при конфигурировании, то присвоим её переменной

 

 

Объявим глобально глубину внутренней очереди передачи RMT

 

 

Вернёмся в функцию led_strip_new_rmt_device и сконфигурируем канал RMT

 

 

Проверим конфигурацию канала

 

 

В заголовочном файле led_strip.h объявим структуру для свойств энкодера байтов, в которой в качестве полей будут разрешающая способность в герцах и модель светодиодов

 

 

Вернёмся в файл led_strip.c и в функции led_strip_new_rmt_device объявим переменную данной структуры и инициализируем её поля

 

 

Выше добавим функцию для настройки энкодера

 

 

В функции led_strip_new_rmt_device вызовем данную функцию

 

 

Объявим глобальную структуру для энкодера

 

 

Займёмся теперь энкодером.

В функции rmt_new_led_strip_encoder объявим указатель на тип только что объявленной структуры

 

 

Добавим аналогичную метку, как в предыдущей функции для перехода по ошибке

 

 

Проверим факт существования входных аргументов, а также валидность модели (принадлежность диапазону значений)

 

 

Выделим память под буфер и проверим успешность выделения

 

 

Выше добавим функцию кодирования

 

 

Объявим указатель на на структуру энкодера

 

 

Объявим хендлы. Один будет хранить указатель на энкодер (кодировщик) байтов, который может кодировать поток байтов в символы RMT, второй — на энкодер (кодировщик) копирования, который копирует заданные символы в память RMT.

 

 

Объявим также две переменные перечислимого типа для состояний

 

 

В зависимости от состояния нашего энкодера (это немного не те состояния, переменные для которых мы создавали выше, это состояние передачи данных RGB или состояния RESET) произведём преобразование цепочки байтов в код RMT либо кодирование команды RESET и переключим состояние на другое. В телах ответвлений переключателя вариантов как-раз-таки и используются статусы, переменные для которых мы объявляли.

 

 

Ниже добавим функцию удаления энкодера

 

 

Ниже также добавим функцию сброса энкодера

 

 

Вернёмся в функцию rmt_new_led_strip_encoder и инициализируем поля структуры энкодера, показав ему имена наших функций обратного вызова

 

 

Добавим переменную для свойств передачи байта и сконфигурируем тайминги импульсов в зависимости от модели светодиода

 

 

Создадим наш энкодер с помощью специальной функции

 

 

Сконфигурируем копирование

 

 

Настроим также кодирование сброса (не менее 50 микросекунд)

 

 

Вернём указатель на структуру энкодера, а также положительный результат

 

 

Добавим заготовки под основные функции нашей ленты

 

 

В функции led_strip_new_rmt_device инициализируем поля переменной структуры ленты, указав имена наших основных функций

 

 

Вернём указатель на нашу структуру

 

 

Вот в принципе и вся инициализация.

На следующем уроке мы постараемся уже конкретно поуправлять свечением различными цветами и различной яркостью наших светодиодов в ленте.

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

 

Недорогие отладочные платы ESP32 можно купить здесь:

На AliExpress Недорогие отладочные платы ESP32

На Яндекс.Маркет Недорогие отладочные платы ESP32

Ленты светодиодные WS2812B разные можно приобрести здесь WS2812B

Логический анализатор 16 каналов можно приобрести (AliExpress) здесь

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 RMT. WS2812B. Лента на умных светодиодах RGB. Инициализация

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 Name

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*