- PVSM.RU - https://www.pvsm.ru -
Здравствуйте, Хабровчане!
В преддверии Нового года хочу поделиться с вами опытом изготовления поделки, в основе которой лежит бесплатная "девборда" из условно одноразового изделия. В статье разберемся, как управлять адресными светодиодами при помощи микроконтроллера PUYA PY32F002BF и как отслеживать заряд батареи при помощи АЦП.
Лирическое отступление.
В наш век доступности всего и вся может возникнуть вопрос - "А зачем ты это делаешь?". Именно этот вопрос задал мне сын, глядя на мигающие огоньки. Ведь можно купить адресную гирлянду на ёлку с кучей режимов и приложением на телефон. Я задумался и ответил: "Хочу чтобы эта штучка мигала именно так, как я хочу". Потом ещё подумал и пришел к выводу, что скорее всего найденная платка мне не давала покоя. Разобрал, увидел контроллер, светодиоды - наверное можно управлять и отложил в ящичек. Потом коллега по работе нашел такую-же платку и предложил подпаять STMку, дабы сделать условную ёлку в виде платы в USB разъем для усиления новогоднего настроения на рабочем месте. Уже звучало как вызов. Зачем припаивать, если уже всё есть на плате. А вызовы и ответы на них - это эволюция. С интересом для себя обнаружил, что приобретенные знания в таких, казалось бы, бесполезных проектиках находят применение в более сложных, нужных и оплачиваемых задачах.
Итак, приступим. Для быстрого старта необходимо ознакомиться со статьёй [1]. Там описано как настроить цепочку инструментов и подготовить народный "свисток" ST-LINK V2.
Аккуратно разбираем найденное (отобранное с лекцией о вреде пагубных привычек у друга/подруги/подростка), пока ещё не запрещенное в Российской Федерации, одноразовое изделие. Я аккуратно пропиливал (не насквозь) часть шва пластикового корпуса и вскрывал поворотным движением отвертки в прорези. Плата держится на двух саморезах. Саморезики в коллекцию, остальное утилизировать согласно правилам раздельного сбора.
Запись в журнале по требованиям безопасности. Плановый инструктаж о мерах предосторожности при работе с литий-содержащими элементами питания. Такие элементы пожароопасны и требуют осторожности в обращении обученным и допущенным персоналом!
Методом пайки отсоединяем аккумулятор (не замкните жалом контактные площадки!) от платы, и убираем его от лиц, которые не сдали на допуск и не расписались в журнале по ТБ. Проводим осмотр платы. Определяем маркировку микроконтроллера, ищем документацию. Находим выводы для программатора.
Вооружившись тестером в режиме прозвонки, ищем места, где подпаять провода. На этом этапе я был слегка огорошен. Первый и пятнадцатый вывод не разведены, ровно как и выводы данных на USB разъеме. Скорее всего, на линию монтажа контроллеры идут уже прошитые. Самая сложная часть этого проекта - подпаяться к 1 и 15 выводам. Я сделал это следующим образом. Методом скрайбирования подготовил две площадки в свободном месте платы для пайки проводов. К этим площадкам припаял две жилы провода (приблизительно 0,15 мм). Вторые концы паял к выводам микросхемы тыкая концом жала в вывод. Паял без микроскопа. Первый вывод получилось сразу, второй с третьей попытки. Проверяем прозвонкой.
Теперь самое время вставить программатор и послать команду pyocd erase -t py32f002bx5 --chip --config ./Misc/pyocd.yaml.
В отличии от моего предыдущего опыта [1], не пришлось ловить момент старта заводской прошивки. Чип стёрся сразу, можно продолжать.
В заводской топологии лента подключена к 7 выводу (PB5). Согласно даташиту, этот вывод может быть: SPI_NSS, USART_RX, TIM1_CH3, TIM14_CH1. И тут я не увидел быстрого способа запустить ленту. Скорее всего, китайцы управляли лентой при помощи ШИМа на таймере и DMA (как тут [2]). Это решение мне нравится, так как не надо менять топологию. Но быстро я это не освою, а у нас же проект выходного дня. Готовое решение я нашел у IOsetting [3], путь к примеру - Examples/PY32F07x/HAL/SPI/WS2812_LED. Управление лентой строится на посылке нужных сигналов через выход SPI. Я подключил ленту к 20 выводу (PA7 - SPI_MOSI, дорожку от PB5 перерезал). Самое время написать встраиваемое специальное программное обеспечение.
Все файлы проекта располагаются в папке User.
В Makefile раскомментируем наш микроконтроллер - MCU_TYPE = PY32F002Bx5
. В файле py32f002b_hal_conf.h откроем необходимую нам периферию (ADC и SPI - #define HAL_ADC_MODULE_ENABLED
и #define HAL_SPI_MODULE_ENABLED
). В файле 32f002b_hal_msp.c добавим инициализацию и деинициализацию SPI.
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_InitStruct; // Структура для хранения настроек
if (hspi->Instance == SPI1)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); // Тактирование
__HAL_RCC_SPI1_CLK_ENABLE();
/* PA7 -> AF0 -> MOSI */
GPIO_InitStruct.Pin = GPIO_PIN_7; // Настройка режима SPI
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI1)
{
__HAL_RCC_SPI1_FORCE_RESET();
__HAL_RCC_SPI1_RELEASE_RESET();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_7);
}
}
В фале ws2812_spi.h задаем количество светодиодов в ленте - #define WS2812_NUM_LEDS 9
.
Так как работа с адресными лентами хорошо описана, и информация доступна в сети, в этой статье не будем рассматривать это подробно. Нас интересуют функции установки цвета светодиода ws2812_pixel(uint16_t led_no, uint8_t r, uint8_t g, uint8_t b) и отправки сформированного массива s2812_send_spi().
В исходном варианте схемы питание на светодиоды подается через транзистор Q3 (видимо, для возможности отключения ленты в момент бездействия изделия). Транзистор управляется через PB3. Этот вывод сконфигурируем как GPIO. В файле main.c добавим включения заголовочных файлов и функции конфигурации портов ввода-вывода и SPI (APP_GpioConfig()
). Из примера в главном цикле запустим простое изменение цвета всей ленты.
....
int main(void)
{
uint8_t i = 0, r = 0, g = 0x60, b = 0xC0; // Цвета со смещением, иначе у нас будет
// только белый цвет
HAL_Init();
APP_GpioConfig(); // Настраиваем ранее описанную перифериию
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0); // включаем ленту - 0, выключаем - 1
ws2812_pixel_all(r, g, b);
ws2812_send_spi();
while (1)
{
i = (i + 1) % WS2812_NUM_LEDS;
ws2812_pixel(i, r++, g++, b++); // Устанавливаем цвет
ws2812_send_spi(); // Отправляем данные
HAL_Delay(20);
}
}
...
Компилируем и прошиваем. После нескольких проб и ошибок (например, я не описывал прототип функции в самом начале и пытался к ней обращаться) лента радостно засветилась.
Простое изменение цвета это хорошо, но одинаково и скучно. Я стал искать, как без библиотек (типа NeoPixel) реализовать что-то весёлое и новогоднее (типа радуги). Поиски привели к LED Strip Effects Generator [4]. Это конструктор, в котором можно задать параметры своей ленты, выбрать эффект (или несколько) и на выходе получить код для Arduino. После небольших правок (я поменял функции отправки и некоторые параметры эффекта) мне удалось запустить радугу на своем устройстве. Далее, чтобы не загромождать тут всё кодом, сошлюсь на github [5] этого проекта.
Для контроля заряда аккумулятора воспользуемся АЦП. Имея список каналов АЦП и соответствующих им ножек микроконтроллера, я стал искать делители. И, похоже, что замер напряжения происходил в момент включения нагревательных элементов, потом сохранялся и отображался с учетом логики заводской программы. Альтернативой этого метода выступил способ измерения каналом ADC_CHANNEL_VREFINT. Для этого была добавлена функция конфигурации АЦП (APP_AdcConfig(void)
). Сам замер максимально прост.
APP_AdcConfig();
HAL_ADC_Start(&AdcHandle);
HAL_ADC_PollForConversion(&AdcHandle,1000000);
adc_value[0]=HAL_ADC_GetValue(&AdcHandle);
T_VCC=adc_valie[0];
В даташите есть формула пересчета попугаев в Вольты, но без внятных средств отладки (нужно было подпаивать UART), я так и не получил внятных результатов. Значения в отсчетах я нашел методом научного перебора (менял напряжение питания на лабораторнике и смотрел сколько у меня загорелось светодиодов, попутно меняя условия их зажигания в попугаях). Этот код я сюда конечно же вставлять не буду, но все желающие могут его увидеть на указанном выше гите. Последним вопросом для меня осталась индикация заряда. Процесс заряда организован при помощи Li-Polymer Charger LP-4068. В оригинальной схеме пятый вывод LP-4068 подключен к входу микроконтроллера и программно отслеживается. Я посмотрел осциллографом эту ножку при подключенном внешнем питании. На ней появлялся периодический импульс, этот импульс, скорее всего, включал светодиод.
Быстрого решения использовать это я не нашел (скорее всего используется внешнее прерывание-установка флага-контроль по времени). Но, примерно на этом этапе, выяснилось, что у микроконтроллера есть встроенный датчик температуры. А в процессе заряда LP-4068 нагревается. По повышению температуры я могу показывать индикацию заряда. Датчик подключен к тому-же каналу АЦП, что и ADC_CHANNEL_VREFINT. В зависимости от того, что требуется измерить (напряжение питания или температуру), нужно переконфигурировать канал АЦП. Общий алгоритм работы выглядит так:
после подачи питания настраивается периферия, и мы попадаем в главный цикл;
если напряжение питания больше 2.9 В и температура не выше 27 градусов - включаем радугу на минуту (радуга постепенно ускоряется, потом горят синие и красные огни, как мигалка полиции);
выключаем ленту на 30 секунд;
включаем индикацию заряда, потом температуры.
повторяем цикл.
При нагреве больше 27 градусов работает только индикация заряда и температуры. При напряжении питания 2.9 В и ниже грустно моргает один светодиод красным цветом. Ниже видео основного режим работы в проектном положении на ёлке. Осторожно, вспышки яркого света! (очень сложно телефоном снять, в живую цвета другие)
Ниже индикация заряда и температуры. При нагреве, синие светодиоды постепенно выключаются, остаются только красные. В качестве корпуса я использовал прозрачный "желток" от шоколадного яйца (покрасил внутри акрилом из баллончика).
Потребление схемы в самом затратном режиме - около 47 мА. На комплектной батарее работает чуть больше 12 часов. Для увеличения времени работы можно уменьшить яркость, увеличить время простоя, и при этом переводить контроллер в режим низкого энергопотребления. По даташиту в режиме СТОП обещают 1.7 мкА.
"Шарик" получился довольно необычным. Те, кто его видят, спрашивают что это и как это. Ещё больше удивляются, из чего он сделан. Что ещё сделать из этой платки? Если напечатать вращающееся основание, то можно получить круговой экран с механической разверткой. Схема работает от 2.4 Вольт. Можно сделать значок или кулончик на Coin Cell Challenge.
Желаю творческих успехов в наступающем Новом году!
Рассказываю про подобное в своем канале - https://t.me/modelistconstruktor [6]
Автор: avtopolet
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/mikrokontrollery/406162
Ссылки в тексте:
[1] статьёй: https://habr.com/ru/articles/783172/
[2] тут: https://controllerstech.com/interface-ws2812-with-stm32/
[3] IOsetting: https://github.com/IOsetting/py32f0-template
[4] LED Strip Effects Generator: https://adrianotiger.github.io/Neopixel-Effect-Generator/
[5] github: https://github.com/Avtopolet/PUYA_WS2812
[6] https://t.me/modelistconstruktor: https://t.me/modelistconstruktor
[7] Источник: https://habr.com/ru/articles/868216/?utm_campaign=868216&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.