Модуль YD-RP2040

Хочу розповісти про доволі дешевий модуль YD-RP2040 та показати деякі приклади роботи з ним.

Фотографії та схематика

Вид з верху:

Знизу:

 

Електричну схему модуля можна знайти тут https://github.com/initdc/YD-RP2040/blob/master/YD-2040-2022-V1.1-SCH.pdf



Відмінності від оригінального Raspberry Pi Pico

Ця плата має кілька ключових апаратних відмінностей від стандартного модуля Raspberry Pi Pico.

Основні зміни:

 - Flash-пам’ять: У модулі може бути встановлена Flash-пам’ять більшого об’єму — на 4Мб(32МБіт) або навіть 16Мб (128 Мбіт) замість 2 Мб в оригіналі. 

- Стабілізатор напруги: DC-DC step-down перетворювач замінено на дешевщий і меньше ефективний лінійний стабілізатор. Це звільнило пін GPIO23, який в оригінальному Pico використовувався для керування DC-DC. 

- RGB-світлодіод: На звільнений пін GPIO23 підключено адресний світлодіод WS2812 (Neopixel).

На відміну від оригінального Pico, ця плата має дві додаткові кнопки: 

- RESET — для апаратного перезавантаження мікроконтролера. 

- USR — користувацька кнопка, під’єднана до піна GPIO24.

Також виведено окремий пін VREF для подачі зовнішньої опорної напруги на АЦП (ADC).

На платі є дві перемички, які за замовчуванням розімкнені: 

- VREF: З’єднує пін VREF мікроконтролера з лінією живлення 3.3V. Якщо ви не плануєте використовувати зовнішню опорну напругу, цю перемичку потрібно запаяти. 

- R68: За замовчуванням пін GPIO23 не під’єднаний до RGB-світлодіода. Щоб світлодіод запрацював, цю перемичку (резистор нульового опору) необхідно запаяти.

BOOTSEL

Ця кнопка переводить мікроконтролер у режим завантаження нової прошивки через USB.

Щоб увійти в цей режим, затисніть кнопку BOOTSEL і, не відпускаючи її, натисніть RESET (або просто підключіть плату до комп’ютера). Після цього мікроконтролер з’явиться у вашій системі як звичайний флеш-накопичувач з назвою “RPI-RP2”.

Для встановлення прошивки достатньо просто скопіювати на цей накопичувач файл у форматі .uf2.

LED (GPIO25)

Як і в оригінальному Raspberry Pi Pico, на платі є вбудований світлодіод, під’єднаний до GPIO25.

Нижче наведено простий приклад коду на C++, який змушує цей світлодіод блимати:
    const uint LED = 25;
    gpio_init(LED);
    // Встановлюємо напрямок піна на вихід (GPIO_OUT)
    gpio_set_dir(LED, GPIO_OUT); 
    while (true) {
        gpio_put(LED, true);
        sleep_ms(500);
        gpio_put(LED, false);
        sleep_ms(1500);
    }

Кнопка USR (GPIO24)

При натисканні ця кнопка замикає пін GPIO24 на землю (GND).

Оскільки на платі відсутній зовнішній підтягувальний резистор до VCC, для коректної роботи кнопки необхідно програмно увімкнути внутрішній підтягувальний (pull-up) резистор мікроконтролера.

    const uint USR_BTN = 24;
    gpio_init(USR_BTN);
    // Встановлюємо напрямок піна на вхід (GPIO_IN)
    gpio_set_dir(USR_BTN, GPIO_IN);
    // Вмикаємо резистор підтяжки до VCC
    gpio_pull_up(USR_BTN);
    while (true) {
        gpio_put(LED, true);
        bool state = gpio_get(USR_BTN);
        printf("USB button state = %d\n", state);
        sleep_ms(500);
    }

Встановлення SDK під VSCode

Щоб підготувати Visual Studio Code для розробки під мікроконтролери RP2040, найзручніше встановити офіційне розширення.

  1. На бічній панелі VSCode перейдіть на вкладку «Розширення» (Extensions) або скористайтеся комбінацією клавіш Ctrl+Shift+X.
  2. У рядку пошуку введіть Raspberry Pi Pico.
  3. Знайдіть у списку розширення Raspberry Pi (зазвичай воно перше) і натисніть кнопку «Встановити» (Install).

Це розширення допоможе автоматично завантажити та налаштувати необхідний набір інструментів (SDK, компілятор).

Після встановлення розширення на бічній панелі VSCode з’явиться нова вкладка з іконкою RP2040 модуля. Через цю вкладку можна керувати проєктами, налаштовувати плату, а також компілювати та завантажувати код.

Hello World

