Pular para o conteúdo principal

Controlando E-Paper e SD Card com XIAO nRF54LM20A Sense

O XIAO nRF54LM20A oferece suporte ao desenvolvimento com módulos periféricos da série XIAO e é totalmente compatível com todo o ecossistema de desenvolvimento dos produtos XIAO. Este artigo demonstra sua compatibilidade com o ecossistema usando como exemplo o driver de ePaper e as funções de leitura/gravação de MicroSD card da série XIAO.

dica

Este tutorial foi desenvolvido com base no sistema de build PlatformIO e no Zephyr RTOS. Se você não estiver familiarizado com a criação de um projeto para o XIAO nRF54LM20A no PlatformIO, você pode ir para Getting Sarted With Seeed Studio XIAO nRF54LM20A.

Preparação de hardware

Antes de começar, prepare um XIAO nRF54LM20A e os periféricos correspondentes.

Seeed Studio XIAO nRF54LM20A SensePlaca Controladora de ePaper para Seeed Studio XIAOeInk Monocromático 2,13"Placa de Expansão Base da Seeed Studio para XIAO

Epaer com eInk Monocromático 2,13"

Esta seção mostra como usar a ePaper Breakout Board para controlar o display eInk Monocromático 2,13" e renderizar os gráficos desejados.

Preparação de software

  1. Modifique o arquivo de device tree app.overlay e escreva a configuração de hardware para o driver do display alvo.
/ {
chosen {
zephyr,display = &ssd16xx_2in13_epaper_gdey0213b74;
};

mipi_dbi_2in13_epaper_gdey0213b74 {
compatible = "zephyr,mipi-dbi-spi";
spi-dev = <&xiao_spi>;
dc-gpios = <&xiao_d 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&xiao_d 0 GPIO_ACTIVE_LOW>;
#address-cells = <1>;
#size-cells = <0>;

ssd16xx_2in13_epaper_gdey0213b74: ssd16xxfb@0 {
compatible = "gooddisplay,gdey0213b74", "solomon,ssd1680";
mipi-max-frequency = <4000000>;
reg = <0>;
/* Adjust to an integer multiple of 8, the actual resolution is 250x122.*/
width = <256>;
height = <122>;
busy-gpios = <&xiao_d 2 GPIO_ACTIVE_HIGH>; /* D7 */

tssv = <0x80>;

full {
border-waveform = <0x05>;
};

partial {
border-waveform = <0x3c>;
};
};
};
};

&xiao_spi {
status = "okay";
cs-gpios = <&xiao_d 1 GPIO_ACTIVE_LOW>;
};
  1. Modifique prj.conf para habilitar as configurações de software.
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=16384

CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3

CONFIG_MIPI_DBI_SPI=y
CONFIG_DISPLAY=y

CONFIG_LVGL=y
CONFIG_LV_Z_MEM_POOL_SIZE=49152
CONFIG_LV_USE_MONKEY=y

CONFIG_LV_USE_LABEL=y

CONFIG_LV_USE_THEME_DEFAULT=y
CONFIG_LV_Z_VDB_SIZE=64
CONFIG_LV_COLOR_DEPTH_1=y

CONFIG_LV_FONT_MONTSERRAT_12=y
CONFIG_LV_FONT_MONTSERRAT_14=y
CONFIG_LV_FONT_MONTSERRAT_16=y
CONFIG_LV_FONT_MONTSERRAT_18=y
CONFIG_LV_FONT_MONTSERRAT_24=y

# Benchmark Demo
CONFIG_LV_USE_FONT_COMPRESSED=y
  1. Modifique o arquivo main.c e implemente a lógica e o conteúdo do display.
main.c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/display.h>
#include <lvgl.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(epaper);

int main(void)
{
// Get display device
const struct device *display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
if (!device_is_ready(display_dev)) {
LOG_ERR("Display device not ready!");
return 0;
}
LOG_INF("Display device ready.");

// Initialize LVGL
// Must be called before any LVGL object creation or operation
lv_init();

// Turn off display blanking (for ePaper, this usually triggers a full refresh to clear old content)
if (display_blanking_off(display_dev)) {
LOG_ERR("Failed to turn off display blanking!");
return 0;
}
LOG_INF("Display blanking is off. Screen should be cleared by full refresh.");

// Get the current active screen and set its background to white
// This is also an LVGL-level "clear" operation to ensure the canvas is white
lv_obj_t *scr = lv_scr_act();
lv_obj_set_style_bg_color(scr, lv_color_white(), LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, LV_STATE_DEFAULT);

// Remove screen padding and scrollbar
lv_obj_set_style_pad_all(scr, 0, LV_STATE_DEFAULT);
lv_obj_set_scrollbar_mode(scr, LV_SCROLLBAR_MODE_OFF);


// Get display width and height (for layout)
lv_disp_t *disp = lv_disp_get_default();
lv_coord_t width = lv_disp_get_hor_res(disp);
lv_coord_t height = lv_disp_get_ver_res(disp);
LOG_INF("Display width: %d, height: %d", width, height);


// Create a centered panel
lv_obj_t *panel = lv_obj_create(scr);
lv_obj_set_size(panel, 230, 50);
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);

