Autor: Luiz Nobre

  • Display e UI do assistente ESP32: painel redondo com LVGL, rosto animado e estado

    Display e UI do assistente ESP32: painel redondo com LVGL, rosto animado e estado

    Segundo artigo da série Assistentes de IA de Bancada. Se no primeiro montamos o pipeline de inferência, agora damos presença ao assistente: um display com rosto, estados animados e UI responsive. É aqui que o projeto deixa de parecer um terminal e passa a ser um objeto de bancada.

    (a) Conceito — quem desenha o quê

    A regra de ouro de UI em MCU é não bloquear o loop. Separe mentalmente três coisas: o modelo de estado (idle, listening, thinking, speaking, error), o render (o que aparece na tela) e a entrada (toque, botão, eventos de rede). O host manda transições de estado por mensagens curtas; a placa interpola e anima localmente.

    Arquitetura recomendada:

    1. Camada de transporte: WebSocket ou SSE recebendo eventos JSON como {"state":"thinking"}.
    2. Camada de estado: uma máquina de estados simples com timeout — se ficar em thinking por mais de 30 s, cai em error.
    3. Camada de render: LVGL com um timer de ~33 ms (30 FPS) para animações não críticas e refresh sob demanda para mudanças de estado.

    Para o “rosto”, duas abordagens rendem bons resultados: olhos geométricos (dois círculos animados com blur e piscar) ou sprite sheet em flash. O primeiro é mais leve e escala melhor; o segundo dá personalidade autoral.

    (b) BOM

    Item Modelo Função Faixa (USD)
    MCU ESP32-S3 N16R8 8 MB PSRAM para framebuffer 8–14
    Display redondo GC9A01 1.28″ 240×240 SPI Rosto / HUD principal 4–7
    Display TFT ST7789 1.9″ 170×320 SPI Alternativa retangular 4–6
    Touch (opcional) CST816S (capacitivo I2C) Interação direta 3–5
    Diffusor Acrílico leitoso 2 mm Suaviza LEDs e luz de fundo 1–3
    Amp + falante MAX98357A + 4Ω 3W Voz do assistente 5–9
    Fonte 5V/2A com capacitor 470µF Estabilidade 3–6

    Kit típico: 30 a 50 dólares. Um display redondo dá identidade; um TFT dá mais área útil para texto e valores.

    (c) Wiring do display

    SPI é o caminho para painéis baratos. Mapeamento funcional no S3:

    • SPI2_HOST: SCLK=GPIO12, MOSI=GPIO11, MISO não usado = -1.
    • CS=GPIO10, DC=GPIO9, RST=GPIO8, BK=GPIO7 (backlight, PWM opcional).
    • Touch I2C: SDA=GPIO4, SCL=GPIO5, INT=GPIO6, RST compartilhado com o painel (ou GPIO3).
    • Transfira o barramento SPI ao display com spi_bus_initialize dedicado — não divida com o cartão SD se puder evitar.

    Cuidados:

    • O backlight em 3V3 direto funciona, mas PWM com MOSFET/transistor permite dimmer e economiza corrente.
    • Fios > 20 cm em SPI geram artefatos; se precisar, reduza o clock para 20–40 MHz.
    • Alguns GC9A01 vêm com color inversion ativado. Se as cores parecerem negativas, ajuste invertColor no driver.
    • Framebuffer de 240×240 em RGB565 = 115.200 bytes. Isso só cabe na PSRAM — não tente no heap interno.

    (d) Código — init, buffer e animação

    Com o framework Arduino e Arduino_GFX / LovyanGFX, o init fica enxuto. Deixe o LVGL cuidar do buffer e do flush:

    #include <lvgl.h>
    #include <Arduino_GFX_Library.h>
    #include <esp_heap_caps.h>
    
    Arduino_DataBus *bus = new Arduino_ESP32SPI(9 /*DC*/, 10 /*CS*/, 12 /*SCK*/, 11 /*MOSI*/);
    Arduino_GFX *gfx = new Arduino_GC9A01(bus, 8 /*RST*/, 0 /*rotation*/);
    
    static lv_disp_draw_buf_t draw_buf;
    static lv_color_t *buf1;
    static lv_disp_drv_t disp_drv;
    
    void gfx_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *px) {
      gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px,
                            area->x2 - area->x1 + 1,
                            area->y2 - area->y1 + 1);
      lv_disp_flush_ready(drv);
    }
    
    void display_init() {
      gfx->begin(40000000);            // 40 MHz
      gfx->fillScreen(BLACK);
    
      // buffer de UMA linha dupla em PSRAM
      uint32_t px = 240 * 20;
      buf1 = (lv_color_t *)heap_caps_malloc(px * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
      lv_disp_draw_buf_init(&draw_buf, buf1, NULL, px);
    
      lv_disp_drv_init(&disp_drv);
      disp_drv.hor_res = 240;
      disp_drv.ver_res = 240;
      disp_drv.flush_cb = gfx_flush;
      disp_drv.draw_buf = &draw_buf;
      lv_disp_drv_register(&disp_drv);
    }

    Agora a máquina de estado e uma animação simples — olhos que respiram, piscam e mudam de cor conforme o estado:

    lv_obj_t *eyeL, *eyeR;
    lv_timer_t *blink_timer;
    
    void set_state(const char* s) {
      if (strcmp(s, "listening") == 0) {
        lv_obj_set_style_bg_color(eyeL, lv_color_hex(0x00E5FF), 0);
        lv_obj_set_style_bg_color(eyeR, lv_color_hex(0x00E5FF), 0);
      } else if (strcmp(s, "thinking") == 0) {
        lv_obj_set_style_bg_color(eyeL, lv_color_hex(0xFFC400), 0);
        lv_obj_set_style_bg_color(eyeR, lv_color_hex(0xFFC400), 0);
      } else if (strcmp(s, "speaking") == 0) {
        lv_obj_set_style_bg_color(eyeL, lv_color_hex(0x00FF88), 0);
        lv_obj_set_style_bg_color(eyeR, lv_color_hex(0x00FF88), 0);
      } else { // idle
        lv_obj_set_style_bg_color(eyeL, lv_color_white(), 0);
        lv_obj_set_style_bg_color(eyeR, lv_color_white(), 0);
      }
    }
    
    void blink_cb(lv_timer_t *t) {
      lv_obj_set_height(eyeL, 12);
      lv_obj_set_height(eyeR, 12);
      lv_timer_t *open = lv_timer_create([](lv_timer_t* o){
        lv_obj_set_height(eyeL, 64);
        lv_obj_set_height(eyeR, 64);
        lv_timer_del(o);
      }, 120, NULL);
      lv_timer_set_repeat_count(open, 1);
    }
    
    void loop() {
      lv_timer_handler();            // nunca bloqueie aqui
      delay(5);
    }

    No setup(), chame lv_init(), display_init() e crie os objetos. Registre blink_cb com lv_timer_create(..., 3000 + rand() % 2000, NULL) para piscadas naturais. O host só precisa emitir set_state("thinking") via WebSocket — o resto é local.

    (e) Troubleshooting — frame rate, PSRAM e partições

    Frame rate baixo: se a tela “arrasta”, quase sempre é flush síncrono com blit de framebuffer inteiro. Reduza o buffer (linha dupla em vez de tela cheia) e anime apenas os objetos que mudam. 30 FPS é suficiente para um rosto; 60 FPS só vale em transições curtas.

    Cores erradas: invertColor ligado no driver, ou byte-swap do RGB565. Teste com um padrão de barras antes de culpar a UI.

    Tearing: sem double buffer e sem sincronismo, você vê rasgo. Com PSRAM, use dois buffers; em telas pequenas, o custo é aceitável.

    PSRAM: confirme que ela está ativa no boot (esp_psram_get_size()). Drivers de display alocando no heap interno estouram rápido. Framebuffer grande → MALLOC_CAP_SPIRAM.

    Partições de flash: LVGL com sprites e fontes come espaço. O layout default de 16 MB precisa de ajuste — crie uma tabela de partição com nvs, ota_0, ota_1, spiffs/littlefs para assets. Deixe OTA de pelo menos 3 MB se pretende atualizar o firmware por rede. Assets (fontes, imagens) vão em LittleFS, não em variáveis globais.

    O que travar na placa vs. host: render, animação, piscadas, debounce e timeout ficam na placa. Fontes grandes, geração de subtítulos e lógica de conversa ficam no host. Nunca envie bitmaps de UI pelo Wi-Fi — envie estado.

    (f) Aplicações reais

    • Rosto de bancada: olhos que reagem ao estado da inferência tornam o tempo de espera perceptível e menos frustrante.
    • Painel de status: além do rosto, um canto mostra latência, modelo ativo e uso de tokens — útil para depurar o pipeline do artigo anterior.
    • Dashboard embarcado: com TFT retangular, exiba grafos do host (via API) ou métricas do laboratório.
    • Produto de mesa: base de UI reutilizável para assistentes com ESP32-S3 + LVGL, com licença MIT facilitando fork.
    • Integração com firmware open-source: o xiaozhi-esp32 já traz o esqueleto de UI e pode servir de ponto de partida para a série.

    Resumo: display e UI são o que transforma um módulo em assistente. A arquitetura é a mesma do Post 1 — estado no host, animação na placa — o que mantém o firmware pequeno, o OTA viável e a experiência fluida.

  • Kendrick Lamar: O Poeta Que Virou Pulitzer

    Kendrick Lamar: O Poeta Que Virou Pulitzer

    Em 16 de abril de 2018, algo impensável aconteceu no mundo da música: um rapper ganhou o Prêmio Pulitzer. Não era um artista de jazz. Não era um compositor clássico. Era Kendrick Lamar Duckworth, o garoto de Compton que transformou trauma, fé e política em poesia de rua — e levou o hip-hop ao patamar mais alto da cultura americana. O Pulitzer não apenas validou Kendrick; redefiniu o que a elite cultural entende por ‘alta arte’.

    Compton como Laboratório

    Nascido em 17 de junho de 1987, Kendrick cresceu em uma das cidades mais violentas dos Estados Unidos. Viu amigos morrerem, ouviu tiros como trilha sonora e encontrou na escrita uma válvula de escape. Aos 8 anos, assistiu Tupac Shakur e Dr. Dre gravando o clipe de ‘California Love’ — o momento que, segundo ele, definiu seu destino. Aos 16, já era conhecido como K-Dot nas batalhas de rima do bairro.

    Seu primeiro projeto, Overly Dedicated (2010), já mostrava um letrista obcecado por detalhes: cada verso era uma cena, cada música um curta-metragem. Mas foi com Section.80 (2011) que o mundo começou a prestar atenção. O álbum independente, lançado exclusivamente no iTunes, abordava a geração Reagan, o crack, a guerra às drogas e a crise de identidade da juventude negra. Dr. Dre ouviu e assinou na hora.

    Dali em diante, a trajetória foi meteórica. good kid, m.A.A.d city (2012) é um romance de formação em formato de álbum — uma narrativa cinematográfica sobre um adolescente tentando não ser engolido pelas ruas. A faixa ‘Sing About Me, I’m Dying of Thirst’ é frequentemente citada como uma das composições mais ambiciosas do rap contemporâneo: 12 minutos de storytelling que alternam perspectivas, narradores e registros emocionais como um romance de Faulkner.

    A Trilogia da Consciência

    Se good kid era sobre sobreviver a Compton, To Pimp a Butterfly (2015) foi sobre sobreviver à América. Misturando jazz, funk, spoken word e produção de ponta com Thundercat, Flying Lotus, Kamasi Washington e George Clinton, o álbum é um tratado sobre raça, depressão e autoestima coletiva. ‘Alright’ virou hino do movimento Black Lives Matter. ‘The Blacker the Berry’ é um soco no estômago — uma confissão de hipocrisia racial que nenhum artista pop teria coragem de fazer. ‘u’ é um ataque de pânico transformado em música. Nenhum álbum de hip-hop havia sido tão ambicioso musicalmente desde The Miseducation of Lauryn Hill — e, possivelmente, nenhum foi tão politicamente urgente.

    Então veio DAMN. (2017). Mais enxuto, mais acessível, mas igualmente denso. Kendrick inverteu a narrativa: e se a maldição não vier de fora, mas de dentro? E se o problema não for o sistema, e sim a alma? O álbum vendeu 603 mil cópias na primeira semana, gerou ‘HUMBLE.’ — seu primeiro número 1 solo na Billboard — e conquistou o Pulitzer. A citação do prêmio descreveu o álbum como ‘uma coleção de canções virtuosísticas, unificadas por sua autenticidade vernacular e dinamismo rítmico, que oferece momentos de grande impacto capturando a complexidade da vida afro-americana moderna’.

    O Silêncio Que Falou Mais Alto

    Mr. Morale & the Big Steppers (2022) foi o álbum mais difícil de Kendrick. Cinco anos de silêncio entre DAMN. e Mr. Morale. Terapia intensiva. Paternidade de dois filhos. O disco é desconfortável, confessional, às vezes difícil de ouvir — em ‘Mother I Sober’, Kendrick revela abusos familiares e traumas geracionais. Em ‘We Cry Together’, ele e a atriz Taylour Paige encenam uma briga de casal tão crua que beira o teatro documental. Não é um álbum feito para playlists; é um divã público.

    Em 2025, sua performance no Super Bowl LIX consolidou o arco. De Compton ao Super Bowl, do anonimato ao centro da cultura. Kendrick Lamar não é apenas o maior letrista do século XXI — é a prova viva de que o hip-hop não precisa pedir licença para ser tratado como literatura.

    O impacto de Kendrick vai muito alem dos numeros. Antes dele, o rap era tratado pela academia e pela critica estabelecida como ‘cultura popular’ — entretenimento, nao arte. Kendrick forcou a porta. Suas letras sao ensinadas em universidades. Seus albuns sao dissecados em cursos de literatura comparada. O rapper que um dia foi K-Dot nas batalhas de rua de Compton hoje divide espaco com James Joyce e Toni Morrison — e isso nao e hiperbole de fa. E o que acontece quando um artista trata cada compasso como literatura e cada album como legado.

    O Pulitzer de 2018 foi um ponto de inflexao, nao so para o hip-hop, mas para a propria definicao institucional do que e ‘musica seria’. A pergunta que Kendrick obrigou o mundo a fazer nao foi ‘rap pode ser arte?’ — isso ja estava respondido desde Illmatic de Nas e The Miseducation de Lauryn Hill. A pergunta foi mais incomoda: ‘por que demoramos tanto para admitir?’

  • Mestre Boca Rica

    Mestre Boca Rica

    A capoeira brasileira não se fez apenas na Bahia e no Rio de Janeiro. Pernambuco também tem uma tradição riquíssima, e entre seus maiores representantes está Mestre Boca Rica, ícone da capoeira do Recife. Com um estilo marcante e uma personalidade forte, ele se tornou referência para gerações de capoeiristas pernambucanos e brasileiros.

    Origens no Recife

    Mestre Boca Rica nasceu e cresceu no Recife, capital pernambucana, onde a capoeira tem características próprias. A capoeira pernambucana, embora ligada às tradições baiana e carioca, desenvolveu um sotaque particular, marcado por movimentos ágeis e por uma musicalidade que dialoga com o frevo e o maracatu.

    A tradição conta que Boca Rica se envolveu com a capoeira ainda jovem, nas ruas e praças do Recife. Sua dedicação e seu talento o levaram a se destacar rapidamente, conquistando o respeito dos mestres mais velhos e o reconhecimento da comunidade capoeirística local.

    Um estilo marcante

    Boca Rica ficou conhecido por seu jogo ágil e criativo, marcado por movimentos rápidos e imprevisíveis. Seu estilo refletia a energia do Recife, cidade de frevo e de carnaval, onde a velocidade e a ginga são marcas registradas da cultura popular.

    Além do jogo, Boca Rica se destacou pela musicalidade e pela liderança nas rodas. Capoeiristas que conviveram com ele descrevem uma figura carismática, capaz de comandar a roda com firmeza e de inspirar os mais jovens com seu exemplo. Essa combinação de técnica e carisma fez dele uma referência natural.

    A capoeira pernambucana

    A trajetória de Boca Rica está intimamente ligada à história da capoeira em Pernambuco. O estado, que já teve uma das mais fortes tradições capoeirísticas do país, viu essa tradição se transformar ao longo do século XX, com a capoeira ganhando espaço nas academias e nos eventos culturais.

    Mestres como Boca Rica foram fundamentais nesse processo, mantendo viva a chama da capoeira pernambucana e formando novas gerações. Seu trabalho ajudou a consolidar o Recife como um dos polos da capoeira brasileira, ao lado de Salvador e do Rio de Janeiro.

    A identidade pernambucana na roda

    A capoeira de Pernambuco tem traços que a distinguem de outras regiões. Relatos de praticantes e estudiosos apontam uma ênfase no jogo rápido e na movimentação contínua, além de uma forte ligação com as festas populares, como o frevo e o maracatu rural. Boca Rica soube incorporar esses elementos ao seu repertório, criando um jogo que era, ao mesmo tempo, tradicional e profundamente local.

    Essa identidade regional enriquece a capoeira brasileira como um todo. Assim como cada sotaque dá cor à língua, cada tradição regional dá cor à capoeira, mostrando que a arte não é um bloco único, mas um mosaico de experiências e influências.

    Mestre e formador

    Boca Rica não foi apenas um grande jogador: foi também um formador. Ao longo de sua trajetória, transmitiu seus conhecimentos a inúmeros alunos, muitos dos quais se tornaram mestres e seguiram difundindo a capoeira pernambucana pelo Brasil e pelo mundo. Sua dedicação ao ensino garantiu a continuidade de uma linhagem que valoriza a técnica, a música e o respeito às raízes.

    Capoeiristas formados por ele destacam a exigência e a generosidade do mestre. Boca Rica cobrava técnica e disciplina, mas também acolhia e incentivava quem demonstrava vontade de aprender. Essa postura fez dele uma figura respeitada e querida em toda a comunidade capoeirística.

    A influência na nova geração

    A influência de Mestre Boca Rica se estendeu muito além de sua própria geração. Muitos dos capoeiristas que hoje comandam grupos e academias em Pernambuco tiveram nele uma referência direta, seja como aluno, seja como admirador de seu estilo. Seu nome é citado com frequência nas rodas do estado, como sinônimo de técnica, energia e autenticidade.

    O estilo de Boca Rica, marcado pela agilidade e pela criatividade, influenciou a forma como a capoeira pernambucana é praticada. Mesmo grupos que seguem linhagens diferentes reconhecem nele uma matriz importante, que ajudou a dar identidade à capoeira do Recife e a projetá-la para o resto do país.

    Mais do que ensinar movimentos, Boca Rica transmitiu uma atitude: a de que a capoeira deve ser vivida com intensidade e com orgulho. Essa postura, aliada ao seu carisma, fez dele uma figura inspiradora, cujo exemplo continua a motivar os mais jovens a se dedicarem à arte com seriedade e paixão.

    Legado e memória

    Mestre Boca Rica faleceu deixando um legado que permanece vivo nas rodas de Pernambuco e de todo o Brasil. Seus alunos e discípulos continuam difundindo seu estilo e seus ensinamentos, garantindo que sua memória atravesse as gerações.

    A história de Boca Rica lembra que a capoeira é uma arte plural, com múltiplas raízes e sotaques. Do Recife à Bahia, do Rio ao mundo, cada mestre acrescentou seu tempero à arte, e é essa diversidade que faz da capoeira uma expressão tão rica e tão brasileira.

    Em Pernambuco, o legado de Boca Rica também se expressa na valorização da capoeira como patrimônio cultural do estado. A cada nova geração de capoeiristas pernambucanos, seu nome é invocado como exemplo de dedicação e de amor à arte, mantendo viva a memória de um dos grandes mestres que o Recife já produziu.

  • A Roda Que Girava Dentro da Roda

    A Roda Que Girava Dentro da Roda

    A Roda Que Girava Dentro da Roda

    No quinto ano do exílio, à margem de um rio que não era o seu, um sacerdote viu o céu se abrir. O ano, segundo os cálculos mais aceitos, era 593 antes da era comum; o lugar, o rio Quebar, na Babilônia; o homem, Ezequiel, da linhagem sacerdotal. O que ele viu — e descreveu com uma precisão que nenhum outro profeta empregou para falar de Deus — atravessou vinte e seis séculos sem perder nada de sua estranheza.

    Há textos que se leem; há textos que se atravessam. O primeiro capítulo de Ezequiel é destes últimos: uma nuvem de fogo vinda do norte, quatro seres vivos com quatro rostos, quatro asas, pernas retas e pés de metal polido e, junto a eles, rodas — rodas dentro de rodas, cheias de olhos ao redor, que se moviam sem se virar, porque o espírito das criaturas estava nas rodas. Por cima, um firmamento como cristal; por cima do firmamento, um trono de safira; sobre o trono, uma figura com o brilho do bronze incandescente. A mística judaica deu a essa visão um nome: Merkabah, o carro. E tratou-a, durante séculos, como o conhecimento mais perigoso que existia.

    O que sabemos

    Sabemos, primeiro, o que o texto diz. O relato de Ezequiel é obsessivamente técnico: materiais, direções, alturas, sons, movimentos. As rodas eram como o brilho de crisólito; havia uma roda dentro da outra; suas bordas eram altas e terríveis, cheias de olhos ao redor. O som das asas era como o ruído de muitas águas, como a voz do Todo-Poderoso, como o tumulto de um exército. Nada, em toda a Bíblia, descreve o trono divino com tamanha precisão mecânica — nem antes, nem depois.

    Sabemos, também, o que essa visão gerou. Em torno do capítulo primeiro de Ezequiel nasceu a mais antiga mística documentada do judaísmo, a tradição da Merkabah: a Mishná, no tratado Hagigá, proíbe ensinar o relato do Carro a um só discípulo; a literatura dos Hecalot, os palácios celestes, descreve ascensões em que o místico atravessa portais guardados para contemplar o Trono. Ezequiel não fundou apenas uma escola: fundou uma maneira de olhar para o céu como quem lê um diagrama.

    E sabemos, por fim, que no século XX um engenheiro de verdade se debruçou sobre o capítulo com ferramentas de engenheiro. Josef F. Blumrich, chefe do setor de projetos do Marshall Space Flight Center da NASA, começou a estudar o texto para desmontar as leituras ufológicas — e terminou escrevendo um livro, As Naves Espaciais de Ezequiel, publicado em 1974, no qual as rodas viram trens de pouso, as criaturas viram motores e o conjunto inteiro vira uma nave. O cético converteu-se em testemunha; o testemunho, em especificação.

    O que não sabemos

    Não sabemos o que Ezequiel viu — e, mais grave, não sabemos se ele mesmo sabia. Sua linguagem, no momento culminante, recua: ‘esta era a aparência da semelhança da glória do Senhor’. Aparência; semelhança. O profeta, que acabara de medir rodas e contar asas, recusa-se a nomear a coisa em si. Essa hesitação é a marca do testemunho autêntico: quem inventa, afirma; quem viu, hesita.

    Não sabemos, tampouco, o que eram os olhos nas rodas. Sensores? Estrelas? O espírito das criaturas dentro das rodas sugere algo que nenhuma leitura alegórica resolve com conforto: um sistema em que inteligência e mecanismo não se distinguem. E não sabemos por que a visão insiste em números — alturas, distâncias, materiais — se o que se queria transmitir era apenas a glória de Deus. A glória, na Bíblia, raramente vem acompanhada de cotas.

    O que está em jogo

    O que está em jogo é a fronteira entre o sagrado e o técnico. Se Ezequiel descreveu uma máquina, então o encontro de Quebar não pertence apenas à história da religião: pertence à história da tecnologia — e a Bíblia se torna, entre outras coisas, um relatório de encontro com algo que voava. Se descreveu apenas uma visão, resta explicar por que a visão fala a língua exata da engenharia: eixos, aros, cubos, alturas, velocidades, materiais. Em ambos os casos, uma certeza incômoda permanece: os antigos não careciam de precisão — careciam apenas de vocabulário. Ou talvez nós é que o tenhamos perdido.

    Quando Blumrich encerrou seu livro, escreveu que, se os fatos não cabem na explicação, talvez seja a explicação que precise mudar. Vinte e seis séculos depois da visão, ainda não decidimos se a roda que girava dentro da roda era um trono, uma nave ou um espelho. E talvez a pergunta verdadeira não seja o que Ezequiel viu, mas o que nos impede de ver o mesmo céu — e de admitir que, sobre o Quebar, algo esteve de fato lá em cima, girando, coberto de olhos, esperando que alguém tivesse a coragem de dar o nome certo.

  • ESP32 como interface física de um LLM local rodando via Ollama

    ESP32 como interface física de um LLM local rodando via Ollama

    Este é o primeiro artigo da série Assistentes de IA de Bancada. Aqui a gente monta a ponte entre um microcontrolador de bancada e um LLM rodando na sua máquina. A pergunta que guia o texto é simples: o que faz sentido rodar no ESP32 e o que deve ficar no host? A resposta curta — tudo que é inferência fica no host; o MCU cuida de entrada, saída e presença física.

    (a) Conceito e Arquitetura

    O ESP32 nunca vai rodar um LLM de verdade. Um modelo quantizado de 3B parâmetros ainda exige gigabytes de RAM e uma GPU decente. O que o MCU faz bem é ser a interface física do modelo: captura áudio, desenha estado, lê botões e envia texto. A arquitetura tem três camadas:

    1. Edge (ESP32-S3): Wi-Fi, I2S para microfone/alto-falante, display e lógica de interação. Protagoniza a experiência.
    2. Host (PC/Raspberry Pi): o Ollama serve o modelo localmente e expõe uma API compatível com OpenAI em http://localhost:11434/v1.
    3. Proxy (opcional): um pequeno serviço FastAPI que normaliza requisições, faz streaming SSE e converte áudio em texto (STT) quando necessário.

    O fluxo é: MCU grava o comando → host transcreve (ou recebe texto pronto) → Ollama gera a resposta → MCU recebe o texto final (ou tokens em streaming) e renderiza. O ponto crítico é que o estado da conversa vive no host; a placa é stateless. Isso simplifica OTA, permite trocar de modelo sem reflash e mantém o firmware pequeno.

    (b) BOM

    Item Modelo sugerido Função Faixa de preço (USD)
    MCU ESP32-S3-DevKitC-1 (N16R8) WROOM-1 com 16 MB flash + 8 MB PSRAM 8–14
    Display GC9A01 1.28″ 240×240 SPI Painel redondo para o “rosto” 4–7
    Áudio INMP441 (I2S MEMS) + MAX98357A Microfone digital + amp classe D 5–9
    Alto-falante 4Ω 3W 40 mm Saída de voz 2–4
    Alimentação Fonte 5V/2A + capacitor 470µF Evitar brownout no Wi-Fi TX 3–6
    Botão/Encoder Push-button 12 mm + KY-040 Push-to-talk e navegação 1–3
    Extra Cartão microSD (opcional) Cache de áudio/prompts 2–4

    Total realista: 25 a 45 dólares por unidade, sem contar o host — que pode ser o notebook que você já tem.

    (c) Wiring & Esquemático

    O segredo é separar os barramentos: I2S em pinos dedicados, o display SPI em outro conjunto e nada de compartilhar clock entre eles. Um mapeamento que funciona no DevKitC-1:

    • I2S microfone (INMP441): SCK=GPIO14, WS=GPIO15, SD=GPIO32, L/R→GND (canal esquerdo), VDD=3V3.
    • I2S saída (MAX98357A): BCLK=GPIO26, LRC=GPIO25, DIN=GPIO22, SD→3V3.
    • Display GC9A01: SCLK=GPIO12, MOSI=GPIO11, CS=GPIO10, DC=GPIO9, RST=GPIO8, BLK=GPIO7.
    • Botão: GPIO0 com pull-up (cuidado: é o pino de boot — segure só depois do boot, ou use GPIO4).

    Cuidados elétricos que evitam dor de cabeça:

    • O pico de corrente do Wi-Fi (transmissão) chega a ~500 mA. Um capacitor de 470µF entre 5V e GND, perto da placa, evita reset aleatório.
    • O MAX98357A puxa corrente pelo VIN; se alimentado em 3V3, a potência cai. Alimente em 5V e mantenha nível de sinal lógico — o chip é tolerante a 3V3.
    • Use fios curtos (< 15 cm) no I2S. Sinais de clock longos geram ruído audível.
    • Nunca ligue o pino RST do display em pull-up externo junto com o boot strap do S3 sem revisar o esquema — alguns módulos travam o boot.

    (d) Código

    Do lado do MCU, a ideia é: ler o prompt (via Serial ou STT), montar um JSON pequeno, fazer POST e parsear a resposta. Segue um esqueleto funcional em C++ (Arduino/PlatformIO) usando HTTPClient e ArduinoJson:

    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <ArduinoJson.h>
    
    const char* SSID = "lab-iot";
    const char* PASS = "senha-local";
    const char* ENDPOINT = "http://192.168.0.42:11434/v1/chat/completions";
    
    void setup() {
      Serial.begin(115200);
      WiFi.begin(SSID, PASS);
      while (WiFi.status() != WL_CONNECTED) { delay(200); }
      Serial.println("WiFi OK");
    }
    
    String askLLM(const String& prompt) {
      HTTPClient http;
      http.begin(ENDPOINT);
      http.setTimeout(60000);              // inferencia local pode demorar
      http.addHeader("Content-Type", "application/json");
    
      JsonDocument doc;
      doc["model"] = "llama3.2:3b";
      doc["stream"] = false;
      JsonArray msgs = doc["messages"].to<JsonArray>();
      JsonObject m = msgs.add<JsonObject>();
      m["role"] = "user";
      m["content"] = prompt;
    
      String body;
      serializeJson(doc, body);
    
      int code = http.POST(body);
      if (code != 200) { http.end(); return "ERRO HTTP " + String(code); }
    
      String payload = http.getString();
      http.end();
    
      JsonDocument resp;
      DeserializationError err = deserializeJson(resp, payload);
      if (err) return "JSON invalido";
      return resp["choices"][0]["message"]["content"].as<String>();
    }
    
    void loop() {
      if (Serial.available()) {
        String line = Serial.readStringUntil('\n');
        String out = askLLM(line);
        Serial.println(out);
      }
    }

    Do lado do host, o Ollama já fala o dialeto OpenAI nativamente. Se você precisar de streaming (tokens chegando aos poucos) ou de transcrição de áudio, um proxy FastAPI resolve:

    from fastapi import FastAPI, Request
    from fastapi.responses import StreamingResponse
    import httpx, json
    
    app = FastAPI()
    OLLAMA = "http://localhost:11434/api/chat"
    
    @app.post("/v1/chat/completions")
    async def proxy(req: Request):
        body = await req.json()
        payload = {
            "model": body.get("model", "llama3.2:3b"),
            "messages": body["messages"],
            "stream": True,
        }
    
        async def gen():
            async with httpx.AsyncClient(timeout=None) as c:
                async with c.stream("POST", OLLAMA, json=payload) as r:
                    async for line in r.aiter_lines():
                        if not line:
                            continue
                        chunk = json.loads(line)
                        tok = chunk.get("message", {}).get("content", "")
                        if tok:
                            # formata como SSE estilo OpenAI
                            yield "data: " + json.dumps(
                                {"choices": [{"delta": {"content": tok}}]}
                            ) + "\n\n"
            yield "data: [DONE]\n\n"
    
        return StreamingResponse(gen(), media_type="text/event-stream")
    

    Com streaming, o ESP32-S3 parseia SSE linha a linha. Não monte um buffer gigante: processe cada data: assim que chegar e libere a linha. A placa tem 8 MB de PSRAM, mas a pilha HTTP é o gargalo real.

    (e) Troubleshooting — latência, contexto e PSRAM

    A primeira decepção de quem monta isso é a latência. Um modelo 3B em CPU leva de 1 a 4 segundos até o primeiro token; em GPU, algumas centenas de ms. Some o round-trip Wi-Fi (~30–80 ms) e o tempo de TTS. Resultado honesto: uma resposta falada em 5–8 s. Para conversa natural, pré-carregue o modelo (ollama run mantém em memória) e use keep_alive longo.

    Contexto come tokens e RAM no host. Envie apenas o histórico relevante; corte janelas antigas. No MCU, o pior erro é tentar guardar o histórico inteiro em String — use nomes fixos e um único buffer rotativo.

    PSRAM: habilite CONFIG_SPIRAM e, se usar o framework Arduino, ative PSRAM em qualquer alocação de framebuffer. Sem PSRAM, o heap interno (~320 KB) estoura ao abrir um socket TLS ou um buffer de áudio. Regra prática: buffers > 8 KB vão para PSRAM.

    O que travar na placa vs. delegar ao host:

    • Na placa: detecção de wake word, debounce de botão, render de animação, timeout de rede, buffer de áudio, TLS (se necessário).
    • No host: inferência, histórico de conversa, embeddings, STT/TTS de alta qualidade, guardrails e roteamento de modelo.

    Outros clássicos: brownout em TX Wi-Fi (capacitor + fonte boa), HTTPClient sem timeout (trava o loop) e JSON com caracteres escapados que quebram o parse — sempre serialize com biblioteca, nunca concatene strings na mão.

    (f) Aplicações reais

    • Painel de bancada do dev: pergunte à placa sobre logs, regex ou nomes de flags sem sair do terminal. O modelo roda offline e não vaza código para a nuvem.
    • Terminal de laboratório: em bancadas com rede isolada, o LLM local responde dúvidas de pinagem, datasheet e fórmulas.
    • Interface para acessibilidade: entrada por voz + saída no display para quem não usa teclado.
    • Protótipo de produto: valide UX de um “assistente de mesa” antes de decidir sobre hardware custom e certificação.
    • Base da série: nos próximos artigos, esta mesma arquitetura recebe display com LVGL, animações de estado e integração com o firmware open-source xiaozhi-esp32.

    Privacidade é o argumento mais forte: nada sai da sua rede. Custo marginal zero por consulta. E o melhor — você aprende de verdade onde está o gargalo, porque ele aparece na sua frente em cada iteração.

  • O Silêncio Também É Som: John Cage, 4’33” e a Música Que Não Toca

    O Silêncio Também É Som: John Cage, 4’33” e a Música Que Não Toca

    29 de agosto de 1952. Woodstock, Nova York. O pianista David Tudor caminha até o centro do palco do Maverick Concert Hall, uma sala de concertos rústica no meio da floresta. Senta-se diante de um piano de cauda. Abre a partitura. Fecha a tampa do teclado. E não toca uma única nota. Durante 4 minutos e 33 segundos — divididos em três movimentos, cronometrados com um cronômetro —, a plateia ouve o que há para ser ouvido: o vento nas árvores que cercam o teatro, gotas de chuva no telhado de madeira, tosses abafadas, o rangido das cadeiras, a própria respiração. Ao final do terceiro movimento, Tudor levanta-se lentamente, faz uma reverência e sai do palco. Estava executada, pela primeira vez, a obra mais radical e mais incompreendida da história da música ocidental: “4’33””, de John Cage.

    Cage não estava fazendo uma piada. Não era provocação dadaísta vazia, não era trollagem acadêmica, não era uma crítica cíclica ao establishment musical. Era filosofia sonora em estado puro — uma ideia que ele levou anos para ter coragem de executar. O compositor americano passara a década anterior estudando seriamente budismo zen com o mestre D. T. Suzuki na Universidade Columbia, absorvendo conceitos como vacuidade, não-intencionalidade e atenção plena. Visitara também a câmara anecoica da Universidade Harvard — um ambiente cientificamente projetado para absorver todo som refletido, o lugar mais silencioso do mundo. E, para seu espanto, dentro da câmara, ainda ouviu dois sons: um grave, que os engenheiros identificaram como sua própria circulação sanguínea, e um agudo, que era o funcionamento de seu sistema nervoso. A conclusão foi devastadora do ponto de vista filosófico: o silêncio absoluto não existe. Não é alcançável. O universo é som — contínuo, inescapável, onipresente. O que chamamos de silêncio é apenas nossa incapacidade de ouvir o que já está soando.

    “4’33”” reformula radicalmente a pergunta fundamental da música ocidental. Não se trata mais de “o que o compositor escreveu?” ou “o que o intérprete está tocando?”, mas de “o que você — você, aí, sentado na plateia, com seus ouvidos, sua atenção, sua presença — está ouvindo neste exato momento?”. Cage desloca o centro de gravidade da música do emissor para o receptor, da intenção autoral para a atenção do ouvinte. O conteúdo da peça não são as notas que Cage deliberadamente não escreveu — são os sons que o mundo oferece quando paramos de tentar controlá-lo, de tentar impor nossa vontade sobre o ambiente sonoro. É uma meditação sobre a escuta como ato criativo. O público, sem saber, torna-se o instrumento. O teatro, o mundo, a chuva — a orquestra.

    As reverberações de “4’33”” na música contemporânea são onipresentes, embora frequentemente não reconhecidas como tal. Brian Eno, discípulo indireto de Cage, transformou a ideia de que o ambiente é música no conceito explícito de “ambient music” — sons que, em suas palavras, devem ser “tão ignoráveis quanto interessantes”, música que não exige sua atenção mas recompensa se você a oferecer. O lo-fi hip hop, com sua estética de baixa fidelidade, texturas de fundo e samples que flutuam em vez de se impor, é um descendente direto dessa linhagem cage-iana. O ASMR — fenômeno colossal do YouTube com centenas de bilhões de visualizações — explora precisamente o território que Cage mapeou sete décadas antes: sons mínimos, quase inaudíveis, sussurros, estalos, texturas sonoras que ativam respostas neurológicas de prazer e relaxamento justamente por habitarem o limiar entre som e silêncio. John Cage teria adorado o ASMR. Provavelmente teria feito uma peça com ele.

    Mas o legado de Cage é mais profundo e mais urgente do que seu impacto estilístico ou suas ramificações nos gêneros musicais contemporâneos. Ele reformulou a própria ontologia da música — a pergunta sobre o que a música é. Se qualquer som pode ser música, então a música não está no objeto sonoro, na partitura, no instrumento, na técnica. Está no gesto de escutar. Isso tem implicações que vão muito além do mundo das artes. Vivemos numa era de ruído constante e inescapável. Notificações, feeds infinitos, alertas de aplicativos, streams automáticos, podcasts em velocidade 2x, playlists algorítmicas que nunca terminam — uma paisagem sonora digital que nunca, em momento algum, se cala. A lição mais urgente de Cage para 2026 é que a escuta verdadeira exige uma forma de silêncio que nossa cultura tecnológica sistematicamente destrói. Não o silêncio como ausência de som — Cage já provou que isso é fisicamente impossível. Mas o silêncio como presença deliberada de atenção. Desligar para ouvir.

    Em 2026, 74 anos após a estreia, “4’33”” permanece tão perturbadora quanto no dia em que foi concebida. Não porque seja difícil de executar — qualquer pessoa, em qualquer lugar do mundo, pode tocá-la agora mesmo. Mas porque exige algo que a vida moderna nos treinou meticulosamente a não oferecer: parar completamente. Fechar os olhos. Abrir os ouvidos — não para o que você escolheu ouvir, mas para o que já está soando. E aceitar, com humildade filosófica, que o universo já está tocando sua música. Basta que alguém escute.

    Fontes

  • Capoeira na Escola

    Capoeira na Escola

    A escola é um espaço de formação integral, e a capoeira tem se mostrado uma aliada poderosa nesse processo. Cada vez mais presente no ambiente escolar, a arte brasileira une atividade física, cultura, história e valores, ensinando muito além dos movimentos. A capoeira na escola é, antes de tudo, uma ferramenta de educação para a vida.

    Uma atividade completa

    A capoeira oferece às crianças e aos jovens uma atividade física completa e prazerosa. A ginga, os chutes, as esquivas e as acrobacias desenvolvem coordenação motora, força, flexibilidade e equilíbrio, de forma lúdica e integrada. Em tempos de sedentarismo e excesso de telas, a capoeira surge como uma alternativa que une movimento e diversão.

    Além dos benefícios físicos, a prática regular melhora a concentração e a disciplina, habilidades fundamentais para o desempenho escolar. Aprender uma sequência de movimentos ou acompanhar o ritmo do berimbau exige atenção e memória, competências que se transferem para a sala de aula.

    História e identidade

    A capoeira é também um conteúdo pedagógico rico. Por meio dela, os alunos entram em contato com a história do Brasil, com a luta dos africanos escravizados, com a formação da cultura afro-brasileira e com temas como liberdade, resistência e identidade. A capoeira dá vida à história, transformando o passado em experiência vivida.

    Essa dimensão é especialmente importante num país como o Brasil, cuja formação está profundamente marcada pela herança africana. A capoeira na escola contribui para o reconhecimento e a valorização dessa herança, fortalecendo a autoestima dos alunos e o respeito à diversidade.

    Valores e convivência

    A roda de capoeira é uma escola de valores. O respeito ao mestre, a hierarquia da bateria, a cooperação do coro e a malícia do jogo ensinam lições de convivência, humildade e solidariedade. Na roda, ninguém joga sozinho: o jogo é sempre uma relação, e isso ensina a importância do outro.

    Muitos professores relatam mudanças significativas no comportamento dos alunos que praticam capoeira: mais disciplina, mais respeito pelos colegas e maior capacidade de trabalhar em grupo. A capoeira forma cidadãos, e não apenas atletas.

    Benefícios cognitivos e emocionais

    Os ganhos da capoeira na escola vão além do corpo e do comportamento. Pesquisas na área da educação indicam que atividades que combinam movimento, música e ritmo estimulam o cérebro, favorecendo a memória, a linguagem e a capacidade de resolução de problemas. A capoeira, ao exigir a leitura do jogo e a resposta rápida aos movimentos do parceiro, exercita justamente essas competências.

    No plano emocional, a capoeira ajuda a desenvolver autoconfiança e controle das emoções. A criança que aprende a cair e a se levantar, a respeitar o colega e a se apresentar na roda constrói, aos poucos, uma imagem mais segura de si. Para alunos tímidos ou com dificuldades de socialização, a roda costuma ser um espaço acolhedor de descoberta.

    A capoeira e a lei

    Vale lembrar que a presença da capoeira na escola dialoga com a legislação brasileira. A Lei 10.639, de 2003, tornou obrigatório o ensino da história e da cultura afro-brasileira nas escolas. A capoeira é uma porta de entrada privilegiada para esse conteúdo, pois une teoria e prática de forma viva e envolvente.

    Ao levar a capoeira para a sala de aula, a escola não apenas cumpre uma determinação legal: ela reconhece a contribuição dos povos africanos à formação do Brasil. É uma forma concreta de combater o preconceito e de promover uma educação antirracista, baseada no conhecimento e no respeito.

    A capoeira e o combate ao preconceito

    A capoeira também pode ser uma poderosa ferramenta de combate ao preconceito racial e à intolerância. Ao apresentar a história dos africanos e afrodescendentes de forma positiva e contextualizada, ela ajuda a desconstruir estereótipos e a promover o respeito entre os alunos. A roda, com sua diversidade de corpos, origens e histórias, é um exemplo concreto de convivência respeitosa.

    Em muitas escolas, projetos de capoeira surgiram justamente como resposta a situações de bullying e de discriminação. A prática coletiva ensina que as diferenças são bem-vindas, e que a força de cada um se soma à do grupo. O aluno que antes se sentia excluído encontra na roda um espaço de acolhimento e de reconhecimento.

    Para que esse potencial se realize, é importante que professores e mestres estejam preparados para trabalhar também a dimensão histórica e cultural da capoeira. Não basta ensinar os movimentos: é preciso contextualizar, explicar a origem da arte e valorizar a contribuição africana. Só assim a capoeira cumpre, na escola, seu papel transformador.

    Inclusão e pertencimento

    A capoeira é uma prática inclusiva por natureza. Não exige equipamentos caros, pode ser praticada por pessoas de diferentes idades e condições físicas, e acolhe a todos na roda, sem distinção. Na escola, essa característica é valiosa, pois cria um espaço de pertencimento para alunos que muitas vezes se sentem à margem.

    Integrar a capoeira ao currículo escolar é, portanto, apostar numa educação mais completa, humana e conectada com a cultura brasileira. É oferecer aos alunos uma ferramenta que fortalece o corpo, enriquece a mente e alimenta a alma.

  • O Irmão Que Desceu em Todas as Línguas

    O Irmão Que Desceu em Todas as Línguas

    O Irmão Que Desceu em Todas as Línguas

    Existe uma frase que se repete em todas as línguas antigas do mundo: “eles desceram”. Na Mesopotâmia, os Anunnaki desceram do céu para criar e governar. No norte gelado, os Æsir desceram e fizeram guerra no céu. No México, Quetzalcóatl desceu para ensinar e partiu prometendo voltar. Nos Andes, Viracocha desceu das águas e caminhou entre os homens. No Japão, Ninigi desceu da Planície do Alto Céu para fundar um trono. A pergunta desta série sempre foi esta: por que todas as culturas, separadas por oceanos e séculos, contaram a mesma história?

    O irmão que desce — o ser do céu que chega à terra, ensina, domina ou se mistura — é talvez o personagem mais recorrente da mitologia mundial. Este é o fechamento da nossa jornada: uma tentativa de olhar para o padrão inteiro, do ponto de vista da mitologia comparada, e perguntar o que ele significa.

    O que sabemos: a gramática comum dos mitos

    Sabemos, primeiro, que o padrão existe — e é impressionantemente estável. Em cada versão, o ser celeste desce com um propósito civilizador: ensina a agricultura, o calendário, as artes, as leis. Em muitas versões, funda uma linhagem — Amaterasu envia Ninigi, e o trono japonês nasce do céu. Em outras, parte — Quetzalcóatl pelo mar, Viracocha sobre as águas — e promete voltar. Em algumas, fica e domina, como os Anunnaki que, no Enuma Elish e na epopeia de Gilgamesh, aparecem como senhores absolutos da terra. O estudioso que mapeou essa gramática foi Joseph Campbell, cujo O Herói de Mil Faces (1949) mostrou que os mitos do mundo inteiro compartilham uma estrutura profunda — o monomito — como se houvesse uma única história sendo contada em mil dialetos. Campbell lia os mitos como “máscaras de Deus”: símbolos de uma verdade interior, não relatos de eventos.

    Ao lado dele, Carl Jung falava de inconsciente coletivo e arquétipos: imagens herdadas, gravadas no próprio hardware da psique humana, que se manifestam em todos os povos. E Mircea Eliade, historiador das religiões, descreveu o mito do eterno retorno: a espera do retorno é estrutural, porque o tempo sagrado é cíclico. Para essa escola, o irmão que desce não desceu jamais — nós é que nascemos olhando para cima.

    No outro extremo, houve quem lesse os mitos como memória literal. Erich von Däniken, em Eram os Deuses Astronautas? (1968), e Zecharia Sitchin, com sua leitura dos Anunnaki como visitantes do planeta Nibiru, transformaram os deuses em astronautas. A ciência rejeitou essas leituras como pseudociência — mas elas continuam fascinando porque tocam em uma ferida real: a insuficiência das explicações puramente simbólicas diante de um padrão tão global.

    O que não sabemos: sonho ou memória

    E aqui está o abismo: não sabemos se todas as culturas sonharam o mesmo sonho ou se todas lembraram do mesmo céu. Se for sonho, o arquétipo explica tudo — o cérebro humano, diante do mesmo céu noturno, produz as mesmas imagens: a luz que desce, o professor que parte, o retorno prometido. Se for memória, então houve um evento — um encontro, uma visão, algo visto no céu por todas as civilizações nascentes — e os mitos são testemunhos, não ficção. Entre uma e outra hipótese não há experimento possível: os deuses não deixam fósseis. O que deixam é essa insistência, essa repetição obstinada: “eles desceram”.

    O que está em jogo: a nossa posição no universo

    O que está em jogo é a nossa posição na ordem das coisas. Se o irmão que desce é arquétipo, então o céu é um espelho: nós projetamos nele as nossas perguntas, e a ufologia moderna — com seus fenômenos aéreos não identificados, agora estudados por governos e agências espaciais — seria apenas o mito mais recente, vestido de radar. Se o irmão que desce é memória, então o céu é um endereço: algo esteve aqui, e o retorno prometido por Quetzalcóatl, Viracocha e Amaterasu seria não poesia, mas agenda. A NASA continua varrendo o céu, e o céu continua não respondendo — ou respondendo de formas que preferimos chamar de anomalias.

    O fechamento: a pergunta final

    Quatro deuses, quatro partidas, quatro promessas — e um único padrão. Ou todas as culturas sonharam o mesmo sonho, ou todas lembraram do mesmo céu; não há terceira porta, e nenhuma das duas pode ser provada. Talvez Campbell estivesse certo, e os mitos sejam as máscaras que Deus usa para ser contado por homens. Talvez estivessem certos os povos, e o irmão realmente tenha descido. Nesta série, atravessamos guerras celestes, cavernas de luz, serpentes emplumadas e mantos sobre o mar — e a pergunta final é a mesma que abriu tudo: se um dia o irmão descer de novo, em todas as línguas ao mesmo tempo, e a humanidade inteira reconhecer a história que já contava desde o princípio — será que vamos recebê-lo como quem recebe um deus, como quem recebe um estranho, ou como quem, finalmente, se reconhece? O céu continua aberto. A pergunta continua no ar.

  • Assistente de Bancada com Wake Word e Voz Local: ESP32-S3 + ESP-SR/WakeNet + Microfone I2S

    Assistente de Bancada com Wake Word e Voz Local: ESP32-S3 + ESP-SR/WakeNet + Microfone I2S

    Este é o artigo de montagem da série Assistentes de IA de Bancada. Aqui o foco é o caminho mais longo e mais recompensador: um assistente que acorda com uma palavra-chave detectada localmente, no próprio ESP32-S3, sem depender de nuvem para ouvir. Se você ainda não viu o panorama dos repositórios, comece por ele — este texto assume aquela base e desce ao hardware, à pinagem e ao firmware.

    (a) Conceito e Arquitetura

    O pipeline tem seis estágios. O microfone MEMS entrega amostras por I2S; o AFE do ESP-SR faz a limpeza do sinal (cancelamento de eco, supressão de ruído e controle automático de ganho); o WakeNet observa continuamente esse fluxo e dispara quando reconhece a palavra-chave. A partir daí o áudio do comando é bufferizado e enviado — via Wi-Fi — para um backend de ASR/LLM (nuvem ou Ollama local). A resposta volta em texto, passa por TTS e sai pelo amplificador I2S.

    O ponto crítico é que os três primeiros estágios rodam 100% no MCU. A nuvem só entra depois do wake word, o que reduz consumo, custo e exposição de dados. É aqui que este projeto se diferencia de um assistente de voz genérico: o objetivo não é conversar abertamente o tempo todo, e sim ter um companheiro de bancada que responde quando chamado, com latência de gatilho abaixo de 100 ms.

    (b) BOM

    Componente (modelo) Função Faixa de preço (BRL)
    ESP32-S3-DevKitC-1 (N16R8, 16 MB flash / 8 MB PSRAM) MCU principal: Wi-Fi/BLE, PSRAM para AFE + WakeNet R$ 60–120
    INMP441 Microfone MEMS I2S 24-bit, 60 Hz–15 kHz R$ 15–30
    MSM261S4030H0 (alternativa) Microfone I2S usado em devkits Espressif R$ 20–40
    MAX98357A Amplificador I2S classe D, 3,2 W R$ 20–35
    Alto-falante 4 Ω / 3 W Saída de áudio (TTS/retorno) R$ 10–25
    Display ST7789 1,3″ SPI (ou ILI9341) Feedback visual / UI LVGL (nível de áudio, status) R$ 35–70
    Botão tátil + LED Push-to-talk e status de estado R$ 2–5
    Protoboard / PCB + jumpers Montagem e cabeamento R$ 15–30

    (c) Wiring & Esquemático

    Sinal Periférico GPIO (ESP32-S3) Observações
    VDD INMP441 3V3 Fonte 3,3 V dedicada; adicione 100 nF perto do pino
    GND INMP441 GND Referência comum
    SCK (BCLK) INMP441 GPIO14 Clock de bits, gerado pelo ESP32 (master)
    WS (LRCLK) INMP441 GPIO15 Seleção de canal/word select
    SD (DIN) INMP441 GPIO32 Dados do mic para o MCU
    L/R INMP441 GND GND = canal esquerdo
    VIN MAX98357A 5V Use o rail 5 V, não o 3V3, em volume alto
    BCLK MAX98357A GPIO26 Clock de bits do I2S de saída
    LRC MAX98357A GPIO25 Word select de saída
    DIN MAX98357A GPIO22 Dados do MCU para o amp
    SD MAX98357A 3V3 Enable; em nível baixo o amp silencia
    CS / DC / RST ST7789 GPIO5 / GPIO4 / GPIO2 Barramento SPI do display

    Cuidados elétricos. Wi-Fi somado a PSRAM produz picos de corrente: use fonte de 5 V/2 A e um capacitor de 470 µF–1000 µF no rail de 3,3 V. Não alimente o amplificador pelo 3V3 do devkit se for operar em volume alto. Todos os periféricos aqui são de nível lógico 3,3 V, então não há divisor de nível. Para o botão, basta o pull-up interno do MCU (ou 10 kΩ externo). Atenção aos strapping pins do ESP32-S3 — GPIO0, GPIO3, GPIO45 e GPIO46: não deixe nenhum deles puxado para o nível errado no boot, pois isso altera o modo de inicialização. No I2S, mantenha o BCLK curto e longe das trilhas de RF; o INMP441 não precisa de MCLK, apenas BCLK e WS.

    (d) Código e Firmware

    Inicialização do I2S de captura (ESP-IDF 5.x):

    #include "driver/i2s_std.h"
    
    i2s_chan_handle_t rx_chan;
    
    void i2s_mic_init(void) {
        i2s_chan_config_t chan_cfg =
            I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
        chan_cfg.dma_desc_num  = 6;
        chan_cfg.dma_frame_num = 240;      // ~15 ms a 16 kHz
        i2s_new_channel(&chan_cfg, NULL, &rx_chan);
    
        i2s_std_config_t std_cfg = {
            .clk_cfg  = I2S_STD_CLK_DEFAULT_CONFIG(16000),
            .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(
                            I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
            .gpio_cfg = {
                .mclk = I2S_GPIO_UNUSED,
                .bclk = GPIO_NUM_14,
                .ws   = GPIO_NUM_15,
                .dout = I2S_GPIO_UNUSED,
                .din  = GPIO_NUM_32,
            },
        };
        std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT;
        i2s_channel_init_std_mode(rx_chan, &std_cfg);
        i2s_channel_enable(rx_chan);
    }

    Wake word com ESP-SR (AFE + WakeNet):

    #include "esp_afe_sr_iface.h"
    #include "esp_afe_sr_models.h"
    #include "model_path.h"
    
    static const esp_afe_sr_iface_t *afe = &ESP_AFE_SR_HANDLE;
    static esp_afe_sr_data_t        *afe_data;
    
    void wakenet_init(void) {
        srmodel_list_t *models = esp_srmodel_init("model");
        afe_config_t cfg = AFE_CONFIG_DEFAULT();
        cfg.wakenet_model_name = esp_srmodel_filter(
            models, ESP_WN_PREFIX, NULL);   // ex.: "wn9_hilexin"
        cfg.aec_init = false;
        cfg.pcm_config.total_ch_num = 1;
        cfg.pcm_config.mic_num      = 1;
        cfg.pcm_config.ref_num      = 0;
        cfg.pcm_config.sample_rate  = 16000;
        afe_data = afe->create_from_config(&cfg);
    }
    
    bool espera_wake_word(void) {
        int chunk = afe->get_feed_chunksize(afe_data);
        int16_t *buf = heap_caps_malloc(chunk * sizeof(int16_t),
                                        MALLOC_CAP_SPIRAM);
        while (1) {
            size_t n;
            i2s_channel_read(rx_chan, buf, chunk * sizeof(int16_t),
                             &n, portMAX_DELAY);
            afe->feed(afe_data, buf);
            afe_fetch_result_t *r = afe->fetch_with_delay(afe_data, 0);
            if (r && r->wakeup_state == WAKENET_DETECTED) return true;
        }
    }

    Conexão Wi-Fi (station):

    #include "esp_wifi.h"
    #include "esp_event.h"
    #include "nvs_flash.h"
    
    void wifi_init_sta(const char *ssid, const char *pass) {
        nvs_flash_init();
        esp_netif_init();
        esp_event_loop_create_default();
        esp_netif_create_default_wifi_sta();
    
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        esp_wifi_init(&cfg);
    
        wifi_config_t wc = { 0 };
        strncpy((char *)wc.sta.ssid,     ssid, sizeof(wc.sta.ssid));
        strncpy((char *)wc.sta.password, pass, sizeof(wc.sta.password));
    
        esp_wifi_set_mode(WIFI_MODE_STA);
        esp_wifi_set_config(WIFI_IF_STA, &wc);
        esp_wifi_start();
        esp_wifi_connect();          // aguarde WIFI_EVENT_STA_GOT_IP
    }

    Chamada HTTP ao backend (LLM local ou nuvem):

    #include "esp_http_client.h"
    
    void pergunta_ao_llm(const char *json_body, char *saida, size_t max) {
        esp_http_client_config_t cfg = {
            .url        = "https://api.exemplo.com/v1/chat",
            .method     = HTTP_METHOD_POST,
            .timeout_ms = 8000,
        };
        esp_http_client_handle_t c = esp_http_client_init(&cfg);
        esp_http_client_set_header(c, "Content-Type",  "application/json");
        esp_http_client_set_header(c, "Authorization", "Bearer SUA_CHAVE");
        esp_http_client_set_post_field(c, json_body, strlen(json_body));
        esp_http_client_perform(c);
        int len = esp_http_client_read_response(c, saida, max - 1);
        if (len < 0) len = 0;
        saida[len] = '\0';
        esp_http_client_cleanup(c);
    }

    (e) Troubleshooting

    • PSRAM: o AFE e o WakeNet exigem memória contínua grande. Habilite PSRAM no menuconfig (CONFIG_SPIRAM) e aloque os buffers com heap_caps_malloc(…, MALLOC_CAP_SPIRAM). Sem PSRAM, o create_from_config falha ou o sistema reinicia por falta de memória.
    • Buffer I2S: estalos e cortes quase sempre vêm de DMA mal dimensionado. Ajuste dma_frame_num para múltiplos do chunksize do AFE (~15 ms) e aumente dma_desc_num se houver underrun. Confirme sample_rate = 16000 e slot de 32 bits (o INMP441 devolve dados alinhados à esquerda).
    • Falsos positivos: ganho alto demais é a causa número um. O AGC do AFE ajuda, mas calibre o nível de entrada, mantenha distância fixa do microfone e evite fontes de ruído contínuo perto do mic. Em ambiente barulhento, um modelo de wake word específico rende mais que aumentar o limiar.
    • Latência: separe a tarefa de áudio da tarefa de rede. Não bloqueie o loop do I2S esperando o HTTP; envie o comando para uma fila e deixe a resposta chegar por evento. Para respostas curtas, streaming por linhas JSON reduz a sensação de espera. Se a latência de nuvem incomodar, o backend local via Ollama elimina o RTT de internet.

    (f) Aplicações reais

    • Companheiro de bancada que registra comandos de voz durante a montagem, sem tirar as mãos do protótipo.
    • Interface de laboratório: acionar roteiros de teste, iniciar gravação de logs ou consultar status por voz.
    • Nó de automação doméstica local-first, no qual o gatilho nunca sai do dispositivo.
    • Base de acessibilidade auditiva/motora, com retorno por display e áudio em uma única placa.
    • Plataforma de estudo de DSP embarcado: trocar modelos de wake word e medir falsos positivos e latência.

    Para o panorama dos repositórios e das APIs, volte ao artigo anterior desta série. Para o contexto de voz offline, veja o material sobre assistentes de voz offline e a série J.A.R.V.I.S.; para o runtime de modelo, o texto sobre LLMs locais; e para a integração com hardware, a discussão de Edge AI. Os dois posts formam o par estratégia + montagem de um assistente de bancada.

  • O Repente e a Poesia Improvisada: O Rap Antes do Rap

    O Repente e a Poesia Improvisada: O Rap Antes do Rap

    Muito antes de os primeiros MCs do Bronx subirem num palco improvisado com dois toca-discos e um microfone, o sertão nordestino já pulsava com batalhas de improviso. O repente — e sua variante mais acelerada e urbana, a embolada — é essencialmente uma batalha de rimas que vem sendo travada há mais de um século sob o sol impiedoso do semiárido brasileiro. Dois violeiros se encaram diante de uma plateia de trabalhadores rurais. Um lança um verso em métrica rigorosa. O outro responde, na hora, no mesmo ritmo, com a mesma rima, sem hesitar. É freestyle. É slam poetry. É jazz scat. É anterior a todos eles — e a maioria dos brasileiros nunca fez essa conexão.

    A cantoria de viola — a forma mais tradicional do repente — segue regras tão rigorosas quanto qualquer forma poética erudita europeia. Os cantadores precisam dominar dezenas de modalidades métricas diferentes: sextilhas (estrofes de seis versos), décimas (dez versos, a mais nobre e difícil), martelos agalopados (ritmo acelerado para temas heroicos), galopes à beira-mar (andamento mais lento e contemplativo). Cada uma dessas modalidades tem sua própria cadência, suas próprias restrições de rima, suas próprias convenções temáticas. E, ainda assim, todo o conteúdo é criado no exato momento da performance, diante de uma plateia que conhece as regras tão bem quanto os poetas e não perdoa um erro de métrica ou uma rima forçada. Ivanildo Vila Nova, pernambucano de 80 anos e um dos maiores repentistas vivos do Brasil, compara o improviso a “pensar em voz alta com métrica e rima”. Não há ensaio. Não há segunda chance. Não há “volta e corrige”. A resposta tem que vir no compasso seguinte — ou o silêncio decreta a derrota. E a plateia vaia.

    A embolada é o primo urbano e acelerado do repente. Enquanto a cantoria de viola é frequentemente associada ao ambiente rural, às feiras e aos festejos de São João do interior, a embolada migrou para as cidades e trocou a viola pelo pandeiro — e acelerou o andamento até o limite da inteligibilidade humana. Popularizada nacionalmente por duplas como Caju e Castanha, pernambucanos que se tornaram presença constante na televisão brasileira nos anos 1990 e 2000, a embolada é uma torrente de palavras em alta velocidade que exige virtuosismo técnico e agilidade mental sobre-humanas. Caju e Castanha, com seu vozeirão e seu pandeiro, mostravam que o improviso nordestino não era coisa de museu folclórico — era entretenimento popular de primeiríssima qualidade, capaz de lotar auditórios, parar feiras e fazer qualquer apresentador de TV ficar boquiaberto com a velocidade e a inteligência das respostas.

    As semelhanças estruturais entre o repente e o rap são tão evidentes que chega a surpreender que a cultura brasileira tenha demorado tanto para explicitamente conectá-los. Ambos são formas de poesia performática baseadas em métrica rigorosa, rima elaborada e competição direta. Ambos surgiram como voz artística de comunidades marginalizadas — o sertanejo pobre e o jovem negro periférico. Ambos funcionam como crônica social imediata: o que aconteceu na feira, a última injustiça do patrão, a política local, a fofoca da vila, tudo vira verso. A diferença principal é tecnológica e instrumental: onde o MC tem um beat eletrônico ou sampleado, o repentista tem a viola de dez cordas; onde o rapper tem uma base produzida em software, o embolador tem o pandeiro e a força dos pulmões. Mas o gesto fundamental é idêntico: a palavra improvisada como afirmação de presença e inteligência no mundo.

    O slam poetry contemporâneo, fenômeno global que chegou ao Brasil nos anos 2010, é o elo que faltava para tornar visível essa genealogia oculta. A FLUP (Festa Literária das Periferias), realizada anualmente no Rio de Janeiro, e o Slam da Guilhermina, em São Paulo — um dos maiores slams do mundo em público —, criaram espaços onde as tradições do repente, do rap e da poesia falada contemporânea se encontram e se reconhecem. Nesses encontros, jovens poetas negros e periféricos frequentemente descobrem que o improviso que praticam tem raízes muito mais profundas do que o Bronx dos anos 1970 — raízes que passam pelo sertão nordestino, pelos griots da África Ocidental (contadores de histórias que improvisavam sobre acontecimentos da comunidade), pelos trovadores medievais da Europa, pelos repentistas cubanos que improvisam décimas ao som do tres. O improviso, no fim das contas, é uma das experiências humanas mais universais e antigas que existem.

    O documentário “O Fim do Sem Fim” (2001), dirigido por Cao Guimarães e Beto Magalhães, capturou esse universo com rara sensibilidade. O filme percorre o interior do Nordeste atrás de repentistas e cantadores cujas tradições estão desaparecendo — não por falta de talento ou relevância, mas por falta de registro, de apoio institucional, de políticas públicas de preservação. “Cartola — Música Para os Olhos” (2007), de Lírio Ferreira e Hilton Lacerda, embora centrado no samba, compartilha a mesma urgência documental: registrar vozes que o Brasil insiste em esquecer enquanto elas ainda podem ser ouvidas. Do partido alto carioca ao freestyle de rua, do repente nordestino ao jazz scat, dos griots do Mali às batalhas de slam de Chicago — a capacidade de criar, no calor do momento, algo que faça sentido rítmico e poético parece estar inscrita no que significa ser humano. Onde houver dois seres humanos com algo a dizer, haverá alguém rimando.

    Fontes