Для початку створимо новий проєкт через вкладку Raspberry Pi. Натисніть на вкладку «New C/C++ Project».

Далі з’явиться вікно налаштувань проєкту. 

- У полі Board type оберіть вашу плату (у нашому випадку, Pico першого покоління без WiFi). 

- Активуємо UART. 

- Рекомендується одразу увімкнути опції Console over UART або Console over USB. Це дозволить виводити діагностичні повідомлення з мікроконтролера.

Що робить опція Console over USB?
Вона активує режим USB CDC, завдяки якому мікроконтролер створює віртуальний COM-порт. Ви зможете бачити повідомлення від плати безпосередньо у терміналі VSCode або будь-якій іншій моніторинговій програмі.


Код прикладу демонструє одночасну роботу з двома послідовними портами: віртуальним (через USB) та апаратним (UART1 на пінах GPIO 4 та 5).

#include 
#include "pico/stdlib.h"
#include "hardware/uart.h"

#define UART_ID uart1
#define BAUD_RATE 115200
#define UART_TX_PIN 4
#define UART_RX_PIN 5

int main()
{
    stdio_init_all();
    uart_init(UART_ID, BAUD_RATE);
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
    while (true) {
        uint32_t current_time = to_ms_since_boot(get_absolute_time());
        printf("Hello, world! Timestamp: %d ms\n", current_time);
        uart_puts(UART_ID, "Hello, UART!\n");
        sleep_ms(1000);
    }
}

Щоб скомпілювати проєкт, ви можете:

  • Натиснути на Compile Project в боковій панелі.
  • Використати комбінацію клавіш: Ctrl+Shift+B (для Windows/Linux) або Cmd+Shift+B (для macOS).

Для завантаження скомпільованої прошивки (.uf2 файл) на плату з RP2040 не потрібен окремий програматор. Це можна зробити двома способами:

1. Ручний спосіб (Drag-and-Drop)

Цей метод є універсальним і працює як звичайне копіювання файлу.

  • Переведіть плату в режим завантажувача: затисніть кнопку BOOTSEL і, не відпускаючи її, натисніть RESET (або просто підключіть плату до USB).
  • Скопіюйте файл: у вашій операційній системі з’явиться новий USB-накопичувач (диск) з назвою RPI-RP2. Просто перетягніть або скопіюйте на нього ваш .uf2 файл з папки build вашого проєкту.
  • Перезавантаження: після завершення копіювання плата автоматично перезавантажиться і почне виконувати нову програму.

2. Автоматичний спосіб (через VSCode)

Розширення для VSCode дозволяє автоматизувати процес компіляції та завантаження. - Підготуйте плату: переведіть її в режим завантажувача, як описано вище. - Запустіть завантаження: у вкладці розширення Raspberry Pi знайдіть і натисніть на Run Project (USB).

Щоб побачити результат роботи програми, потрібно підключитися до віртуального COM-порту, який плата створює через USB.

У VSCode для цього є декілька плагінів, окрім того можна використати будь який стороній монітор COM/UART. В результаті ми маємо побачити:

Hello from USB! Timestamp: 6001 ms
Hello from USB! Timestamp: 7001 ms
Hello from USB! Timestamp: 8001 ms
Hello from USB! Timestamp: 9001 ms
Hello from USB! Timestamp: 10001 ms

Приклад використання USR кнопки

Тепер модифікуємо попередній приклад. Замість постійного виведення повідомлень, ми будемо надсилати рядок у консоль лише при натисканні на додаткову кнопку USR (пін GPIO24).

Для відстеження натискання ми використаємо механізм переривань (interrupts). Це ефективний підхід, який дозволяє процесору реагувати на зовнішні події (як-от натискання кнопки), не витрачаючи ресурси на постійну перевірку її стану в головному циклі програми.

#include 
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/uart.h"

#define UART_ID      uart1
#define BAUD_RATE    115200
#define UART_TX_PIN  4
#define UART_RX_PIN  5

#define USR_BTN 24

uint32_t last_usrbtn_time = 0;
// обробник переривання
void button_callback(uint gpio, uint32_t events) {
    if (events & GPIO_IRQ_EDGE_FALL) {
        uint32_t current_time = to_ms_since_boot(get_absolute_time());
        if (current_time - last_usrbtn_time > 200) {
            printf("Hello, world! Timestamp: %d ms\n", current_time);
            last_usrbtn_time = current_time;
        }
    }
}

int main() {
    stdio_init_all();
    uart_init(UART_ID, BAUD_RATE);
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
    // інціалізація кнопки
    gpio_init(USR_BTN); 
    gpio_set_dir(USR_BTN, GPIO_IN);
    gpio_pull_up(USR_BTN);
    // активуємо переривання
    gpio_set_irq_enabled_with_callback(USR_BTN, GPIO_IRQ_EDGE_FALL, true, &button_callback);
    
    while (true) {
        // пустий цикл
        tight_loop_contents();
    }
}