// Set panel background to white, border to black for visibility
lv_obj_set_style_bg_color(panel, lv_color_white(), LV_STATE_DEFAULT);
lv_obj_set_style_border_color(panel, lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_border_width(panel, 2, LV_STATE_DEFAULT);
lv_obj_set_style_pad_all(panel, 10, LV_STATE_DEFAULT);


// Add text to the panel
lv_obj_t *label = lv_label_create(panel);
lv_label_set_text(label, "nRF54LM20A Hello World");

// Set text color to black for visibility on white background
lv_obj_set_style_text_color(label, lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_text_font(label, &lv_font_montserrat_16, LV_STATE_DEFAULT);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

// Add a time label at the top right
lv_obj_t *time_label = lv_label_create(scr);
lv_label_set_text(time_label, "07:21 PM");
lv_obj_set_style_text_color(time_label, lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_text_font(time_label, &lv_font_montserrat_12, LV_STATE_DEFAULT);
lv_obj_align(time_label, LV_ALIGN_TOP_RIGHT, -11, 5);

// Add a Zephyr logo at the bottom left
lv_obj_t *zephyr_label = lv_label_create(scr);
lv_label_set_text(zephyr_label, "Zephyr");
lv_obj_set_style_text_color(zephyr_label, lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_text_font(zephyr_label, &lv_font_montserrat_12, LV_STATE_DEFAULT);
lv_obj_align(zephyr_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);

// Add author label at the bottom right
lv_obj_t *author_label = lv_label_create(scr);
lv_label_set_text(author_label, "Seeed Studio");
lv_obj_set_style_text_color(author_label, lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_text_font(author_label, &lv_font_montserrat_12, LV_STATE_DEFAULT);
lv_obj_align(author_label, LV_ALIGN_BOTTOM_RIGHT, -11, -5);


// Add four squares at the top left with a for loop
lv_obj_t *squares[4];
int square_offsets = 5;
for (int i = 0; i < 4; i++) {
squares[i] = lv_obj_create(scr);
lv_obj_set_size(squares[i], 10, 10);
lv_obj_set_style_bg_color(squares[i], lv_color_white(), LV_STATE_DEFAULT);
lv_obj_set_style_border_color(squares[i], lv_color_black(), LV_STATE_DEFAULT);
lv_obj_set_style_border_width(squares[i], 1, LV_STATE_DEFAULT);
lv_obj_set_style_radius(squares[i], 0, LV_STATE_DEFAULT);
lv_obj_align(squares[i], LV_ALIGN_TOP_LEFT, square_offsets, 5);
square_offsets+=15;
}

while (1) {
lv_task_handler();
k_sleep(K_MSEC(1000)); // Lower refresh rate, suitable for ePaper
}
return 0;
}
dica

Se você precisar controlar displays de outros tamanhos e tipos, visite o link do repositório abaixo.

Resultado

Após gravar o programa e ligar o dispositivo, o texto nRF54LM20A Hello World será exibido no display eInk monocromático de 2,13".

Cartão SD

Antes de iniciar este exemplo, além da Expansion Board Base for XIAO, você também precisa de um cartão MicroSD formatado em FAT32 com capacidade não superior a 32 GB. O slot do cartão está localizado na parte de trás da Expansion Board Base for XIAO.

Preparação de software

  1. Modifique o arquivo de device tree app.overlay e adicione configurações de protocolo SPI para operações de leitura e gravação no cartão SD.

&xiao_spi {
status = "okay";
cs-gpios = <&xiao_d 2 GPIO_ACTIVE_LOW>;

sdhc0: sdhc@0 {
compatible = "zephyr,sdhc-spi-slot";
reg = <0>;
status = "okay";
mmc {
compatible = "zephyr,sdmmc-disk";
disk-name = "SD";
status = "okay";
};
spi-max-frequency = <24000000>;
};
};
  1. Habilite a configuração de software SPI em prj.conf.
CONFIG_DISK_ACCESS=y
CONFIG_LOG=y

# Enable SDHC interface
CONFIG_DISK_DRIVERS=y
CONFIG_DISK_DRIVER_SDMMC=y

# Allocate buffer on RAM for transferring chunk of data
# from Flash to SPI — increased from 8 to 64 for SD card reliability
CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=64
# SDHC driver for SD card interface
CONFIG_SDHC=y

# FAT filesystem for SD card
CONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y
CONFIG_FS_FATFS_LFN_MODE_STACK=y
CONFIG_FS_FATFS_EXFAT=y
CONFIG_FS_FATFS_MAX_LFN=255

# Increased stack and heap sizes for SD card operations
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=16384
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=32000
CONFIG_IDLE_STACK_SIZE=8192

# Shell for filesystem operations
CONFIG_SHELL=y
CONFIG_SHELL_STACK_SIZE=16000
CONFIG_FILE_SYSTEM_SHELL=y
  1. Adicione a lógica para gravar dados no cartão SD em main.c. Como o código é bastante extenso, recomenda-se consultar o código de exemplo no repositório.

Resultado

  1. Insira o cartão MicroSD no slot da Expansion Board for XIAO. Ligue o dispositivo e abra o monitor serial. O sistema lerá o tamanho do cartão SD, testará a função de montagem e, em seguida, gravará arquivos.
  • Crie uma nova pasta chamada some
  • Crie um novo arquivo chamado some.dat
  • Crie um novo arquivo chamado test.txt e escreva conteúdo nele

  1. Use um leitor de cartões para acessar o cartão SD e você encontrará os três arquivos criados com conteúdo dentro.

  1. Abra o arquivo TXT. Seu conteúdo é XIAO nRF54LM20A SD Card Test, o que verifica a gravação bem-sucedida no cartão SD.

Resumo

Com os exemplos acima, você agora deve ter um bom domínio do uso do display ePaper e do cartão MicroSD no XIAO nRF54LM20A. Sinta-se à vontade para compartilhar suas ideias com a comunidade de código aberto.

Suporte técnico e discussão sobre o produto

Obrigado por escolher nossos produtos! Estamos aqui para oferecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.

Loading Comments...