feat(i18n): English localization (phase 3)
CI / Lint e auditorias (push) Successful in 1m51s
CI / Trivy (dependências e segredos) (push) Successful in 15s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m41s

- Translate content to English across messages/en.json, data/en, lib/data/en, and public/exemplos/en
- Implement localized routing, slugs, and language negotiation with fallback to en
- Build dedicated search index for English with strict book exclusion
- Update components and pages to dynamically render localized strings and datasets
- Verify full structural parity and exact 1:1 match on Portuguese pages via comparator

Co-Authored-By: Antigravity <noreply@google.com>
This commit is contained in:
Lucas RayanandAntigravity committed 2026-11-01 14:17:13 -03:00
1 parent 22b1f26aed
commit c1bd2c7e11
61 files changed
+18182 -1225

No files matched your search

+858
View File
@@ -0,0 +1,858 @@
/**
* Base de Dados Oficial Curada: ESP Component Registry & IDF Component Manager
*
* O ESP Component Registry (https://components.espressif.com) é o ecossistema
* central de distribuição de bibliotecas modulares para o ESP-IDF v4.4+ / v5.x+.
*/
export const CATEGORIAS_COMPONENTES = [
{
id: "todos",
nome: "All Components",
icone: "Layers",
descricao: "Explore the curated catalog of libraries and drivers"
},
{
id: "ui_display",
nome: "UI, Displays & Graphics",
icone: "Monitor",
descricao: "Graphics libraries (LVGL), LCD/OLED display drivers, touch controllers and decoders"
},
{
id: "cloud_conectividade",
nome: "Cloud & Connectivity",
icone: "Cloud",
descricao: "ESP RainMaker, AWS IoT, MQTT, WebSockets, Mesh-Lite and ESP-Hosted coprocessing"
},
{
id: "audio_voz_ia",
nome: "Áudio, Voz & IA",
icone: "Brain",
descricao: "Reconhecimento de fala ESP-SR, processamento DSP, codecs, câmeras DVP e TinyML"
},
{
id: "smart_home_mesh",
nome: "Smart Home & Mesh",
icone: "Home",
descricao: "Matter SDK, pilhas Zigbee 3.0 (ZBOSS), Thread e redes ESP-NOW"
},
{
id: "drivers_perifericos",
nome: "Drivers & Sensores",
icone: "Cpu",
descricao: "Botões, encoders, LEDs RGB, Ethernet (W5500/CH390), USB nativo e sensores ambientais/IMU"
},
{
id: "bsp_placas",
nome: "BSPs (Board Support Packages)",
icone: "CircuitBoard",
descricao: "Pacotes de suporte direto para placas oficiais como ESP-BOX-3, Korvo, EYE e M5Stack"
},
{
id: "sistema_utilitarios",
nome: "Sistema & Utilitários",
icone: "Wrench",
descricao: "Sistemas de arquivos LittleFS, wrappers C++ modernos, CBOR e utilitários de rede"
}
];
export const COMPONENTES_REGISTRY = [
// ==========================================
// 1. UI, Displays & Graphics
// ==========================================
{
id: "espressif-esp_lvgl_port",
namespace: "espressif",
name: "esp_lvgl_port",
versao: "^2.4.0",
categoria: "ui_display",
oficial: true,
popular: true,
titulo: "ESP LVGL Port",
descricao: "Port oficial e thread-safe do LVGL (Light and Versatile Graphics Library) para ESP-IDF com aceleração por hardware e suporte multi-display.",
tags: ["LVGL", "GUI", "Display", "Touch", "IHM"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
dependenciasSugeridas: ["lvgl/lvgl^9.1.0"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_lvgl_port",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port",
exemploYaml: `dependencies:
espressif/esp_lvgl_port: "^2.4.0"
lvgl/lvgl: "^9.1.0"`
},
{
id: "lvgl-lvgl",
namespace: "lvgl",
name: "lvgl",
versao: "^9.1.0",
categoria: "ui_display",
oficial: false,
popular: true,
titulo: "LVGL Graphics Library Core",
descricao: "Biblioteca gráfica de código aberto em C mais popular para sistemas embarcados. Fornece widgets ricos, animações fluidas e suporte a layouts modernos.",
tags: ["LVGL 9", "Graphics", "Widgets", "GUI", "Embedded UI"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/lvgl/lvgl",
urlRepo: "https://github.com/lvgl/lvgl",
exemploYaml: `dependencies:
lvgl/lvgl: "^9.1.0"`
},
{
id: "espressif-esp32_display_panel",
namespace: "espressif",
name: "esp32_display_panel",
versao: "^0.2.0",
categoria: "ui_display",
oficial: true,
popular: true,
titulo: "ESP32 Display Panel Driver",
descricao: "Driver unificado de controladores LCD (RGB, SPI, QSPI, MIPI-DSI) e touch capacitivo desenhado especialmente para ESP32-S3 e ESP32-P4.",
tags: ["LCD", "MIPI-DSI", "QSPI", "Touch", "ST7789", "ILI9341"],
chips: ["ESP32-S3", "ESP32-P4", "ESP32-S2", "ESP32"],
urlRegistry: "https://components.espressif.com/components/espressif/esp32_display_panel",
urlRepo: "https://github.com/esp-arduino-libs/ESP32_Display_Panel",
exemploYaml: `dependencies:
espressif/esp32_display_panel: "^0.2.0"`
},
{
id: "espressif-esp_lcd_touch",
namespace: "espressif",
name: "esp_lcd_touch",
versao: "^1.1.2",
categoria: "ui_display",
oficial: true,
popular: true,
titulo: "ESP LCD Touch Framework",
descricao: "Componente central de abstração de painéis touch para telas LCD. Suporta calibragem de coordenadas, leitura de múltiplos toques e integração direta com LVGL.",
tags: ["Touchscreen", "Capacitivo", "Resistivo", "I2C Touch", "Coordenadas"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch",
exemploYaml: `dependencies:
espressif/esp_lcd_touch: "^1.1.2"`
},
{
id: "espressif-esp_lcd_touch_gt911",
namespace: "espressif",
name: "esp_lcd_touch_gt911",
versao: "^1.1.2",
categoria: "ui_display",
oficial: true,
popular: true,
titulo: "Driver Touch Capacitivo GT911",
descricao: "Driver I2C especializado para o controlador de touch capacitivo Goodix GT911, amplamente utilizado em displays de 4.3\", 5\" e 7\" para ESP32-S3 e P4.",
tags: ["GT911", "Goodix", "Touch Capacitivo", "Multitouch", "I2C"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_gt911",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_gt911",
exemploYaml: `dependencies:
espressif/esp_lcd_touch_gt911: "^1.1.2"`
},
{
id: "espressif-esp_lcd_touch_ft5x06",
namespace: "espressif",
name: "esp_lcd_touch_ft5x06",
versao: "^1.1.0",
categoria: "ui_display",
oficial: true,
popular: false,
titulo: "Driver Touch FocalTech FT5x06 / FT6x36",
descricao: "Driver de painel touch capacitivo para controladores FocalTech (FT5206, FT5316, FT5436, FT6236, FT6336) com suporte a gestos e interrupções.",
tags: ["FT6236", "FT5x06", "FocalTech", "Touch", "I2C"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2", "ESP32-C3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_ft5x06",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_ft5x06",
exemploYaml: `dependencies:
espressif/esp_lcd_touch_ft5x06: "^1.1.0"`
},
{
id: "espressif-esp_jpeg",
namespace: "espressif",
name: "esp_jpeg",
versao: "^1.3.0",
categoria: "ui_display",
oficial: true,
popular: false,
titulo: "ESP JPEG Decoder (TJpgDec)",
descricao: "Decodificador e codificador JPEG de alta velocidade com otimizações SIMD em Assembly para exibir imagens e streams de câmeras em displays sem atrasos.",
tags: ["JPEG", "TJpgDec", "Câmera", "Imagem", "SIMD"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_jpeg",
urlRepo: "https://github.com/espressif/esp-jpeg",
exemploYaml: `dependencies:
espressif/esp_jpeg: "^1.3.0"`
},
// ==========================================
// 2. Cloud & Connectivity
// ==========================================
{
id: "espressif-esp_rainmaker",
namespace: "espressif",
name: "esp_rainmaker",
versao: "^1.4.0",
categoria: "cloud_conectividade",
oficial: true,
popular: true,
titulo: "ESP RainMaker Agent",
descricao: "Agente oficial de firmware para a plataforma de nuvem AIoT ESP RainMaker. Habilita controle por app móvel, Alexa, Google Home e OTA.",
tags: ["RainMaker", "AWS Cloud", "App iOS/Android", "Alexa", "Google Home", "OTA"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_rainmaker",
urlRepo: "https://github.com/espressif/esp-rainmaker",
exemploYaml: `dependencies:
espressif/esp_rainmaker: "^1.4.0"`
},
{
id: "espressif-mesh_lite",
namespace: "espressif",
name: "mesh_lite",
versao: "^1.2.0",
categoria: "cloud_conectividade",
oficial: true,
popular: true,
titulo: "ESP Mesh-Lite Network Stack",
descricao: "Rede em malha Wi-Fi leve onde cada nó possui conectividade IP independente, permitindo comunicação direta na rede local e acesso à nuvem com múltiplos saltos.",
tags: ["Mesh", "Wi-Fi Mesh", "Rede em Malha", "IoT Distribuída", "IP Layer"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/mesh_lite",
urlRepo: "https://github.com/espressif/esp-mesh-lite",
exemploYaml: `dependencies:
espressif/mesh_lite: "^1.2.0"`
},
{
id: "espressif-esp_modbus",
namespace: "espressif",
name: "esp_modbus",
versao: "^1.0.15",
categoria: "cloud_conectividade",
oficial: true,
popular: true,
titulo: "ESP-Modbus Industrial Stack",
descricao: "Implementação completa da pilha industrial Modbus (Master/Slave) suportando interfaces RS-485 (RTU/ASCII) e Ethernet/Wi-Fi (Modbus TCP).",
tags: ["Modbus", "RS-485", "Modbus TCP", "Automação Industrial", "PLC"],
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_modbus",
urlRepo: "https://github.com/espressif/esp-modbus",
exemploYaml: `dependencies:
espressif/esp_modbus: "^1.0.15"`
},
{
id: "espressif-net_connect",
namespace: "espressif",
name: "net_connect",
versao: "^1.0.0",
categoria: "cloud_conectividade",
oficial: true,
popular: false,
titulo: "Unified Network Connect",
descricao: "Componente unificado de gerenciamento de conexão de rede, alternando e inicializando de forma transparente Wi-Fi, Ethernet, Thread ou PPP móvel.",
tags: ["Network", "Wi-Fi", "Ethernet", "Fallback", "Conexão Automática"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/net_connect",
urlRepo: "https://github.com/espressif/esp-idf/tree/master/components",
exemploYaml: `dependencies:
espressif/net_connect: "^1.0.0"`
},
{
id: "espressif-esp_hosted",
namespace: "espressif",
name: "esp_hosted",
versao: "^0.0.10",
categoria: "cloud_conectividade",
oficial: true,
popular: false,
titulo: "ESP-Hosted Coprocessor",
descricao: "Transforma o ESP32 em um coprocessador de comunicação sem fio (Wi-Fi + BLE) para hosts Linux (Raspberry Pi, i.MX) ou microcontroladores via SPI/SDIO/UART.",
tags: ["Coprocessador", "SDIO", "SPI", "Linux Wi-Fi", "Raspberry Pi"],
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_hosted",
urlRepo: "https://github.com/espressif/esp-hosted",
exemploYaml: `dependencies:
espressif/esp_hosted: "^0.0.10"`
},
{
id: "espressif-esp-now",
namespace: "espressif",
name: "esp-now",
versao: "^2.5.0",
categoria: "cloud_conectividade",
oficial: true,
popular: true,
titulo: "ESP-NOW Enhanced & Provisioning",
descricao: "Extensão com recursos avançados de emparelhamento por controle remoto, segurança AES-128 e controle de múltiplos dispositivos com protocolo ESP-NOW.",
tags: ["ESP-NOW", "Sem Fio", "Baixa Latência", "Broadcast", "Controle Remoto"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-now",
urlRepo: "https://github.com/espressif/esp-now",
exemploYaml: `dependencies:
espressif/esp-now: "^2.5.0"`
},
// ==========================================
// 3. Áudio, Voz & IA
// ==========================================
{
id: "espressif-esp-sr",
namespace: "espressif",
name: "esp-sr",
versao: "^1.5.0",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "ESP-SR Speech Recognition",
descricao: "Framework de reconhecimento de fala 100% offline com WakeNet (palavra de ativação), MultiNet (comandos locais) e algoritmos acústicos AFE.",
tags: ["Voz", "WakeNet", "MultiNet", "Reconhecimento de Fala", "Offline", "AEC"],
chips: ["ESP32-S3", "ESP32-P4", "ESP32"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-sr",
urlRepo: "https://github.com/espressif/esp-sr",
exemploYaml: `dependencies:
espressif/esp-sr: "^1.5.0"`
},
{
id: "espressif-esp_codec_dev",
namespace: "espressif",
name: "esp_codec_dev",
versao: "^1.3.0",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "ESP Audio Codec Device HAL",
descricao: "Camada unificada de abstração de codecs de áudio I2S/I2C (ES8311, ES8388, ES7210, ES7243, TAS5805M) para entrada e saída de som estéreo.",
tags: ["Audio Codec", "I2S", "ES8311", "ES8388", "Microfone DAC"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_codec_dev",
urlRepo: "https://github.com/espressif/esp-codec-dev",
exemploYaml: `dependencies:
espressif/esp_codec_dev: "^1.3.0"`
},
{
id: "espressif-es8311",
namespace: "espressif",
name: "es8311",
versao: "^1.0.0",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "Driver Codec de Áudio ES8311",
descricao: "Driver dedicado de baixo consumo para o codec Everest ES8311 (DAC mono + ADC de microfone) presente no ESP32-S3-BOX e placas de IoT.",
tags: ["ES8311", "Áudio", "DAC", "Microfone", "I2S"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3"],
urlRegistry: "https://components.espressif.com/components/espressif/es8311",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/es8311",
exemploYaml: `dependencies:
espressif/es8311: "^1.0.0"`
},
{
id: "espressif-esp32-camera",
namespace: "espressif",
name: "esp32-camera",
versao: "^2.0.12",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "ESP32 Camera Driver",
descricao: "Driver oficial de câmeras CMOS (OV2640, OV3660, OV5640, OV7670, GC0308) com suporte a DMA, DMA-2D, captura JPEG e streaming MJPEG por HTTP/RTSP.",
tags: ["Câmera", "OV2640", "OV5640", "DVP", "MIPI-CSI", "Vídeo"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2"],
urlRegistry: "https://components.espressif.com/components/espressif/esp32-camera",
urlRepo: "https://github.com/espressif/esp32-camera",
exemploYaml: `dependencies:
espressif/esp32-camera: "^2.0.12"`
},
{
id: "espressif-esp-dsp",
namespace: "espressif",
name: "esp-dsp",
versao: "^1.5.1",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "ESP-DSP Signal Processing",
descricao: "Biblioteca oficial de processamento digital de sinais para SoCs ESP32 (FFT, filtros digitais FIR/IIR, matrizes e álgebra linear acelerada).",
tags: ["DSP", "FFT", "Filtros", "Matemática", "SIMD", "Assembly"],
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-dsp",
urlRepo: "https://github.com/espressif/esp-dsp",
exemploYaml: `dependencies:
espressif/esp-dsp: "^1.5.1"`
},
{
id: "espressif-esp-nn",
namespace: "espressif",
name: "esp-nn",
versao: "^1.2.0",
categoria: "audio_voz_ia",
oficial: true,
popular: true,
titulo: "ESP-NN Neural Network Kernels",
descricao: "Kernels otimizados em assembly vetorial para aceleração de redes neurais e modelos TensorFlow Lite Micro em chips ESP32.",
tags: ["TinyML", "TensorFlow Lite", "Redes Neurais", "Inferência", "Edge AI"],
chips: ["ESP32-S3", "ESP32-P4", "ESP32"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-nn",
urlRepo: "https://github.com/espressif/esp-nn",
exemploYaml: `dependencies:
espressif/esp-nn: "^1.2.0"`
},
// ==========================================
// 4. Smart Home & Mesh
// ==========================================
{
id: "espressif-esp-matter",
namespace: "espressif",
name: "esp-matter",
versao: "^1.3.0",
categoria: "smart_home_mesh",
oficial: true,
popular: true,
titulo: "ESP Matter SDK",
descricao: "SDK oficial para criar dispositivos interoperáveis com Apple Home, Google Home, Alexa e Home Assistant sobre Wi-Fi e Thread.",
tags: ["Matter", "Smart Home", "Apple HomeKit", "Google Home", "Thread", "CHIP"],
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-matter",
urlRepo: "https://github.com/espressif/esp-matter",
exemploYaml: `dependencies:
espressif/esp-matter: "^1.3.0"`
},
{
id: "espressif-esp-zigbee-lib",
namespace: "espressif",
name: "esp-zigbee-lib",
versao: "^1.6.0",
categoria: "smart_home_mesh",
oficial: true,
popular: true,
titulo: "ESP Zigbee 3.0 Library",
descricao: "Pilha certificada Zigbee 3.0 (ZBOSS) para criação de nós Coordenadores, Roteadores e Dispositivos Finais de baixo consumo em chips 802.15.4.",
tags: ["Zigbee 3.0", "ZBOSS", "802.15.4", "Home Automation", "Bateria"],
chips: ["ESP32-H2", "ESP32-C6"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-zigbee-lib",
urlRepo: "https://github.com/espressif/esp-zigbee-sdk",
exemploYaml: `dependencies:
espressif/esp-zigbee-lib: "^1.6.0"`
},
{
id: "espressif-esp_rcp_update",
namespace: "espressif",
name: "esp_rcp_update",
versao: "^1.0.0",
categoria: "smart_home_mesh",
oficial: true,
popular: false,
titulo: "ESP RCP Thread/Zigbee Gateway",
descricao: "Componente para atualização de coprocessador de rádio (RCP) 802.15.4 para construção de Thread Border Routers e gateways Zigbee multiprotocolo.",
tags: ["Thread Border Router", "OpenThread", "RCP", "Zigbee Gateway"],
chips: ["ESP32-H2", "ESP32-C6", "ESP32-S3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_rcp_update",
urlRepo: "https://github.com/espressif/esp-thread-br",
exemploYaml: `dependencies:
espressif/esp_rcp_update: "^1.0.0"`
},
// ==========================================
// 5. Drivers & Sensores
// ==========================================
{
id: "espressif-led_indicator",
namespace: "espressif",
name: "led_indicator",
versao: "^1.2.0",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "LED Indicator Driver",
descricao: "Driver inteligente para controle de padrões de iluminação de LED (piscar rápido, respiração/fade, códigos de erro e RGB) sem travar o loop principal.",
tags: ["LED", "PWM", "RGB", "Blink", "Feedback Visual"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/led_indicator",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/led/led_indicator",
exemploYaml: `dependencies:
espressif/led_indicator: "^1.2.0"`
},
{
id: "espressif-button",
namespace: "espressif",
name: "button",
versao: "^3.4.0",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "IoT Button Handler (iot_button)",
descricao: "Gerenciador completo de botões com debounce, eventos de clique único, duplo, múltiplo, pressionamento longo e matrizes de teclado.",
tags: ["Botão", "Debounce", "Long Press", "Double Click", "GPIO"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/button",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/button",
exemploYaml: `dependencies:
espressif/button: "^3.4.0"`
},
{
id: "espressif-led_strip",
namespace: "espressif",
name: "led_strip",
versao: "^2.5.4",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "Addressable LED Strip (WS2812/SK6812)",
descricao: "Driver de alto desempenho para fitas e matrizes de LED endereçáveis WS2812, WS2813 e SK6812 usando periféricos RMT ou SPI.",
tags: ["WS2812B", "Neopixel", "SK6812", "RMT", "Fita de LED", "RGB"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/led_strip",
urlRepo: "https://github.com/espressif/idf-extra-components/tree/master/led_strip",
exemploYaml: `dependencies:
espressif/led_strip: "^2.5.4"`
},
{
id: "espressif-esp_tinyusb",
namespace: "espressif",
name: "esp_tinyusb",
versao: "^1.5.0",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "ESP Native USB Device (TinyUSB)",
descricao: "Extensão oficial do TinyUSB para ESP32-S2, ESP32-S3 e ESP32-P4, permitindo emular portas seriais USB CDC, Teclado/Mouse HID, Pen Drive MSC, DFU e WebUSB.",
tags: ["USB Nativo", "TinyUSB", "USB CDC", "USB HID", "WebUSB", "MSC"],
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_tinyusb",
urlRepo: "https://github.com/espressif/esp-tinyusb",
exemploYaml: `dependencies:
espressif/esp_tinyusb: "^1.5.0"`
},
{
id: "espressif-w5500",
namespace: "espressif",
name: "w5500",
versao: "^1.2.0",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "WIZnet W5500 SPI Ethernet Driver",
descricao: "Driver oficial para o chip Ethernet WIZnet W5500 via barramento SPI, integrando perfeitamente a interface física à pilha TCP/IP (lwIP) nativa do ESP-IDF.",
tags: ["W5500", "Ethernet", "SPI Ethernet", "RJ45", "lwIP", "Rede Cabeada"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/w5500",
urlRepo: "https://github.com/espressif/esp-eth-drivers/tree/master/w5500",
exemploYaml: `dependencies:
espressif/w5500: "^1.2.0"`
},
{
id: "espressif-ch390",
namespace: "espressif",
name: "ch390",
versao: "^1.0.0",
categoria: "drivers_perifericos",
oficial: true,
popular: false,
titulo: "CH390 SPI Ethernet Driver",
descricao: "Driver SPI Ethernet 10/100M para o controlador WCH CH390, ideal para adicionar porta de rede RJ45 econômica em placas com ESP32-C3, S3 ou P4.",
tags: ["CH390", "Ethernet", "WCH", "SPI Ethernet", "RJ45"],
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/ch390",
urlRepo: "https://github.com/espressif/esp-eth-drivers/tree/master/ch390",
exemploYaml: `dependencies:
espressif/ch390: "^1.0.0"`
},
{
id: "espressif-usb_host_uvc",
namespace: "espressif",
name: "usb_host_uvc",
versao: "^1.0.4",
categoria: "drivers_perifericos",
oficial: true,
popular: false,
titulo: "USB Host UVC (Webcam Driver)",
descricao: "Driver USB Host para conectar webcams USB UVC padrão diretamente na porta USB nativa do ESP32-S2, ESP32-S3 ou ESP32-P4.",
tags: ["USB Host", "UVC", "Webcam", "Câmera USB", "Vídeo"],
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/usb_host_uvc",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/usb/usb_host_uvc",
exemploYaml: `dependencies:
espressif/usb_host_uvc: "^1.0.4"`
},
{
id: "espressif-sensor_hub",
namespace: "espressif",
name: "sensor_hub",
versao: "^1.0.0",
categoria: "drivers_perifericos",
oficial: true,
popular: false,
titulo: "ESP Sensor Hub Manager",
descricao: "Framework unificado para gerenciamento de sensores heterogêneos (I2C/SPI) com amostragem periódica, fusão de dados e disparo por eventos/interrupções.",
tags: ["Sensores", "Sensor Hub", "I2C", "Eventos", "Coleta Periódica"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/sensor_hub",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/sensor_hub",
exemploYaml: `dependencies:
espressif/sensor_hub: "^1.0.0"`
},
{
id: "espressif-bmi270_sensor",
namespace: "espressif",
name: "bmi270_sensor",
versao: "^1.0.1",
categoria: "drivers_perifericos",
oficial: true,
popular: false,
titulo: "Driver Sensor IMU Bosch BMI270",
descricao: "Driver oficial para o sensor inercial IMU de 6 eixos Bosch BMI270 (Acelerômetro + Giroscópio) com detecção de gestos de movimento e passos.",
tags: ["BMI270", "IMU", "Acelerômetro", "Giroscópio", "Bosch", "Gestos"],
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/bmi270_sensor",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/imu/bmi270",
exemploYaml: `dependencies:
espressif/bmi270_sensor: "^1.0.1"`
},
{
id: "espressif-ds18b20",
namespace: "espressif",
name: "ds18b20",
versao: "^1.0.0",
categoria: "drivers_perifericos",
oficial: true,
popular: true,
titulo: "Driver Sensor de Temperatura DS18B20",
descricao: "Driver digital para sensor de temperatura 1-Wire Dallas/Maxim DS18B20 com suporte a múltiplos sensores no mesmo pino GPIO via barramento RMT.",
tags: ["DS18B20", "1-Wire", "Temperatura", "Sensor", "Dallas"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/ds18b20",
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/temperature/ds18b20",
exemploYaml: `dependencies:
espressif/ds18b20: "^1.0.0"`
},
{
id: "esp-idf-lib-scd4x",
namespace: "esp-idf-lib",
name: "scd4x",
versao: "^1.0.0",
categoria: "drivers_perifericos",
oficial: false,
popular: true,
titulo: "Driver Sensor CO2 Sensirion SCD40/SCD41",
descricao: "Driver I2C de alta precisão para sensores fotoacústicos de CO2, temperatura e umidade relativa Sensirion SCD40 e SCD41 com auto-calibragem.",
tags: ["SCD40", "SCD41", "Sensirion", "CO2", "Qualidade do Ar", "I2C"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/esp-idf-lib/scd4x",
urlRepo: "https://github.com/UncleRus/esp-idf-lib/tree/master/components/scd4x",
exemploYaml: `dependencies:
esp-idf-lib/scd4x: "^1.0.0"`
},
// ==========================================
// 6. BSPs (Board Support Packages)
// ==========================================
{
id: "espressif-esp-box-3",
namespace: "espressif",
name: "esp-box-3",
versao: "^1.2.0",
categoria: "bsp_placas",
oficial: true,
popular: true,
titulo: "BSP ESP32-S3-BOX-3",
descricao: "Pacote de suporte completo para a placa de desenvolvimento de IA ESP32-S3-BOX-3, inicializando tela touch, codec de áudio, microfones duplos, sensor de movimento e LEDs com uma única função.",
tags: ["BSP", "ESP-BOX-3", "Display Touch", "Microfone", "Áudio ES8311", "I2C/SPI"],
chips: ["ESP32-S3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-box-3",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp-box-3",
exemploYaml: `dependencies:
espressif/esp-box-3: "^1.2.0"`
},
{
id: "espressif-esp32_s3_korvo_2",
namespace: "espressif",
name: "esp32_s3_korvo_2",
versao: "^1.1.0",
categoria: "bsp_placas",
oficial: true,
popular: false,
titulo: "BSP ESP32-S3-Korvo-2",
descricao: "Board Support Package para o kit de desenvolvimento de áudio e reconhecimento de voz ESP32-S3-Korvo-2, com suporte a microfones I2S e botões de toque.",
tags: ["BSP", "Korvo", "Áudio", "Array de Microfones", "ESP-SR"],
chips: ["ESP32-S3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_korvo_2",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_korvo_2",
exemploYaml: `dependencies:
espressif/esp32_s3_korvo_2: "^1.1.0"`
},
{
id: "espressif-esp32_s3_eye",
namespace: "espressif",
name: "esp32_s3_eye",
versao: "^1.1.0",
categoria: "bsp_placas",
oficial: true,
popular: true,
titulo: "BSP ESP32-S3-EYE",
descricao: "Board Support Package para a placa de visão computacional oficial ESP32-S3-EYE, configurando câmera OV2640, display LCD SPI redondo e microfone digital.",
tags: ["BSP", "ESP32-S3-EYE", "Câmera", "Visão Computacional", "Display"],
chips: ["ESP32-S3"],
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_eye",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_eye",
exemploYaml: `dependencies:
espressif/esp32_s3_eye: "^1.1.0"`
},
{
id: "espressif-m5stack_core_s3",
namespace: "espressif",
name: "m5stack_core_s3",
versao: "^1.0.0",
categoria: "bsp_placas",
oficial: true,
popular: true,
titulo: "BSP M5Stack CoreS3",
descricao: "Board Support Package oficial para o dispositivo M5Stack CoreS3, inicializando tela sensível ao toque, PMIC AXP2101, câmera GC0308 e alto-falante I2S.",
tags: ["BSP", "M5Stack", "CoreS3", "Display ILI9342C", "AXP2101", "Câmera"],
chips: ["ESP32-S3"],
urlRegistry: "https://components.espressif.com/components/espressif/m5stack_core_s3",
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3",
exemploYaml: `dependencies:
espressif/m5stack_core_s3: "^1.0.0"`
},
{
id: "waveshare-esp32_p4_wifi6_touch_lcd_7b",
namespace: "waveshare",
name: "esp32_p4_wifi6_touch_lcd_7b",
versao: "^1.0.0",
categoria: "bsp_placas",
oficial: false,
popular: true,
titulo: "BSP Waveshare ESP32-P4 Touch LCD 7\"",
descricao: "Pacote de suporte para a placa de alta performance Waveshare ESP32-P4 com tela touch capacitiva de 7 polegadas (MIPI-DSI 1024x600) e coprocessador Wi-Fi 6.",
tags: ["BSP", "ESP32-P4", "MIPI-DSI", "Waveshare", "Tela 7 Polegadas", "Touch"],
chips: ["ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/waveshare/esp32_p4_wifi6_touch_lcd_7b",
urlRepo: "https://github.com/waveshare/ESP32-P4-WiFi6-Touch-LCD-7B",
exemploYaml: `dependencies:
waveshare/esp32_p4_wifi6_touch_lcd_7b: "^1.0.0"`
},
// ==========================================
// 7. Sistema & Utilitários
// ==========================================
{
id: "joltwallet-littlefs",
namespace: "joltwallet",
name: "littlefs",
versao: "^1.14.8",
categoria: "sistema_utilitarios",
oficial: false,
popular: true,
titulo: "LittleFS Filesystem for ESP-IDF",
descricao: "Port robusto do sistema de arquivos LittleFS para memória Flash SPI com wear-leveling dinâmico e proteção contra corrupção por queda de energia.",
tags: ["LittleFS", "Flash", "Filesystem", "Wear Leveling", "NVS"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/joltwallet/littlefs",
urlRepo: "https://github.com/joltwallet/esp_littlefs",
exemploYaml: `dependencies:
joltwallet/littlefs: "^1.14.8"`
},
{
id: "espressif-esp-idf-cxx",
namespace: "espressif",
name: "esp-idf-cxx",
versao: "^1.2.0",
categoria: "sistema_utilitarios",
oficial: true,
popular: true,
titulo: "ESP-IDF C++ Idiomatic Wrappers",
descricao: "Conjunto de classes e wrappers C++ modernos (C++17/C++20/C++23) com semântica RAII para GPIOs, Wi-Fi, timers, filas FreeRTOS e semáforos.",
tags: ["C++", "C++20", "RAII", "Modern C++", "Object Oriented", "FreeRTOS"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/esp-idf-cxx",
urlRepo: "https://github.com/espressif/esp-idf-cxx",
exemploYaml: `dependencies:
espressif/esp-idf-cxx: "^1.2.0"`
},
{
id: "espressif-cbor",
namespace: "espressif",
name: "cbor",
versao: "^0.6.0",
categoria: "sistema_utilitarios",
oficial: true,
popular: false,
titulo: "TinyCBOR Serialization",
descricao: "Biblioteca ultraleve para serialização e deserialização de dados em formato binário CBOR (Concise Binary Object Representation).",
tags: ["CBOR", "Serialização", "Binário", "IoT Protocol", "JSON Compacto"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/cbor",
urlRepo: "https://github.com/espressif/tinycbor",
exemploYaml: `dependencies:
espressif/cbor: "^0.6.0"`
},
{
id: "espressif-esp_websocket_client",
namespace: "espressif",
name: "esp_websocket_client",
versao: "^1.2.4",
categoria: "sistema_utilitarios",
oficial: true,
popular: true,
titulo: "ESP WebSocket Client",
descricao: "Cliente WebSocket bidirecional em tempo real com suporte a TLS/SSL (WSS), reconexão automática, sub-protocolos e ping/pong de heartbeat.",
tags: ["WebSocket", "WSS", "TLS", "Tempo Real", "Sockets", "JSON"],
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
urlRegistry: "https://components.espressif.com/components/espressif/esp_websocket_client",
urlRepo: "https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client",
exemploYaml: `dependencies:
espressif/esp_websocket_client: "^1.2.4"`
}
];
export const GUIA_COMPONENT_MANAGER = {
titulo: "Como Usar o ESP Component Registry no ESP-IDF",
resumo: "A partir do ESP-IDF v4.4 e consolidado no v5.x+, a Espressif adotou a arquitetura de pacotes modulares gerenciada pelo IDF Component Manager. Esqueça submódulos git complexos: agora basta declarar as bibliotecas no arquivo de manifesto idf_component.yml do seu projeto.",
vantagens: [
{
titulo: "Instalação Automática e Desacoplada",
descricao: "O compilador baixa, compila e gerencia as versões das bibliotecas automaticamente durante o 'idf.py build' ou 'idf.py reconfigure'."
},
{
titulo: "Versionamento Semântico Rigoroso",
descricao: "Controle exatamente quando atualizar com operadores de versão (^ para compatibilidade minor, ~ para patches ou versões exatas fixas)."
},
{
titulo: "Projetos mais Leves e Limpos",
descricao: "O repositório do seu projeto fica limpo, sem carregar código de terceiros dentro do histórico do Git."
},
{
titulo: "Compartilhamento Corporativo ou Comunitário",
descricao: "Publique seus próprios componentes na nuvem pública da Espressif ou em registros privados locais da sua empresa."
}
],
comandosCli: [
{
comando: 'idf.py add-dependency "namespace/componente^versao"',
exemplo: 'idf.py add-dependency "espressif/esp_lvgl_port^2.4.0"',
explicacao: "Cria ou atualiza automaticamente o arquivo 'main/idf_component.yml' adicionando a dependência informada."
},
{
comando: "idf.py reconfigure",
exemplo: "idf.py reconfigure",
explicacao: "Força o CMake e o Component Manager a resolver novamente a árvore de dependências e baixar pacotes pendentes."
},
{
comando: "compote component upload --name <component_name> --namespace <sua_org>",
exemplo: "compote component upload --name meu_driver_sensor --namespace minhadiv",
explicacao: "Publica seu componente de código aberto ou proprietário no ESP Component Registry usando a ferramenta oficial Compote CLI."
}
],
sintaxeManifesto: `# Estrutura típica do arquivo: main/idf_component.yml
dependencies:
# Baixa do registro oficial da Espressif
espressif/esp_lvgl_port: "^2.4.0"
espressif/button: "~3.4.0"
# Versão exata
espressif/led_indicator: "1.2.0"
# Dependência da comunidade
joltwallet/littlefs: "^1.14.8"
# Dependência local no seu disco (opcional)
# meu_driver_local:
# path: "../../components/meu_driver"`
};
+722
View File
@@ -0,0 +1,722 @@
/**
* Structured Database for ESP32 Troubleshooting, Common Errors, and Diagnostics Guide.
* Covers 6 technical categories with root causes, best practices vs workarounds, and code examples
* in Arduino C++, ESP-IDF (C), and MicroPython.
*/
export const categoriasDiagnostico = [
{
id: "alimentacao",
nome: "Power & Hardware",
icone: "Zap",
cor: "amber",
descricao: "Voltage drops caused by Wi-Fi/BLE RF spikes, conflicting strapping pins, electromagnetic noise, and LDO issues.",
},
{
id: "cpu-panics",
nome: "CPU Panics & Guru Meditation",
icone: "Cpu",
cor: "red",
descricao: "Null pointers, memory access violations (Load/StoreProhibited), illegal instructions, and cache panics in ISRs.",
},
{
id: "freertos",
nome: "FreeRTOS & Multitasking",
icone: "Layers",
cor: "purple",
descricao: "Task Watchdog (TWDT), Interrupt Watchdog (IWDT), Stack Overflow, and scheduler deadlocks.",
},
{
id: "memoria",
nome: "Memory, Heap & PSRAM",
icone: "Activity",
cor: "blue",
descricao: "Heap fragmentation, Memory Leaks, DMA allocations, and PSRAM limitations.",
},
{
id: "boot-flash",
nome: "Bootloader & Flashing",
icone: "Terminal",
cor: "emerald",
descricao: "Serial communication failures (DTR/RTS), SPI Flash read errors, clock mismatch, and invalid partitions.",
},
{
id: "conectividade",
nome: "Connectivity & Protocols",
icone: "Wifi",
cor: "cyan",
descricao: "Wi-Fi Beacon Timeout, TLS/HTTPS handshake failures due to lack of SNTP clock, and signal instability.",
},
];
export const sintomasRapidos = [
{ id: "bootloop", rotulo: "🔄 Bootloop (Crash loop)", categoria: "todos" },
{ id: "wifi-crash", rotulo: "📶 Crashes when enabling Wi-Fi/BLE", categoria: "alimentacao" },
{ id: "upload-fail", rotulo: "🔌 Upload failed (Flashing error)", categoria: "boot-flash" },
{ id: "random-freeze", rotulo: "⏱️ Freezes after minutes/hours", categoria: "memoria" },
{ id: "null-pointer", rotulo: "💥 Guru Meditation (Crash)", categoria: "cpu-panics" },
{ id: "wdt-reset", rotulo: "🐕 Watchdog Triggered", categoria: "freertos" },
{ id: "tls-fail", rotulo: "🔒 HTTPS / SSL failure", categoria: "conectividade" },
];
export const errosCatalogo = [
{
id: "brownout-reset",
titulo: "Brownout Detector Reset (Voltage Drop)",
categoria: "alimentacao",
sintomas: ["bootloop", "wifi-crash"],
gravidade: "Alta",
logSerial: "Brownout detector was triggered\n\nrst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)",
resumo: "ESP32 supply voltage dropped below the safe operating threshold (approximately 2.8V ~ 2.43V).",
causaRaiz:
"When Wi-Fi or BLE radios initialize, the power amplifier (PA) draws instantaneous current spikes exceeding 500 mA within less than 1 ms. If the power supply, long/thin USB cables, breadboard rails, or LDO regulator cannot supply transient current with low impedance, the voltage on the 3V3 rail collapses momentarily, triggering the internal Brownout comparator circuit to prevent Flash corruption and undefined logic states.",
gambiarra: {
titulo: "Disabling Brownout detector in software",
descricao: "Calling WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) to suppress the error in code.",
consequencia: "Extremely dangerous: the ESP32 continues executing instructions under undervoltage, corrupting SPI Flash memory, locking peripheral registers, and causing erratic field failures without notice.",
},
solucaoEngenharia: {
titulo: "Proper hardware sizing and decoupling capacitors",
passos: [
"Add a 10 µF to 100 µF low-ESR tantalum or ceramic capacitor in parallel with a 100 nF ceramic capacitor as close as possible to the 3V3 and GND pins of the ESP32.",
"Use LDO regulators rated for at least 600 mA to 1 A peaks with excellent transient response (e.g. AP2112K, ME6211, TPS73733, or robust XC6206). Avoid low-grade AMS1117 clones.",
"Avoid powering the ESP32 through long breadboard power rails with thin jumper wires when Wi-Fi transmits at full power.",
],
},
codigoArduino: `// Do NOT disable the Brownout detector! If you need to reduce current peaks in bench testing:
#include <WiFi.h>
void setup() {
Serial.begin(115200);
// Optional: Slightly reducing maximum Wi-Fi TX power from 20dBm to 17dBm cuts current spikes by ~20%
WiFi.setTxPower(WIFI_POWER_17dBm);
WiFi.begin("SSID", "PASSWORD");
}`,
codigoEspIdf: `// ESP-IDF configuration:
#include "esp_wifi.h"
#include "esp_log.h"
void app_main(void) {
// In menuconfig: Component config -> ESP32-specific -> Hardware Brownout Reset (Keep ENABLED)
// To mitigate transient peaks in power-constrained designs:
esp_wifi_set_max_tx_power(68); // 68 = 17dBm (units of 0.25dBm)
}`,
codigoMicroPython: `# Safe Wi-Fi connection in MicroPython with supply stabilization:
import network
import time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Wait for supply rails to settle before turning on transmitter
time.sleep_ms(200)
wlan.connect("SSID", "PASSWORD")
attempts = 0
while not wlan.isconnected() and attempts < 30:
time.sleep_ms(200)
attempts += 1
if wlan.isconnected():
print("Wi-Fi Connected! IP:", wlan.ifconfig()[0])
else:
print("[ERROR] Failed to connect Wi-Fi")`,
dicaPro: "If designing custom PCBs, route a solid ground plane directly beneath the module and keep 3.3V power traces at 0.5 mm to 1 mm minimum width to prevent resistive voltage drop (IR drop) during RF bursts.",
},
{
id: "strapping-pins",
titulo: "Strapping Pin Conflict at Boot",
categoria: "alimentacao",
sintomas: ["bootloop", "upload-fail"],
gravidade: "Crítica",
logSerial: "rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)\nflash read err, 1000\nwaiting for download",
resumo: "The ESP32 fails to boot firmware from Flash or enters download mode unintentionally because a strapping pin was pulled to an incorrect logic level during reset.",
causaRaiz:
"The instant EN/CHIP_PU rises (Power-On Reset), the CPU latches the electrical logic level on specific strapping pins to configure Flash voltage (1.8V vs 3.3V), boot mode (UART Download vs SPI Flash Boot), and clock output. Connecting external sensors, relays, or LEDs with pull-up/pull-down resistors to these pins forces invalid strapping states, halting the bootloader.",
gambiarra: {
titulo: "Adding delays in code or manually disconnecting cables at each boot",
descricao: "Attempting to fix the problem in setup() or manually unplugging wires before every reset.",
consequencia: "Useless: Strapping pins are sampled by silicon hardware before the CPU executes a single line of application code or the second-stage bootloader.",
},
solucaoEngenharia: {
titulo: "Safe GPIO allocation and reset isolation",
passos: [
"ESP32 (Classic): Avoid using GPIO 0 (Boot mode), GPIO 2 (must be LOW or floating during flashing), GPIO 12 (selects Flash voltage: pulling HIGH at reset burns/locks 3.3V flash), and GPIO 15 (suppresses boot log output if LOW).",
"ESP32-C3: Avoid pulling GPIO 8 LOW or GPIO 9 LOW during reset.",
"ESP32-S3: Watch GPIO 0, GPIO 45 (VDD_SPI voltage level), and GPIO 46.",
"If these pins must interface with peripherals, use transistors or digital bus switches to isolate them until the EN pin has completely risen and stabilized.",
],
},
codigoArduino: `// SAFE PINOUT RECOMMENDATIONS (ESP32 Classic):
// Preferred pins for I2C / SPI / General Sensors:
// SDA: GPIO 21 | SCL: GPIO 22
// SPI: MOSI 23 | MISO 19 | SCK 18 | CS 5
// WARNING: GPIOs 34, 35, 36 (VP), 39 (VN) are INPUT-ONLY (no internal pull-up/pull-down).
// Never configure them as pinMode(..., OUTPUT); nor for I2C/SPI buses.`,
codigoEspIdf: `// In ESP-IDF, lock Flash voltage via eFuse to free GPIO 12 (WARNING: IRREVERSIBLE):
// If using classic ESP32 and GPIO 12 is needed for peripherals:
// espefuse.py --port /dev/ttyUSB0 set_flash_voltage 3.3V
// This permanently disables hardware strapping sampling on GPIO 12.`,
codigoMicroPython: `# Safe pin setup in MicroPython:
from machine import Pin
# Safe pins for outputs and buttons with internal pull-up:
led = Pin(2, Pin.OUT) # GPIO 2
button = Pin(4, Pin.IN, Pin.PULL_UP) # GPIO 4 (safe)
# Pins 34, 35, 36, 39 are INPUT-ONLY with no internal pull-ups:
analog_sensor = Pin(36, Pin.IN) # Correct (requires external pull-up if used as a digital input)`,
dicaPro: "Remember: Input-only pins (GPI 34 to 39 on classic ESP32) have neither internal silicon pull-up/pull-down circuits nor output drivers. External resistors are mandatory.",
},
{
id: "guru-load-prohibited",
titulo: "Guru Meditation: LoadProhibited / StoreProhibited",
categoria: "cpu-panics",
sintomas: ["bootloop", "null-pointer"],
gravidade: "Crítica",
logSerial: "Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.\nCore 0 register dump:\nPC : 0x400d14bc PS : 0x00060830 A0 : 0x800d1512 A1 : 0x3ffb1f20 \nEXCVADDR: 0x00000000",
resumo: "The CPU attempted to read (Load) or write (Store) to an inaccessible or invalid memory address, typically null pointer 0x00000000.",
causaRaiz:
"This is the classic null pointer dereference or dangling pointer access. The EXCVADDR register shows the faulty memory address: if EXCVADDR is 0x00000000 or near zero (e.g. 0x00000008, a struct offset), code attempted to access members of an uninitialized object or a failed malloc allocation.",
gambiarra: {
titulo: "Inserting random delays or rebooting in loop without fixing root cause",
descricao: "Assuming it is a timing glitch and scattering delay() calls or masking reboots.",
consequencia: "The firmware continues crashing intermittently in production whenever the null pointer condition recurs.",
},
solucaoEngenharia: {
titulo: "Defensive validation and Backtrace decoding",
passos: [
"Always verify that pointers returned by allocation or lookup functions (malloc, WiFi.client(), JSON parsing, xQueueReceive) are non-NULL before accessing their fields.",
"Install 'Espressif Exception Decoder' in your IDE (Arduino IDE / PlatformIO) or run 'xtensa-esp32-elf-addr2line -pfia -e firmware.elf 0x400d14bc' to pinpoint the exact line of code that triggered the crash.",
"In ESP-IDF, run 'idf.py monitor' which decodes the call backtrace in real-time.",
],
},
codigoArduino: `// DEFENSIVE CODING:
struct SensorData {
float temperature;
float humidity;
};
void processSensor(SensorData* sensor) {
// Mandatory check against LoadProhibited:
if (sensor == nullptr) {
Serial.println("[ERROR] Null sensor pointer!");
return;
}
Serial.printf("Temp: %.1f C\\n", sensor->temperature);
}`,
codigoEspIdf: `// In ESP-IDF, use ESP_RETURN_ON_FALSE or explicit assertions:
#include "esp_log.h"
#include "esp_check.h"
static const char* TAG = "SENSOR";
esp_err_t read_data(char* buffer, size_t max_len) {
ESP_RETURN_ON_FALSE(buffer != NULL, ESP_ERR_INVALID_ARG, TAG, "Null buffer supplied!");
// Safe operation...
return ESP_OK;
}`,
codigoMicroPython: `# Preventing NoneType exceptions in MicroPython:
import json
def process_sensor(raw_data):
if raw_data is None:
print("[ERROR] Null data received!")
return None
try:
obj = json.loads(raw_data)
# Safe lookup with fallback default
temperature = obj.get("temp", 0.0)
return temperature
except (ValueError, AttributeError) as e:
print("Error processing payload:", e)
return None`,
dicaPro: "If EXCVADDR is 0x3fxxxxxx or 0x40xxxxxx but the code crashes, you likely experienced a buffer overflow that corrupted adjacent pointers in RAM.",
},
{
id: "guru-iram-cache",
titulo: "Cache Error / InstructionFetchError in ISRs",
categoria: "cpu-panics",
sintomas: ["bootloop", "null-pointer"],
gravidade: "Alta",
logSerial: "Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)\nGuru Meditation Error: Core 0 panic'ed (InstructionFetchError)",
resumo: "An interrupt service routine (ISR) tried to execute code or read constants from SPI Flash while the Flash memory controller was disabled for a write or erase operation.",
causaRaiz:
"By default, ESP32 application code resides in external SPI Flash and is fetched into CPU execution pipeline via internal Instruction Cache. When the ESP32 writes to Flash (such as NVS commits, LittleFS, SPIFFS, or OTA updates), the hardware cache is momentarily disabled. If an ISR fires during this window and its function body resides in Flash, the CPU cannot fetch the instruction and enters an immediate panic.",
gambiarra: {
titulo: "Disabling all interrupts before writing to Flash",
descricao: "Wrapping Flash file operations in indiscriminate noInterrupts() blocks.",
consequencia: "Causes dropped sensor pulses, jitter on system timers, and potential watchdog resets.",
},
solucaoEngenharia: {
titulo: "Allocating ISRs and callback constants in IRAM / DRAM",
passos: [
"Decorate EVERY hardware interrupt handler with the IRAM_ATTR attribute (e.g., void IRAM_ATTR isrHandler()).",
"Ensure any variables or constant strings accessed inside the ISR reside in DRAM (avoid inline string literals in ISR without DRAM_ATTR in ESP-IDF).",
"Never call heavy library functions (such as Serial.print or floating-point formatting) inside an interrupt handler.",
],
},
codigoArduino: `// ISR properly placed in internal IRAM:
volatile uint32_t pulseCount = 0;
void IRAM_ATTR handleGpioInterrupt() {
pulseCount++;
}
void setup() {
pinMode(4, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(4), handleGpioInterrupt, FALLING);
}`,
codigoEspIdf: `// ESP-IDF:
#include "esp_attr.h"
#include "driver/gpio.h"
static volatile uint32_t pulses = 0;
// Placed explicitly in IRAM:
static void IRAM_ATTR gpio_isr_handler(void* arg) {
pulses++;
}
void app_main(void) {
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
gpio_isr_handler_add(GPIO_NUM_4, gpio_isr_handler, NULL);
}`,
codigoMicroPython: `# Safe interrupt handling (ISR) in MicroPython:
import micropython
from machine import Pin
# Pre-allocate emergency exception buffer for ISR debugging:
micropython.alloc_emergency_exception_buf(100)
pulse_count = 0
# Interrupt callback: do NOT allocate memory (no new strings, no new floats)
def handle_pulse(pin):
global pulse_count
pulse_count += 1
sensor = Pin(4, Pin.IN, Pin.PULL_UP)
sensor.irq(trigger=Pin.IRQ_FALLING, handler=handle_pulse)`,
dicaPro: "When passing ESP_INTR_FLAG_IRAM in ESP-IDF, every function invoked by the ISR (including FreeRTOS API calls) MUST support IRAM (e.g. xQueueSendFromISR).",
},
{
id: "freertos-twdt",
titulo: "Task Watchdog Timer (TWDT) Timeout",
categoria: "freertos",
sintomas: ["bootloop", "wdt-reset"],
gravidade: "Crítica",
logSerial: "E (10532) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:\nE (10532) task_wdt: - IDLE0 (CPU 0)\nTask watchdog got triggered. System will be reset.",
resumo: "A high-priority task entered a busy loop without yielding CPU time, preventing the FreeRTOS IDLE task from feeding the watchdog.",
causaRaiz:
"FreeRTOS runs an essential priority-0 task called IDLE on each CPU core. The Task Watchdog monitors whether the IDLE task executes periodically (by default, within 5 seconds). If a task with priority >= 1 runs a tight while(1) loop without blocking calls (vTaskDelay, queue reads, semaphores), it starves the IDLE task, triggering an emergency hardware reset.",
gambiarra: {
titulo: "Disabling Task Watchdog in menuconfig or increasing timeout to 60s",
descricao: "Turning off the TWDT to prevent the board from rebooting.",
consequencia: "If the firmware encounters an unexpected deadlock or infinite loop, the device freezes permanently and requires manual power cycling.",
},
solucaoEngenharia: {
titulo: "Event-driven architecture and periodic CPU yield",
passos: [
"Never write empty busy-wait loops like while(!condition); in FreeRTOS tasks.",
"Always insert vTaskDelay(pdMS_TO_TICKS(10)) or wait for events with xQueueReceive(), ulTaskNotifyTake(), or xSemaphoreTake() with a timeout.",
"If heavy compute tasks must run continuously, feed the watchdog explicitly via esp_task_wdt_reset().",
],
},
codigoArduino: `// CORRECT ARDUINO FREERTOS PATTERN:
void myTask(void *pvParameters) {
for (;;) {
float sensorValue = analogRead(36);
// YIELD CPU to FreeRTOS scheduler and IDLE task:
vTaskDelay(pdMS_TO_TICKS(100)); // Non-blocking 100ms pause
}
}`,
codigoEspIdf: `// ESP-IDF Task Watchdog pattern:
#include "esp_task_wdt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void compute_task(void *pvParameters) {
esp_task_wdt_add(NULL);
while (1) {
// Compute...
// Feed watchdog during long processing cycles:
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(50));
}
}`,
codigoMicroPython: `# Watchdog and non-blocking tasks with uasyncio in MicroPython:
from machine import WDT
import uasyncio as asyncio
wdt = WDT(timeout=5000)
async def sensor_task():
while True:
wdt.feed()
await asyncio.sleep_ms(100)
async def main():
asyncio.create_task(sensor_task())
while True:
await asyncio.sleep(1)
asyncio.run(main())`,
dicaPro: "In Arduino, delay(ms) internally calls vTaskDelay. However, delayMicroseconds() or raw compute loops do not yield CPU time and will trigger the TWDT if held for more than a few seconds.",
},
{
id: "freertos-stack-overflow",
titulo: "Stack Overflow (Task Stack Depletion)",
categoria: "freertos",
sintomas: ["bootloop", "null-pointer"],
gravidade: "Crítica",
logSerial: "Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception).\nDebug exception reason: Stack canary watchpoint triggered (my_task)",
resumo: "The task consumed more stack memory than allocated upon creation, corrupting the RTOS protection canary.",
causaRaiz:
"Each FreeRTOS task is allocated a fixed contiguous memory block for local variables, function arguments, and return addresses. Declaring large arrays on the stack (e.g., char buffer[2048];), heavy JSON documents, or deep call recursions within a default 2048-byte stack overflows the boundary and overwrites adjacent memory.",
gambiarra: {
titulo: "Assigning 64KB stack blindly to every task",
descricao: "Inflating task stack sizes indiscriminately to avoid overflow crashes.",
consequencia: "The ~320 KB usable SRAM of the ESP32 is quickly exhausted, leading to out-of-memory errors in Wi-Fi and TLS allocations.",
},
solucaoEngenharia: {
titulo: "Deliberate stack sizing and HighWaterMark monitoring",
passos: [
"Measure actual stack consumption using uxTaskGetStackHighWaterMark(). It returns the minimum free stack remaining since task creation.",
"Move large buffers from the stack to the heap (using malloc/free) or declare them static outside function scope if reused.",
"Tasks running secure TLS/HTTPS or MQTT over SSL connections require at least 6 KB to 8 KB of stack due to MbedTLS cryptographic frame complexity.",
],
},
codigoArduino: `// MONITORING TASK STACK IN ARDUINO:
void sensorTask(void *pvParameters) {
for (;;) {
// Task workload...
UBaseType_t freeStack = uxTaskGetStackHighWaterMark(NULL);
Serial.printf("[STACK] Remaining free stack: %d bytes\\n", (int)freeStack);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
void setup() {
Serial.begin(115200);
// Allocate 4096 bytes (4KB) with safety margin:
xTaskCreatePinnedToCore(sensorTask, "sensorTask", 4096, NULL, 1, NULL, 1);
}`,
codigoEspIdf: `// Enable double stack checking in menuconfig:
// Component config -> FreeRTOS -> Set a end of stack check -> Option 2 (Check by Stack Canary)
// This catches overflows BEFORE memory structures become silently corrupted at runtime.`,
codigoMicroPython: `# Memory and stack inspection in MicroPython:
import gc
import micropython
micropython.mem_info()
gc.collect()
print("Free Heap:", gc.mem_free(), "bytes")
print("Allocated Heap:", gc.mem_alloc(), "bytes")`,
dicaPro: "If a function only processes an HTTP or JSON payload occasionally, allocate the buffer dynamically on the heap during the transaction and free it immediately, rather than permanently inflating task stack.",
},
{
id: "memoria-fragmentacao-heap",
titulo: "Heap Fragmentation and Memory Leaks",
categoria: "memoria",
sintomas: ["random-freeze", "tls-fail"],
gravidade: "Alta",
logSerial: "E (45892) mbedtls: mbedtls_ssl_setup returned -0x7f00\nE (45892) esp-tls: create_ssl_handle failed\nE (45893) HTTP_CLIENT: Connection failed, out of memory",
resumo: "The ESP32 fails to allocate memory despite reporting a seemingly adequate total free heap size.",
causaRaiz:
"Heap memory becomes fragmented after thousands of allocations and deallocations of varying sizes over time (common when repeatedly concatenating Arduino String objects in loops). Free heap becomes split into tiny isolated chunks. When Wi-Fi or TLS libraries request a single contiguous 40 KB block for an SSL certificate buffer, malloc fails even if 100 KB total free memory exists across disconnected fragments.",
gambiarra: {
titulo: "Scheduling periodic ESP.restart() every few hours",
descricao: "Triggering a daily reboot to reset fragmented memory.",
consequencia: "Merely conceals the bug: during traffic spikes the device crashes well ahead of the scheduled reboot.",
},
solucaoEngenharia: {
titulo: "Eliminate dynamic strings and use pre-allocated static buffers",
passos: [
"In Arduino, avoid the String class. Use standard C-style character arrays (char buffer[128];) with safe snprintf().",
"Monitor fragmentation by comparing total free memory (heap_caps_get_free_size) with the largest contiguous free block (heap_caps_get_largest_free_block).",
"In complex ESP-IDF firmware, enable Heap Memory Tracing (CONFIG_HEAP_TRACING) to locate missing free() calls.",
],
},
codigoArduino: `// COMPARISON:
// ❌ AVOID (Causes severe heap fragmentation):
// String json = "{\\"temp\\":";
// json += String(temperature) + "}";
// ✅ RECOMMENDED (Zero heap allocations):
char payload[64];
snprintf(payload, sizeof(payload), "{\\"temp\\":%.2f,\\"hum\\":%.2f}", temperature, humidity);
// Health check:
Serial.printf("Free Heap: %u | Largest Block: %u\\n",
ESP.getFreeHeap(),
ESP.getMaxAllocHeap());`,
codigoEspIdf: `// Heap monitoring in ESP-IDF:
#include "esp_heap_caps.h"
#include "esp_log.h"
void inspect_memory(void) {
size_t total_free = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
ESP_LOGI("HEAP", "Total free: %d bytes | Largest contiguous: %d bytes", total_free, largest_block);
}`,
codigoMicroPython: `# Preventing heap fragmentation in MicroPython:
import gc
gc.enable()
# Pre-allocate reusable bytearrays instead of instantiating new strings:
rx_buffer = bytearray(256)
def read_sensor_zero_alloc(stream):
bytes_read = stream.readinto(rx_buffer)
return rx_buffer[:bytes_read]
gc.collect()
print(f"Free Heap: {gc.mem_free()} B | Allocated: {gc.mem_alloc()} B")`,
dicaPro: "If the largest contiguous free block drops below 35 KB to 40 KB, modern HTTPS/TLS connections will fail during the cryptographic handshake.",
},
{
id: "memoria-dma-psram",
titulo: "DMA Allocation Failure in External Memory (PSRAM)",
categoria: "memoria",
sintomas: ["bootloop", "random-freeze"],
gravidade: "Alta",
logSerial: "E (1204) spi_master: spi_bus_initialize: DMA channel not compatible with external RAM buffer\nESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG)",
resumo: "Firmware attempted to pass a buffer allocated in external PSRAM to a DMA-driven peripheral (SPI, I2S, LCD, SDMMC) that can only access internal SRAM.",
causaRaiz:
"On ESP32 family chips (especially classic ESP32, ESP32-S2, and ESP32-S3 standard bus), the peripheral DMA engine has no direct physical access to external SPI/QSPI PSRAM. DMA transfers strictly require source and destination buffers to reside in internal SRAM.",
gambiarra: {
titulo: "Disabling DMA on peripherals",
descricao: "Switching SPI/I2S buses to polled CPU transfer mode without DMA.",
consequencia: "Throughput plummets and the CPU core stays 100% occupied during display updates or audio streaming.",
},
solucaoEngenharia: {
titulo: "Explicit allocation with MALLOC_CAP_DMA and MALLOC_CAP_INTERNAL",
passos: [
"Always allocate DMA buffers using heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL).",
"Keep heavy non-DMA assets (decoded images, machine learning weights, inactive audio) in PSRAM, copying small frames to internal DMA buffers on demand (ping-pong buffering).",
],
},
codigoArduino: `// Allocating DMA buffers in Arduino ESP32:
#include <esp_heap_caps.h>
uint8_t* dmaBuffer = nullptr;
void setup() {
size_t size = 4096;
// Guarantees buffer is allocated in DMA-accessible internal SRAM:
dmaBuffer = (uint8_t*) heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
if (dmaBuffer == nullptr) {
Serial.println("[ERROR] Failed to allocate internal DMA buffer!");
}
}`,
codigoEspIdf: `// ESP-IDF:
#include "esp_heap_caps.h"
uint8_t* allocate_spi_buffer(size_t len) {
return (uint8_t*) heap_caps_aligned_alloc(4, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
}`,
codigoMicroPython: `# In MicroPython, inspect available PSRAM:
import gc
import esp32
print("Total accessible memory in MicroPython:", gc.mem_free() + gc.mem_alloc(), "bytes")
buffer_spi = bytearray(1024)`,
dicaPro: "On the ESP32-P4, the advanced AXI bus matrix enables DMA into specific external memory regions, but for the ESP32/S2/S3/C3 lines, internal SRAM placement is mandatory.",
},
{
id: "boot-failed-connect",
titulo: "Failed to connect to ESP32: Timed out waiting for packet header",
categoria: "boot-flash",
sintomas: ["upload-fail"],
gravidade: "Média",
logSerial: "A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header\nesptool.py v4.6\nConnecting...................",
resumo: "The programming tool (esptool / Arduino IDE / PlatformIO) was unable to place the microcontroller into UART bootloader mode.",
causaRaiz:
"To initiate flashing, the USB-UART bridge (CH340, CP2102, FTDI) toggles DTR and RTS lines to pull GPIO 0 LOW while pulsing EN/RST LOW then HIGH. On many third-party development boards, the RC timing circuit on EN lacks adequate capacitance to hold the reset state during the DTR transition.",
gambiarra: {
titulo: "Holding the physical BOOT button with your finger at every upload",
descricao: "Pressing BOOT/GPIO 0 manually each time the compiler finishes generating binaries.",
consequencia: "Inconvenient during rapid prototyping and impossible on sealed boards enclosed in enclosures.",
},
solucaoEngenharia: {
titulo: "Add a 10 µF capacitor on EN or verify USB data cable",
passos: [
"Solder a 10 µF (or 1 µF to 10 µF) ceramic or electrolytic capacitor between the EN (RST) and GND pins. This stabilizes the automatic reset ramp.",
"Ensure the USB cable has active data lines (D+ and D-). Many cheap charging cables contain only power wires.",
"On Linux, confirm your user belongs to the 'dialout' group (sudo usermod -a -G dialout $USER) and that the 'brltty' service is not holding the serial port.",
],
},
codigoArduino: `// Command-line verification with esptool:
// python -m esptool --port /dev/ttyUSB0 chip_id
// If it prints the MAC and chip model, physical communication is working.`,
codigoEspIdf: `// In ESP-IDF:
// idf.py -p /dev/ttyUSB0 -b 460800 flash
// If flashing fails at high speeds, reduce baud rate:
// idf.py -p /dev/ttyUSB0 -b 115200 flash`,
codigoMicroPython: `# Flashing official MicroPython firmware via terminal:
# 1. Erase flash:
# esptool.py --port /dev/ttyUSB0 erase_flash
# 2. Flash binary at safe baud rate:
# esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-*.bin`,
dicaPro: "When using ESP32-S3 or C3 modules with native USB (Direct USB-JTAG), verify that your tooling is configured for the USB CDC/JTAG port rather than a legacy UART bridge.",
},
{
id: "tls-sntp-clock-fail",
titulo: "TLS/HTTPS Handshake Failure due to Desynchronized Clock",
categoria: "conectividade",
sintomas: ["tls-fail", "random-freeze"],
gravidade: "Alta",
logSerial: "E (15420) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700\nE (15420) esp-tls: Failed to verify peer certificate!\nE (15421) esp-tls: Verification info: The certificate is not yet valid (or has expired)",
resumo: "Secure HTTPS, AWS IoT, MQTT over TLS, or Web API requests fail because the internal ESP32 RTC defaults to 01/01/1970.",
causaRaiz:
"Digital certificates (X.509 SSL/TLS) include strict validity windows (Not Before and Not After). Because typical ESP32 boards lack an external RTC battery, the internal clock resets to the Unix epoch (1970) on every cold boot. When MbedTLS checks the server certificate date, it deems it 'not yet valid' (since current dates are decades ahead of 1970), aborting the handshake with error -0x2700 (MBEDTLS_ERR_X509_CERT_VERIFY_FAILED).",
gambiarra: {
titulo: "Disabling SSL certificate verification (Insecure / No-Verify)",
descricao: "Using client.setInsecure() in Arduino or turning off CA validation in ESP-IDF.",
consequencia: "Creates a critical security vulnerability: the device is completely exposed to Man-in-the-Middle (MitM) attacks, allowing credentials and firmware to be intercepted.",
},
solucaoEngenharia: {
titulo: "Mandatory SNTP time synchronization prior to opening TLS sockets",
passos: [
"Immediately after acquiring an IP address, start the SNTP client querying reliable NTP servers (e.g. pool.ntp.org, time.google.com).",
"Block outbound HTTPS/MQTT connections until system time is confirmed synchronized.",
"Set the correct timezone string so log timestamps match local operational time.",
],
},
codigoArduino: `// SNTP SYNCHRONIZATION BEFORE HTTPS IN ARDUINO:
#include <WiFi.h>
#include <time.h>
void syncClock() {
configTime(0, 0, "pool.ntp.org", "time.google.com");
Serial.print("Waiting for NTP time sync");
time_t now = time(nullptr);
// Year 2024 in Unix timestamp is > 1700000000. If smaller, clock is still in 1970:
while (now < 1700000000) {
delay(500);
Serial.print(".");
now = time(nullptr);
}
Serial.println("\\n[OK] Clock synchronized! TLS handshakes enabled.");
}`,
codigoEspIdf: `// SNTP in ESP-IDF:
#include "esp_sntp.h"
#include "esp_log.h"
void initialize_sntp(void) {
ESP_LOGI("SNTP", "Starting SNTP client...");
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, "pool.ntp.org");
esp_sntp_init();
}`,
codigoMicroPython: `# SNTP synchronization and HTTPS requests in MicroPython:
import ntptime
import time
import urequests
def sync_and_request():
try:
print("Synchronizing clock via NTP...")
ntptime.host = "pool.ntp.org"
ntptime.settime()
print("UTC Time synchronized:", time.localtime())
response = urequests.get("https://api.github.com")
print("HTTPS Response:", response.status_code)
response.close()
except Exception as e:
print("[TLS/NTP ERROR]:", e)`,
dicaPro: "If operating in isolated local networks without internet access, configure a local NTP server on the gateway router or add a physical DS3231 RTC module over I2C.",
},
];
export const regrasDecodificadorLog = [
{
padrao: /Brownout detector was triggered/i,
titulo: "Brownout Detector (Critical Undervoltage)",
tipo: "Power / Hardware",
explicacao:
"Voltage on the 3.3V rail dropped below safe limits (typically caused by Wi-Fi/BLE RF transmit spikes or an underpowered power supply).",
acaoRecomendada:
"Add a 10 µF to 100 µF low-ESR capacitor on the VCC rail, verify power cables, and ensure the LDO regulator delivers adequate current.",
},
{
padrao: /LoadProhibited|StoreProhibited/i,
titulo: "Guru Meditation: Load/StoreProhibited (Null or Invalid Pointer)",
tipo: "CPU Panic / Exception",
explicacao:
"Attempted to read or write to an invalid memory location (usually null pointer dereference or array index out of bounds).",
acaoRecomendada:
"Decode the Backtrace using Exception Decoder or 'addr2line' to find the exact line. Add defensive 'if (ptr != NULL)' validation.",
},
{
padrao: /Cache disabled but cached memory region accessed|InstructionFetchError/i,
titulo: "Interrupt Cache Error (ISR outside IRAM)",
tipo: "CPU Panic / Flash",
explicacao:
"An interrupt handler (ISR) attempted to execute code from external Flash while Flash was busy with a write or erase operation (NVS, LittleFS, OTA).",
acaoRecomendada:
"Add the IRAM_ATTR attribute to the interrupt callback and ensure variables accessed inside the ISR reside in DRAM.",
},
{
padrao: /Task watchdog got triggered/i,
titulo: "Task Watchdog Timer (TWDT) Timeout",
tipo: "FreeRTOS / Multitasking",
explicacao:
"A high-priority task monopolized the CPU without yielding (missing vTaskDelay or blocking queues), starving the FreeRTOS IDLE task.",
acaoRecomendada:
"Add vTaskDelay(pdMS_TO_TICKS(10)) inside compute loops, or use queues and semaphores instead of continuous while(1) loops.",
},
{
padrao: /Stack canary watchpoint triggered/i,
titulo: "Stack Overflow (Task Stack Exhaustion)",
tipo: "FreeRTOS / Memory",
explicacao:
"The task exceeded the stack memory allocated during creation, corrupting the RTOS stack canary sentinel.",
acaoRecomendada:
"Increase task stack size in xTaskCreate (e.g. from 2048 to 4096 bytes) and allocate large arrays on the heap.",
},
{
padrao: /Timed out waiting for packet header|Failed to connect to ESP32/i,
titulo: "UART Connection / Upload Failure",
tipo: "Bootloader / Connection",
explicacao:
"The host computer failed to place the ESP32 into flashing mode via DTR/RTS, or the USB cable lacks data lines.",
acaoRecomendada:
"Add a 10 µF capacitor between EN and GND, verify data cable continuity, or hold the physical BOOT button during upload initiation.",
},
{
padrao: /The certificate is not yet valid|-0x2700/i,
titulo: "SSL/TLS Certificate Failure (Clock stuck in 1970)",
tipo: "Connectivity / TLS",
explicacao:
"The ESP32 attempted to validate an HTTPS/TLS server certificate with its internal clock unset at the Unix epoch (1970).",
acaoRecomendada:
"Synchronize time via SNTP (configTime in Arduino or ntptime.settime() in MicroPython) before making secure TLS requests.",
},
{
padrao: /rst:0x1 \(POWERON_RESET\),boot:0x[0-9a-fA-F]+/i,
titulo: "Power-On Reset / Strapping Pins Latch",
tipo: "Hardware / Boot",
explicacao:
"The microcontroller rebooted and logged its strapping register. If it freezes immediately after, a strapping pin is held at an incorrect level.",
acaoRecomendada:
"Check that strapping GPIOs (0, 2, 12, 15 on ESP32 or 8, 9 on C3) are not pulled to incompatible states by external circuits at reset.",
},
];
+193
View File
@@ -0,0 +1,193 @@
/**
* Structured Technical Glossary Database for ESP32.
* Covers all Espressif SoC series (ESP32, S2, S3, S31, C2, C3, C5, C6, C61, H2, H4, P4)
* and their hardware, peripherals, radio, security and software features.
*/
export const categoriasGlossario = [
{
id: "processamento",
nome: "Processing, CPU & Silicon",
icone: "Cpu",
emoji: "🧠",
cor: "blue",
descricao: "Xtensa and RISC-V architectures, cores, ULP coprocessors, AI vector accelerators and floating-point units.",
termos: [
{
termo: "Xtensa vs RISC-V Architecture",
definicao: "Processor instruction set architecture. Classic ESP32, S2 and S3 use proprietary Tensilica Xtensa cores (LX6/LX7). Modern series C (C2, C3, C5, C6, C61), H (H2, H4) and P (P4) adopt the open, modular and energy-efficient 32-bit RISC-V architecture.",
exemplo: "ESP32-S3 uses dual-core Xtensa LX7, while ESP32-C6 uses single-core RISC-V and ESP32-P4 features dual-core RISC-V at 400 MHz.",
},
{
termo: "CPU Cores (Dual-Core vs Single-Core)",
definicao: "Independent central processing units. Dual-core chips allow dedicating one core (Core 0) to Wi-Fi/Bluetooth protocol stacks and FreeRTOS scheduling, leaving the second core (Core 1) entirely free for user application tasks.",
exemplo: "ESP32, ESP32-S3 and ESP32-P4 are dual-core; ESP32-S2, C2, C3, C6 and H2 are single-core.",
},
{
termo: "ULP Coprocessor (Ultra Low Power)",
definicao: "An ultra-low-power auxiliary processor that operates while the main CPU cores are asleep in Deep Sleep mode. It can monitor analog sensors, read GPIOs or scan I2C/SPI buses consuming microamps.",
exemplo: "ESP32 includes an FSM/assembly ULP; ESP32-S2, S3, C5 and C6 integrate a 32-bit RISC-V ULP coprocessor running up to 20–48 MHz.",
},
{
termo: "Vector Instructions & AI Acceleration",
definicao: "SIMD (Single Instruction, Multiple Data) CPU extension designed for parallel mathematical operations, accelerating matrix multiplications, FFTs, audio filtering and neural network inference.",
exemplo: "ESP32-S3 includes 128-bit vector extensions; ESP32-P4 features high-throughput vector instructions for DSP and machine vision.",
},
{
termo: "FPU (Floating-Point Unit)",
definicao: "Dedicated hardware module for single-precision IEEE 754 floating-point operations. Avoids software floating-point emulation, executing float math in single clock cycles.",
exemplo: "ESP32, ESP32-S3 and ESP32-P4 have hardware FPU; ESP32-C3 uses software floating-point emulation.",
},
],
},
{
id: "conectividade",
nome: "Connectivity & Radio",
icone: "Wifi",
emoji: "📡",
cor: "teal",
descricao: "Wi-Fi 4, Wi-Fi 6, Bluetooth Dual Mode, BLE, Zigbee, Thread, Matter and wireless mesh networks.",
termos: [
{
termo: "Wi-Fi 6 (802.11ax)",
definicao: "Next-generation Wi-Fi standard delivering higher spectral efficiency, lower latency, and reduced power consumption via OFDMA and Target Wake Time (TWT).",
exemplo: "ESP32-C6 and C5 support 802.11ax in 2.4 GHz; ESP32-C5 adds dual-band 5 GHz support.",
},
{
termo: "Target Wake Time (TWT)",
definicao: "A Wi-Fi 6 power-saving mechanism allowing the access point and ESP32 to negotiate scheduled sleep periods. The device stays asleep for hours and wakes only at negotiated transmission times.",
exemplo: "Battery-powered ESP32-C6 sensors use TWT to preserve battery life while remaining associated to Wi-Fi 6 routers.",
},
{
termo: "Bluetooth LE Audio & Isochronous Channels",
definicao: "Next-generation Bluetooth audio architecture using the LC3 codec over isochronous BIS/CIS channels, enabling broadcast audio (Auracast) and ultra-low latency.",
exemplo: "ESP32-H4 supports Bluetooth 5.4 LE Audio with isochronous streams.",
},
{
termo: "Thread & IEEE 802.15.4",
definicao: "An open, IPv6-based, low-power wireless mesh networking protocol designed specifically for smart home automation.",
exemplo: "ESP32-H2 and ESP32-C6 feature an IEEE 802.15.4 radio supporting Thread and Zigbee.",
},
{
termo: "Matter Protocol",
definicao: "A unified application layer protocol running over IPv6 (Wi-Fi, Thread and Ethernet) ensuring seamless cross-ecosystem interoperability across Apple Home, Google Home, Alexa and SmartThings.",
exemplo: "ESP32-C6, H2 and S3 devices run ESP-Matter firmware certified for cross-platform smart home setups.",
},
],
},
{
id: "memoria",
nome: "Memory & Buses",
icone: "Database",
emoji: "💾",
cor: "purple",
descricao: "Internal SRAM, RTC fast/slow memory, external Flash, PSRAM, cache architecture and memory-mapped SPI buses.",
termos: [
{
termo: "Internal SRAM & Memory Regions",
definicao: "High-speed static RAM embedded on the silicon die. Divided into instruction SRAM (IRAM) and data SRAM (DRAM).",
exemplo: "Classic ESP32 provides 520 KB of internal SRAM; ESP32-P4 includes 768 KB on-chip L2 SRAM.",
},
{
termo: "PSRAM (Pseudo-Static RAM)",
definicao: "External dynamic RAM with an internal self-refresh controller that communicates with the CPU via high-speed SPI/QSPI/OPI buses through cache memory.",
exemplo: "ESP32-S3 modules commonly integrate 8 MB of Octal PSRAM for audio buffers and display framebuffers.",
},
{
termo: "Flash Memory & Partition Table",
definicao: "Non-volatile NOR flash memory storing bootloader, partition table, firmware application binaries and file systems (NVS, LittleFS, SPIFFS).",
exemplo: "The partition table (partitions.csv) configures OTA slots (ota_0, ota_1) and storage partitions.",
},
{
termo: "NVS (Non-Volatile Storage)",
definicao: "A structured key-value storage library implemented inside dedicated flash partitions for persisting calibration parameters, Wi-Fi credentials and state.",
exemplo: "Wi-Fi credentials and pairing keys are saved to NVS and retained across deep sleep cycles and reboots.",
},
],
},
{
id: "perifericos",
nome: "Peripherals & I/O",
icone: "Sliders",
emoji: "⚡",
cor: "amber",
descricao: "GPIO matrix, analog converters, serial communication buses, timers and specialized hardware interfaces.",
termos: [
{
termo: "GPIO Matrix & Pin Muxing",
definicao: "A flexible internal routing matrix that decouples internal peripheral signals (UART, SPI, I2C, PWM) from physical package pins, allowing almost any digital signal to route to any GPIO.",
exemplo: "On the ESP32, hardware I2C or UART can be assigned to arbitrary digital GPIO pins in firmware.",
},
{
termo: "Strapping Pins",
definicao: "Dedicated physical pins sampled by hardware boot ROM during power-up or reset to determine boot mode (UART download vs SPI flash boot), VDD_SPI voltage and console logging.",
exemplo: "GPIO0 pulled low during reset puts the ESP32 into ROM serial download mode for flashing.",
},
{
termo: "SAR ADC & Non-Linearity",
definicao: "Successive Approximation Register Analog-to-Digital Converter used for reading analog voltages. Requires software calibration for accurate readings near 0V and reference limits.",
exemplo: "ESP-IDF esp_adc_cal APIs use factory calibration eFuses to convert raw ADC counts into calibrated millivolts.",
},
{
termo: "TWAI / CAN Bus",
definicao: "Two-Wire Automotive Interface, Espressif's implementation of the ISO 11898-1 CAN 2.0B / CAN FD standard for robust vehicle and industrial networking.",
exemplo: "ESP32-S3 and P4 connect to CAN bus networks through external CAN transceivers (e.g. SN65HVD230).",
},
],
},
{
id: "seguranca",
nome: "Hardware Security",
icone: "ShieldCheck",
emoji: "🔒",
cor: "green",
descricao: "Secure Boot, Flash Encryption, cryptographic hardware accelerators, eFuses and physical tamper resistance.",
termos: [
{
termo: "eFuse (One-Time Programmable Memory)",
definicao: "A block of one-time programmable microscopic electrical fuses on the silicon die storing MAC addresses, cryptographic keys, and permanent security configurations.",
exemplo: "Secure Boot and Flash Encryption permanently lock configuration bits in eFuses during device manufacturing.",
},
{
termo: "Secure Boot v2",
definicao: "A cryptographic chain of trust starting in ROM code that verifies digital signatures (RSA-3072 or ECDSA) of bootloader and application binaries before execution.",
exemplo: "Secure Boot prevents execution of unauthorized or tampered firmware on production ESP32 devices.",
},
{
termo: "Flash Encryption",
definicao: "On-the-fly transparent hardware encryption (AES-128 or XTS-AES-256) of external flash memory contents. The encryption key is stored securely in eFuses and never exposed.",
exemplo: "Flash Encryption protects firmware intellectual property and sensitive credentials against physical flash readout.",
},
{
termo: "Hardware Cryptographic Accelerators",
definicao: "Dedicated silicon calculation blocks executing AES, SHA, RSA, ECC and RNG operations at hardware speeds without loading CPU cores.",
exemplo: "Hardware AES and SHA accelerate TLS/HTTPS handshakes on ESP32 without stalling FreeRTOS tasks.",
},
],
},
{
id: "energia",
nome: "Power & Thermal Management",
icone: "Battery",
emoji: "🔋",
cor: "emerald",
descricao: "Deep Sleep, Light Sleep, brownout detection, power management algorithms and battery conservation.",
termos: [
{
termo: "Deep Sleep Mode",
definicao: "Ultra-low-power sleep state where high-performance CPU cores, digital peripherals, and radio are completely powered down, drawing only microamps.",
exemplo: "In Deep Sleep, ESP32 consumes roughly 5–10 µA while RTC memory and timer remain active to wake the device.",
},
{
termo: "Brownout Detector",
definicao: "An internal hardware monitoring circuit that triggers a safe system reset if input VDD supply voltage drops below a calibrated threshold (~2.8V).",
exemplo: "Sudden Wi-Fi transmit current spikes on weak power supplies trigger the Brownout detector to prevent memory corruption.",
},
{
termo: "Wake-up Sources",
definicao: "Configurable hardware triggers capable of waking the ESP32 from sleep modes, including RTC timers, external GPIO edges, touch pins and ULP signals.",
exemplo: "esp_sleep_enable_ext0_wakeup configures a door sensor pin to instantly wake the chip from Deep Sleep.",
},
],
},
];
+184
View File
@@ -0,0 +1,184 @@
/**
* Conhecimento de domínio da busca inteligente.
*
* Sem dependências nem alias de import: roda no servidor (montando o índice),
* no navegador (interpretando a consulta) e em scripts de teste no Node.
*
* Todos os textos de `termos` já estão normalizados (minúsculos, sem acento).
*/
export const normalizar = (s = "") =>
String(s)
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
/**
* Reconhece pinos ocupados por flash/PSRAM com base no que o diagrama diz.
* "forte": o pino é consumido pela memória (ou é a alimentação dela).
* "fraco": só é afetado em certos modos (ex.: SPI de 8 linhas/octal).
* Avisos genéricos de tensão mínima ("para chips com flash integrada...") não contam.
*/
const nivelMemoria = (palavra) => (p) => {
const citam = p._avs.filter((a) => a.includes(palavra) && !/^para chips (com|sem)/.test(a));
if (citam.some((a) => /(utilizad|dedicad|conectad)/.test(a) && !/a menos que/.test(a))) return "forte";
if (p._fn.some((f) => /alimentacao/.test(f) && f.includes(palavra))) return "forte";
if (citam.length) return "fraco";
return null;
};
/**
* Assuntos que o usuário pode citar. Cada um sabe:
* - termos: como as pessoas escrevem (sinônimos, siglas, plurais comuns);
* - pinoCats / pinoRe: como reconhecer os pinos relacionados no diagrama;
* - pinoRotulo: frase usada no título do resultado de pinos.
* Os dados de especificação ligam-se aos assuntos por SPEC_CAMPOS.
*/
export const TOPICOS = [
{ id: "flash", nome: "Flash", termos: ["flash", "memoria flash", "spi flash", "armazenamento", "firmware", "rom externa"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "connected to flash memory" },
{ id: "psram", nome: "PSRAM", termos: ["psram", "ram externa", "spiram"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "connected to PSRAM" },
{ id: "memoria", nome: "Memory", termos: ["memoria", "sram", "heap", "rtc ram", "kb de ram", "memoria interna", "ram"], pinoRotulo: "" },
{ id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "wireless", "sem fio", "802.11", "wifi6", "wifi 6", "wi-fi 6"], pinoCats: ["Antena"], pinoRotulo: "antenna and radio pins" },
{ id: "bluetooth", nome: "Bluetooth", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh"], pinoCats: ["Antena"], pinoRotulo: "antenna and radio pins" },
{ id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4"], pinoRotulo: "" },
{ id: "matter", nome: "Matter", termos: ["matter", "casa inteligente", "smart home"], pinoRotulo: "" },
{ id: "ethernet", nome: "Ethernet", termos: ["ethernet", "rmii", "cabo de rede", "lan"], pinoCats: ["Ethernet"], pinoRotulo: "Ethernet pins" },
{ id: "can", nome: "CAN / TWAI", termos: ["can", "twai", "can bus", "canbus", "can fd"], pinoRe: /twai|\bcan\b/, pinoRotulo: "CAN/TWAI pins" },
{ id: "usb", nome: "USB", termos: ["usb", "otg", "usb serial", "usb otg", "hid", "cdc"], pinoCats: ["USB"], pinoRotulo: "USB pins" },
{ id: "jtag", nome: "JTAG / Depuração", termos: ["jtag", "debug", "depuracao", "depurar", "openocd", "gdb"], pinoCats: ["JTAG"], pinoRotulo: "JTAG pins" },
{ id: "adc", nome: "ADC", termos: ["adc", "analogico", "entrada analogica", "conversor analogico", "analogread", "saradc"], pinoCats: ["ADC"], pinoRotulo: "with ADC" },
{ id: "dac", nome: "DAC", termos: ["dac", "saida analogica", "conversor digital"], pinoCats: ["DAC"], pinoRotulo: "with DAC" },
{ id: "touch", nome: "Touch capacitivo", termos: ["touch", "capacitivo", "toque", "touchpad", "sensor de toque"], pinoCats: ["Touch"], pinoRotulo: "de touch capacitivo" },
{ id: "uart", nome: "UART", termos: ["uart", "serial", "tx", "rx", "txd", "rxd", "porta serial"], pinoCats: ["UART"], pinoRotulo: "de UART" },
{ id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "barramento spi"], pinoCats: ["SPI"], pinoRotulo: "de SPI" },
{ id: "i2c", nome: "I2C", termos: ["i2c", "sda", "scl", "twi", "iic"], pinoCats: ["I2C"], pinoRotulo: "de I2C" },
{ id: "i2s", nome: "I2S", termos: ["i2s", "audio", "som", "microfone", "pdm", "codec"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "de I2S/áudio" },
{ id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "dimmer"], pinoRe: /ledc|pwm/, pinoRotulo: "de PWM" },
{ id: "sd", nome: "Cartão SD / SDIO", termos: ["sd", "sdio", "sd card", "sdcard", "cartao sd", "microsd", "sdmmc", "mmc"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "de cartão SD/SDIO" },
{ id: "camera", nome: "Câmera", termos: ["camera", "cam", "dvp", "csi", "mipi csi", "ov2640", "video"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "de câmera" },
{ id: "lcd", nome: "Display / LCD", termos: ["lcd", "display", "tela", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "de display/LCD" },
{ id: "strapping", nome: "Boot / Strapping", termos: ["strapping", "boot", "bootstrap", "modo de boot", "download mode", "modo de gravacao", "inicializacao"], pinoCats: ["Strapping"], pinoRotulo: "de strapping (modo de boot)" },
{ id: "energia_pinos", nome: "Power", termos: ["alimentacao", "vdd", "3v3", "3.3v", "tensao", "regulador", "ldo", "fonte"], pinoCats: ["Power"], pinoRotulo: "power pins" },
{ id: "clock", nome: "Clock / Cristal", termos: ["clock", "xtal", "cristal", "oscilador", "32khz", "40mhz"], pinoCats: ["Clock"], pinoRotulo: "de clock/cristal" },
{ id: "gpio", nome: "GPIO", termos: ["gpio", "entradas e saidas"], pinoCats: ["GPIO"], pinoRotulo: "de GPIO" },
{ id: "baixo_consumo", nome: "Baixo consumo / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocessador", "lp gpio", "low power", "rtc gpio"], pinoCats: ["Low Power"], pinoRotulo: "de baixo consumo (LP/RTC)" },
{ id: "antena", nome: "Antena / RF", termos: ["antena", "rf", "radiofrequencia", "ipex"], pinoCats: ["Antena"], pinoRotulo: "de antena/RF" },
{ id: "seguranca", nome: "Security", termos: ["seguranca", "secure boot", "criptografia", "encriptacao", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "protecao"], pinoRotulo: "" },
{ id: "consumo", nome: "Consumo de energia", termos: ["consumo", "bateria", "deep sleep", "light sleep", "sleep", "modem sleep", "corrente", "miliamperes", "autonomia", "economia de energia", "low power mode"], pinoRotulo: "" },
{ id: "temperatura", nome: "Temperatura", termos: ["temperatura", "calor", "graus", "faixa de temperatura", "industrial"], pinoRotulo: "" },
{ id: "ia", nome: "IA / Aceleração", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vetorial", "inteligencia artificial", "rede neural", "esp-nn", "esp-dl"], pinoRotulo: "" },
{ id: "processador", nome: "Processor", termos: ["processador", "cpu", "nucleo", "nucleos", "core", "dual core", "single core", "arquitetura", "xtensa", "risc-v", "riscv"], pinoRotulo: "" },
{ id: "frequencia", nome: "Frequency", termos: ["frequencia", "mhz", "velocidade", "desempenho", "performance"], pinoRotulo: "" },
{ id: "ferramentas", nome: "Ferramentas / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "versao do idf"], pinoRotulo: "" },
{ id: "encapsulamento", nome: "Módulos e encapsulamento", termos: ["modulo", "modulos", "encapsulamento", "package", "qfn", "wroom", "wrover", "mini-1"], pinoRotulo: "" },
];
/**
* Campos de public/series.json que respondem a cada assunto.
* `campo` aceita caminho com ponto (seguranca.aes). `secao` é o id da âncora
* na página /series/[key].
*/
export const SPEC_CAMPOS = [
{ campo: "arquitetura", label: "Arquitetura", secao: "processador", topicos: ["processador"] },
{ campo: "nucleos", label: "Núcleos", secao: "processador", topicos: ["processador"] },
{ campo: "frequencia", label: "Frequency", secao: "processador", topicos: ["frequencia", "processador"] },
{ campo: "coprocessador_ulp", label: "Coprocessador ULP", secao: "processador", topicos: ["baixo_consumo"] },
{ campo: "aceleradores_ia", label: "Aceleradores de IA", secao: "processador", topicos: ["ia"] },
{ campo: "wifi", label: "Wi-Fi", secao: "conectividade", topicos: ["wifi"] },
{ campo: "bluetooth", label: "Bluetooth", secao: "conectividade", topicos: ["bluetooth"] },
{ campo: "zigbee_thread", label: "Zigbee/Thread", secao: "conectividade", topicos: ["zigbee"] },
{ campo: "matter", label: "Matter", secao: "conectividade", topicos: ["matter"] },
{ campo: "ethernet", label: "Ethernet", secao: "conectividade", topicos: ["ethernet"] },
{ campo: "ethernet_mac", label: "Ethernet MAC", secao: "conectividade", topicos: ["ethernet"] },
{ campo: "can", label: "CAN", secao: "conectividade", topicos: ["can"] },
{ campo: "memoria_sram", label: "SRAM", secao: "memoria", topicos: ["memoria"] },
{ campo: "memoria_sram_rtc", label: "SRAM RTC", secao: "memoria", topicos: ["memoria", "baixo_consumo"] },
{ campo: "memoria_rom", label: "ROM", secao: "memoria", topicos: ["memoria"] },
{ campo: "flash_externa", label: "Flash externa", secao: "memoria", topicos: ["flash", "memoria"] },
{ campo: "psram_externa", label: "PSRAM externa", secao: "memoria", topicos: ["psram", "memoria"] },
{ campo: "gpio", label: "GPIO", secao: "perifericos", topicos: ["gpio"] },
{ campo: "adc", label: "ADC", secao: "perifericos", topicos: ["adc"] },
{ campo: "dac", label: "DAC", secao: "perifericos", topicos: ["dac"] },
{ campo: "touch", label: "Touch", secao: "perifericos", topicos: ["touch"] },
{ campo: "uart", label: "UART", secao: "perifericos", topicos: ["uart"] },
{ campo: "spi", label: "SPI", secao: "perifericos", topicos: ["spi", "flash"] },
{ campo: "i2c", label: "I2C", secao: "perifericos", topicos: ["i2c"] },
{ campo: "i2s", label: "I2S", secao: "perifericos", topicos: ["i2s"] },
{ campo: "pwm", label: "PWM", secao: "perifericos", topicos: ["pwm"] },
{ campo: "usb", label: "USB", secao: "perifericos", topicos: ["usb"] },
{ campo: "lcd", label: "LCD", secao: "interfaces", topicos: ["lcd"] },
{ campo: "camera", label: "Câmera", secao: "interfaces", topicos: ["camera"] },
{ campo: "mipi_csi", label: "MIPI CSI", secao: "interfaces", topicos: ["camera"] },
{ campo: "mipi_dsi", label: "MIPI DSI", secao: "interfaces", topicos: ["lcd"] },
{ campo: "sdio", label: "SDIO", secao: "interfaces", topicos: ["sd"] },
{ campo: "sensor_temperatura", label: "Sensor de temperatura", secao: "interfaces", topicos: ["temperatura"] },
{ campo: "seguranca.aes", label: "AES", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.sha", label: "SHA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.rsa", label: "RSA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.ecc", label: "ECC", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.ecdsa", label: "ECDSA", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.hmac", label: "HMAC", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.assinatura_digital", label: "Assinatura digital", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.rng", label: "Gerador aleatório", secao: "seguranca", topicos: ["seguranca"] },
{ campo: "seguranca.criptografia_flash", label: "Criptografia de flash", secao: "seguranca", topicos: ["seguranca", "flash"] },
{ campo: "seguranca.secure_boot", label: "Secure Boot", secao: "seguranca", topicos: ["seguranca", "strapping"] },
{ campo: "temperatura_operacao", label: "Temperatura de operação", secao: "temperatura", topicos: ["temperatura"] },
{ campo: "temperatura_armazenamento", label: "Temperatura de armazenamento", secao: "temperatura", topicos: ["temperatura"] },
{ campo: "esp_idf_minimo", label: "ESP-IDF mínimo", secao: "ferramentas", topicos: ["ferramentas"] },
{ campo: "arduino_core", label: "Core Arduino", secao: "ferramentas", topicos: ["ferramentas"] },
{ campo: "depuracao", label: "Depuração", secao: "ferramentas", topicos: ["jtag", "ferramentas"] },
{ campo: "encapsulamento", label: "Encapsulamento", secao: "ferramentas", topicos: ["encapsulamento"] },
{ campo: "modulos", label: "Módulos", secao: "ferramentas", topicos: ["encapsulamento"] },
];
const ROTULOS_ENERGIA = {
active: "Ativo",
modem_sleep: "Modem Sleep",
light_sleep: "Light Sleep",
deep_sleep: "Deep Sleep",
hibernation: "Hibernação",
};
const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj);
/**
* Monta, para cada série, a lista plana de especificações (com os assuntos a
* que respondem) e os pinos do diagrama. É o que o navegador baixa.
*
* @param {Record<string, object>} series conteúdo de public/series.json
* @param {Record<string, object[]>} conexoes pinos por série (public/conexoes)
*/
export function montarConhecimento(series, conexoes) {
const saida = {};
for (const [chave, s] of Object.entries(series)) {
const specs = [];
for (const c of SPEC_CAMPOS) {
const valor = pegar(s, c.campo);
if (valor == null || valor === "") continue;
specs.push({ label: c.label, valor: String(valor), secao: c.secao, topicos: c.topicos });
}
for (const [modo, valor] of Object.entries(s.consumo_energia ?? {})) {
const base = modo.replace(/_cpu.*|_wifi.*/, "");
const label = ROTULOS_ENERGIA[modo] ?? ROTULOS_ENERGIA[base] ?? modo.replace(/_/g, " ");
specs.push({ label: `Consumo: ${label}`, valor: String(valor), secao: "energia", topicos: ["consumo"] });
}
saida[chave] = {
nome: s.nome_completo ?? chave,
specs,
pinos: (conexoes[chave] ?? []).map((p) => ({
n: String(p.numero),
nome: p.nome,
f: p.funcoes ?? [],
c: p.categorias ?? [],
a: p.avisos ?? [],
})),
};
}
return saida;
}
+60 -17
View File
@@ -1,9 +1,17 @@
import seriesData from "@/public/series.json";
import frameworksData from "@/public/frameworks.json";
import { categoriasGlossario } from "@/lib/glossarioData";
import { errosCatalogo } from "@/lib/diagnosticoData";
import { COMPONENTES_REGISTRY } from "@/lib/componentRegistryData";
import { montarConhecimento } from "@/lib/searchTopics";
import seriesDataPt from "@/public/series.json";
import frameworksDataPt from "@/public/frameworks.json";
import { categoriasGlossario as glossarioPt } from "@/lib/glossarioData";
import { errosCatalogo as errosPt } from "@/lib/diagnosticoData";
import { COMPONENTES_REGISTRY as componentesPt } from "@/lib/componentRegistryData";
import { montarConhecimento as montarConhecimentoPt } from "@/lib/searchTopics";
import seriesDataEn from "@/data/en/series.json";
import frameworksDataEn from "@/data/en/frameworks.json";
import { categoriasGlossario as glossarioEn } from "@/lib/data/en/glossario";
import { errosCatalogo as errosEn } from "@/lib/data/en/diagnostico";
import { COMPONENTES_REGISTRY as componentesEn } from "@/lib/data/en/componentes";
import { montarConhecimento as montarConhecimentoEn } from "@/lib/data/en/topicos";
import { readFileSync, existsSync } from "node:fs";
import path from "node:path";
@@ -15,7 +23,7 @@ import path from "node:path";
* `keywords` guarda texto extra pesquisável (não exibido).
*/
const PAGINAS = [
const PAGINAS_PT = [
{ titulo: "Início", descricao: "Página inicial do ESPDocs", href: "/", keywords: "home inicio" },
{ titulo: "Todas as Séries", descricao: "Pinouts, especificações e restrições de cada série ESP32", href: "/series", keywords: "chips pinout especificações" },
{ titulo: "Comparador de Séries", descricao: "Compare até 4 modelos lado a lado", href: "/comparacao", keywords: "comparar comparação versus" },
@@ -29,12 +37,41 @@ const PAGINAS = [
{ titulo: "Sobre o Projeto", descricao: "História, autor e Ciência Embarcada", href: "/sobre", keywords: "autor contato" },
];
const PAGINAS_EN = [
{ titulo: "Home", descricao: "ESPDocs homepage", href: "/en", keywords: "home" },
{ titulo: "All Series", descricao: "Pinouts, specifications and restrictions for each ESP32 series", href: "/en/series", keywords: "chips pinout specifications" },
{ titulo: "Series Comparator", descricao: "Compare up to 4 models side by side", href: "/en/compare", keywords: "compare comparison versus" },
{ titulo: "Board Catalog", descricao: "Development boards, pinouts and purchasing", href: "/en/catalog", keywords: "boards dev boards devkit buy" },
{ titulo: "Smart Selector", descricao: "Find the ideal chip for your project", href: "/en/selector", keywords: "quiz choose recommend selector" },
{ titulo: "Error Diagnostics", descricao: "Troubleshoot brownout, bootloop, WDT and crashes", href: "/en/diagnostics", keywords: "error problem bug crash issue" },
{ titulo: "Frameworks & SDKs", descricao: "ESP-IDF, Arduino, Rust, RainMaker and more", href: "/en/frameworks", keywords: "sdk" },
{ titulo: "Component Registry", descricao: "Driver catalog and idf_component.yml generator", href: "/en/components", keywords: "libraries drivers yml components" },
{ titulo: "Technical Glossary", descricao: "Essential hardware and software concepts", href: "/en/glossary", keywords: "terms dictionary definition meaning" },
{ titulo: "About the Project", descricao: "History, author and open source", href: "/en/about", keywords: "author contact" },
];
const cortar = (texto = "", max = 140) => (texto.length > max ? `${texto.slice(0, max - 1).trimEnd()}…` : texto);
export function construirIndiceBusca() {
export function construirIndiceBusca(locale = "pt") {
const isEn = locale === "en";
const paginas = isEn ? PAGINAS_EN : PAGINAS_PT;
const seriesData = isEn ? seriesDataEn : seriesDataPt;
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
const categoriasGlossario = isEn ? glossarioEn : glossarioPt;
const errosCatalogo = isEn ? errosEn : errosPt;
const componentes = isEn ? componentesEn : componentesPt;
const montarConhecimento = isEn ? montarConhecimentoEn : montarConhecimentoPt;
const prefixo = isEn ? "/en" : "";
const slugSeries = `${prefixo}/series`;
const slugFrameworks = `${prefixo}/frameworks`;
const slugGlossario = isEn ? "/en/glossary" : "/glossario";
const slugDiagnostico = isEn ? "/en/diagnostics" : "/diagnostico";
const slugComponentes = isEn ? "/en/components" : "/componentes";
const itens = [];
for (const p of PAGINAS) {
for (const p of paginas) {
itens.push({ tipo: "pagina", ...p, keywords: p.keywords });
}
@@ -43,7 +80,7 @@ export function construirIndiceBusca() {
tipo: "serie",
titulo: chave,
descricao: cortar(`${s.nome_completo ?? ""} — ${s.descricao ?? ""}`),
href: `/series/${chave}`,
href: `${slugSeries}/${chave}`,
keywords: [s.arquitetura, s.wifi, s.bluetooth, s.frequencia, s.nucleos].filter(Boolean).join(" "),
});
}
@@ -53,7 +90,7 @@ export function construirIndiceBusca() {
tipo: "framework",
titulo: f.nome ?? chave,
descricao: cortar(`${f.nome_completo ?? ""} — ${f.descricao ?? ""}`),
href: `/frameworks/${encodeURIComponent(chave)}`,
href: `${slugFrameworks}/${encodeURIComponent(chave)}`,
keywords: [f.linguagem, f.tipo, f.funcao_principal].filter(Boolean).join(" "),
});
}
@@ -65,7 +102,7 @@ export function construirIndiceBusca() {
tipo: "glossario",
titulo: t.termo,
descricao: cortar(t.definicao),
href: `/glossario#${slug}`,
href: `${slugGlossario}#${slug}`,
keywords: [cat.nome, t.exemplo].filter(Boolean).join(" "),
});
}
@@ -76,25 +113,31 @@ export function construirIndiceBusca() {
tipo: "erro",
titulo: e.titulo,
descricao: cortar(e.resumo),
href: `/diagnostico#${e.id}`,
href: `${slugDiagnostico}#${e.id}`,
keywords: [e.logSerial, ...(e.sintomas ?? [])].filter(Boolean).join(" "),
});
}
for (const c of COMPONENTES_REGISTRY) {
for (const c of componentes) {
itens.push({
tipo: "componente",
titulo: c.titulo,
descricao: cortar(c.descricao),
href: "/componentes",
href: slugComponentes,
keywords: [c.name, c.namespace, ...(c.tags ?? [])].filter(Boolean).join(" "),
});
}
const conexoes = {};
for (const chave of Object.keys(seriesData)) {
const arquivo = path.join(process.cwd(), "public", "conexoes", `${chave}.json`);
if (existsSync(arquivo)) conexoes[chave] = JSON.parse(readFileSync(arquivo, "utf8"));
const pastaConexoes = isEn ? path.join(process.cwd(), "data", "en", "conexoes") : path.join(process.cwd(), "public", "conexoes");
const arquivo = path.join(pastaConexoes, `${chave}.json`);
if (existsSync(arquivo)) {
conexoes[chave] = JSON.parse(readFileSync(arquivo, "utf8"));
} else {
const fallback = path.join(process.cwd(), "public", "conexoes", `${chave}.json`);
if (existsSync(fallback)) conexoes[chave] = JSON.parse(readFileSync(fallback, "utf8"));
}
}
return {
+39 -4
View File
@@ -6,6 +6,8 @@
* nascendo sem título próprio.
*/
import { ENABLED_LOCALES, getLocalizedHref } from "@/i18n/links";
export const SITE = {
url: "https://espdocs.cienciaembarcada.com.br",
nome: "ESPDocs",
@@ -28,16 +30,49 @@ export const SITE = {
* Usar isto em vez de escrever o objeto à mão garante que nenhuma página fique
* sem canonical ou sem og:title.
*/
export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "website" }) {
const url = `${SITE.url}${caminho}`;
export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "website", locale = "pt" }) {
const currentLocale = locale || "pt";
const basePath = caminho.startsWith("/") ? caminho : `/${caminho}`;
const canonicalPath = getLocalizedHref(`/pt${basePath}`, currentLocale);
const url = `${SITE.url}${canonicalPath}`;
const languages = {};
for (const loc of ENABLED_LOCALES) {
if (basePath === "/livro" && loc !== "pt") continue;
const locHref = getLocalizedHref(`/pt${basePath}`, loc);
const langKey = loc === "pt" ? "pt-BR" : loc;
languages[langKey] = `${SITE.url}${locHref}`;
}
if (ENABLED_LOCALES.includes("en") && basePath !== "/livro") {
languages["x-default"] = `${SITE.url}${getLocalizedHref(`/pt${basePath}`, "en")}`;
}
const ogLocaleMap = {
pt: "pt_BR",
en: "en_US",
es: "es_419",
fr: "fr_FR",
de: "de_DE",
"zh-CN": "zh_CN",
};
const alternateLocales = ENABLED_LOCALES
.filter((l) => l !== currentLocale && (basePath !== "/livro" || l === "pt"))
.map((l) => ogLocaleMap[l])
.filter(Boolean);
return {
title: titulo,
description: descricao,
keywords,
alternates: { canonical: caminho },
alternates: {
canonical: canonicalPath,
languages: Object.keys(languages).length > 1 ? languages : undefined,
},
openGraph: {
type: tipo,
locale: "pt_BR",
locale: ogLocaleMap[currentLocale] || "pt_BR",
alternateLocale: alternateLocales.length > 0 ? alternateLocales : undefined,
url,
siteName: SITE.nome,
title: `${titulo} · ${SITE.nome}`,