Керування RGB LED (WS2812) за допомогою PIO

З заводу на цьому модулі RGB не підʼєднаний до мікроконтролера. Щоб це виправити потрібно запаяти перемичку R68 краплиною припою.

Для керування адресним світлодіодом WS2812 ми використаємо PIO (Programmable I/O) — унікальну особливість RP2040, що дозволяє створювати власні апаратні інтерфейси. Ми візьмемо готову PIO-програму з офіційних прикладів Raspberry Pi.

Завантажте файл ws2812.pio з офіційного репозиторію Raspberry Pi і розмістіть його в теці вашого проєкту.

Щоб система збірки знала про PIO-програму та підключила необхідні бібліотеки, додайте наступні рядки до файлу CMakeLists.txt:
...
# Генерує C-хедер з нашої .pio програми
pico_generate_pio_header(HelloWorld ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR})

# Додаємо бібліотеку hardware_pio до нашого проєкту
target_link_libraries(HelloWorld pico_stdlib hardware_pio)

Тепер об’єднаємо наш попередній код з перериваннями та новий функціонал для керування світлодіодом. При кожному натисканні кнопки USR колір світлодіода буде змінюватися.

Ось повний код файлу main.cpp:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/pio.h"
#include "ws2812.pio.h" // Файл, згенерований з ws2812.pio

#define UART_ID uart1
#define BAUD_RATE 115200
#define UART_TX_PIN 4
#define UART_RX_PIN 5
#define LED 25
#define USR_BTN 24
#define WS2812_PIN 23 // Пін світлодіода

// Масив кольорів у форматі 0x00GGRRBB (зелений, червоний, синій)
uint32_t ws2812Colors[] = {
    0x00800000, // Red
    0x80000000, // Green
    0x00008000, // Blue
    0x80808000, // White
    0x00000000  // Off
};
uint8_t ws2812ColorIndex = 0;
PIO ws2812pio = pio0;
int ws2812stateMachine = 0; // Номер автомату (State Machine) в PIO

uint32_t last_usrbtn_time = 0;

void button_callback_rgb(uint gpio, uint32_t events) {
    if (events & GPIO_IRQ_EDGE_FALL) {
        uint32_t current_time = to_ms_since_boot(get_absolute_time());
        if (current_time - last_usrbtn_time > 200) {
            printf("Hello, world! Timestamp: %d ms\n", current_time);
            last_usrbtn_time = current_time;
        }
        ws2812ColorIndex++;
        if (ws2812ColorIndex >= sizeof(ws2812Colors) / sizeof(ws2812Colors[0])) {
            ws2812ColorIndex = 0;
        }
        // Відправляємо новий колір у PIO-автомат
        pio_sm_put_blocking(ws2812pio, ws2812stateMachine, ws2812Colors[ws2812ColorIndex]);
    }
}

int main() {
    stdio_init_all();
    uart_init(UART_ID, BAUD_RATE);
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);

    gpio_init(LED);
    gpio_set_dir(LED, GPIO_OUT);

    gpio_init(USR_BTN); 
    gpio_set_dir(USR_BTN, GPIO_IN);
    gpio_pull_up(USR_BTN);

    gpio_set_irq_enabled_with_callback(USR_BTN, GPIO_IRQ_EDGE_FALL, true, &button_callback_rgb);

    // Знаходимо вільний автомат PIO і завантажуємо в нього нашу програму
    uint offset = pio_add_program(ws2812pio, &ws2812_program);
    // Ініціалізуємо автомат, вказавши пін, частоту та інші параметри
    ws2812_program_init(ws2812pio, ws2812stateMachine, offset, WS2812_PIN, 800000, false);

    while (true) {
        tight_loop_contents();
    }
}

Після завантаження цієї прошивки кожне натискання кнопки USR буде змінювати колір RGB-світлодіода.

Матеріали, документація та семпли

  • Офіційна документація https://www.raspberrypi.com/products/raspberry-pi-pico/
  • Офіційні приклади роботи з мікроконтролдером https://github.com/raspberrypi/pico-examples/tree/master/blink
  • Відео роботи з рідним СДК https://www.youtube.com/watch?v=3fsbwl_GGVQ
  • Схематика модуля YD2040 https://github.com/initdc/YD-RP2040/blob/master/

Коментарі

Популярні дописи з цього блогу

Огляд DC-DC Step-down Buck перетворювачів

ESP8266 модуль з OLED екраном (HW-364A)

Модуль PD тригер IP2721 на 15 та 20 вольт