
Usar APIs públicas de IA no ESP32 é possível? Sim — e onde cada peça trabalha
Um modelo de linguagem de 28,9M parâmetros gera texto dentro de um ESP32-S3, a 9,5 tokens por segundo. A retificação, e onde cada peça trabalha.
Requisitos de hardware:
- Placa ESP32 ou ESP32-S3 com Wi-Fi
- Rede Wi-Fi com saída para internet
- Opcional: PC ou mini-servidor na mesma rede, para a parte do modelo local
Baixe o material deste tutorial:
- Projeto completo (ZIP)343 KBFirmware que consulta um modelo pelos dois caminhos: HTTP simples para um gateway na sua rede, ou HTTPS para a nuvem. Filtro de JSON, consulta não bloqueante, README e manual em PDF.
- Manual em PDF (7 páginas)417 KBComparativo entre nuvem e rede local, o custo de RAM do handshake TLS, filtro de JSON e checklist de dez itens.
Quer receber novos manuais e esquemas industriais? Entre no nosso canal do Telegram / WhatsApp
A pergunta que todo mundo faz
“Dá para colocar o ChatGPT dentro do ESP32?”
A resposta curta é que dá para o ESP32 conversar com esses modelos, e isso é bem diferente de rodar um dentro dele. Entender essa diferença é o que separa um projeto que funciona na bancada de um que funciona no campo — e é o assunto deste texto.
O que é, de fato, uma dessas IAs
Quando se fala em Gemini, ChatGPT ou Claude, está se falando de uma rede neural. Simplificando ao que interessa aqui: o modelo processou uma quantidade enorme de texto e guardou o que aprendeu na forma de bilhões de números, chamados de pesos.
Responder a uma pergunta significa fazer contas com todos esses números. Não é buscar uma resposta pronta em algum banco de dados — é cálculo, toda vez.
Guarde essa ideia, porque tudo o que vem a seguir decorre dela.
Por que os modelos grandes não rodam dentro da placa
A pergunta natural é: se é só um monte de números, por que não gravo na flash e rodo ali?
Depende do tamanho do modelo. Para os grandes, o limite não é espaço — é capacidade de cálculo e memória. Um ESP32 tem algumas centenas de kilobytes de RAM interna. Gemini, ChatGPT e Claude precisam de dezenas de gigabytes de memória de vídeo e de aceleradores dedicados só para responder em tempo aceitável. Esses ficam no datacenter, e não há arquitetura esperta que mude isso.
O que mudou desde a primeira versão deste texto é onde fica a fronteira do “pequeno” — e ela ficou bem mais longe do que se supunha. Há uma retificação sobre isso no fim do artigo.
Isso não é defeito do ESP32. São ferramentas para trabalhos diferentes: o servidor não fica cinco meses ligado num painel a 45 °C consumindo menos de um watt, e o ESP32 não faz álgebra linear em escala de datacenter. Cada um no seu posto.
Como o ESP32 conversa com o modelo: a API
API é o jeito de um programa conversar com outro. Para quem vem da automação, a analogia mais direta é esta: o ESP32 manda um valor para um servidor e recebe uma resposta — igual a consultar um equipamento remoto. A diferença é que esse “equipamento” é o modelo, está na internet, cobra por consulta e depende do link estar de pé.
Na prática: a placa conecta no Wi-Fi, faz uma requisição HTTPS para o endereço do fornecedor levando uma chave de acesso e lê o texto que volta.
| 1 | #include <WiFi.h> |
| 2 | #include <HTTPClient.h> |
| 3 | const char* WIFI_SSID = "SUA_REDE"; |
| 4 | const char* WIFI_PASS = "SUA_SENHA"; |
| 5 | // A chave fica gravada no firmware. Guarde esse detalhe: |
| 6 | // ele volta mais adiante no texto. |
| 7 | const char* API_URL = "https://api.exemplo.com/v1/chat"; |
| 8 | const char* API_KEY = "sua-chave-aqui"; |
| 9 | String perguntarAoModelo(const String& pergunta) { |
| 10 | HTTPClient http; |
| 11 | http.begin(API_URL); |
| 12 | http.addHeader("Content-Type", "application/json"); |
| 13 | http.addHeader("Authorization", String("Bearer ") + API_KEY); |
| 14 | String corpo = "{\"prompt\":\"" + pergunta + "\"}"; |
| 15 | int codigo = http.POST(corpo); |
| 16 | String resposta = (codigo == 200) ? http.getString() : String(""); |
| 17 | http.end(); |
| 18 | return resposta; |
| 19 | } |
| 20 | void setup() { |
| 21 | Serial.begin(115200); |
| 22 | WiFi.begin(WIFI_SSID, WIFI_PASS); |
| 23 | // Sem limite de tempo a placa fica presa aqui para sempre quando o Wi-Fi |
| 24 | // nao sobe — e o artigo trata justamente de depender do link. |
| 25 | unsigned long inicio = millis(); |
| 26 | while (WiFi.status() != WL_CONNECTED && millis() - inicio < 20000) { |
| 27 | delay(500); |
| 28 | Serial.print("."); |
| 29 | } |
| 30 | Serial.println(); |
| 31 | if (WiFi.status() != WL_CONNECTED) { |
| 32 | Serial.println("Sem Wi-Fi: nada a fazer sem o link."); |
| 33 | return; |
| 34 | } |
| 35 | Serial.println(perguntarAoModelo("Explique MQTT em uma frase.")); |
| 36 | } |
| 37 | void loop() { |
| 38 | // Exemplo minimo: uma consulta so, no boot. |
| 39 | } |
E funciona. A resposta aparece no monitor serial, e é um bom momento — você acabou de ligar um microcontrolador de poucos reais a um modelo que roda em datacenter.
É aqui que a maioria dos tutoriais termina. Vamos um passo além.
O que muda quando o projeto sai da bancada
Nada do que vem agora é defeito da placa. São características da arquitetura escolhida — pedir a decisão para um serviço que está longe. Cada uma delas é um critério para você decidir se essa arquitetura serve ao seu caso.
Dependência do link. A decisão só acontece se a internet estiver de pé. Para um projeto de mesa, tudo bem. Para um equipamento que precisa continuar operando quando a operadora cai, não serve — a decisão precisa ser local.
Tempo de resposta. Somando ida, processamento e volta, a resposta leva de centenas de milissegundos a alguns segundos. Se o seu processo tolera isso, ótimo. Se o ciclo da máquina é mais curto que a resposta, a decisão chega atrasada.
Custo por consulta. No teste é irrelevante. O número que importa é o de regime: multiplique por dispositivo, por ciclo, por turno, por mês. Faça essa conta cedo, ainda no projeto.
A chave no firmware. A chave de API fica gravada na placa, e firmware pode ser extraído de um dispositivo com acesso físico. Em bancada isso não importa; em equipamento instalado em campo, importa. Não existe jeito realmente seguro de guardar segredo em microcontrolador.
Para onde o dado vai. Cada consulta envia informação para fora da sua rede. Em projeto pessoal é irrelevante; em ambiente corporativo, costuma ser a primeira pergunta que fazem — e nem sempre é uma discussão técnica.
Repare no padrão: nenhum desses pontos é sobre o ESP32. Todos são sobre onde a conta é feita.
O meio do caminho: o modelo na sua própria rede
Entre “usar o da internet” e “não usar nada” existe um terceiro caminho: rodar um modelo menor dentro da sua própria rede. Ferramentas como o Ollama baixam o modelo para uma máquina sua e executam localmente.
Um ponto importante, porque é a confusão mais comum: o Ollama não roda no ESP32. Ele roda num PC, num mini-servidor ou num gateway. O ESP32 continua fazendo o que faz bem — coletar, medir e publicar.
Voltando à ideia do começo: não é que nada caiba fora do datacenter. O que não cabe são os modelos maiores. Um modelo menor, escolhido para uma tarefa específica, roda numa máquina comum — sem internet, sem mensalidade e sem o dado sair de onde está.
Veja o que essa mudança resolve: o link externo deixa de importar, o tempo de resposta cai muito, o custo por consulta desaparece e o dado permanece na sua rede. Quatro dos cinco pontos da seção anterior, com uma decisão de arquitetura. O que fica é o hardware do gateway — investimento único, e que é seu.
Onde o ESP32 brilha nessa arquitetura
O papel dele não muda, e é justamente o papel que nenhum servidor faz bem:
1. Ler sensor com temporização confiável, de forma contínua. 2. Reagir na hora ao que é crítico e não pode esperar resposta de rede. 3. Publicar o dado — MQTT, HTTP, Modbus — para quem vai analisar. 4. Continuar de pé por meses, com consumo baixo, em ambiente hostil.
A inteligência pesada mora no gateway, na mesma rede, a poucos milissegundos de distância. O ESP32 entrega o dado e recebe a conclusão, sem depender do mundo lá fora.
Existe ainda um quarto caminho: rodar um modelo dentro da própria placa. Por muito tempo isso significou apenas um classificador com TensorFlow Lite Micro — treinado para uma tarefa só, sem gerar texto. Continua sendo uma opção excelente e barata para decisão imediata. Mas o teto desse caminho subiu — hoje existe um modelo de linguagem rodando no ESP32-S3, com o passo a passo publicado — e é disso que trata a retificação a seguir.
Como escolher, na prática
Protótipo, prova de conceito, projeto pessoal: API pública. Rápido de montar, barato no volume de teste e você aprende bastante no caminho.
Equipamento em campo, com requisito de disponibilidade ou de privacidade: modelo local no gateway, ESP32 coletando.
Decisão que precisa ser imediata e é sempre a mesma pergunta: modelo pequeno embarcado, direto na placa.
Nos três casos o ESP32 faz o mesmo: ele é a ponta que enxerga o mundo real. O que muda é onde a conta acontece — e agora você tem os critérios para decidir isso conscientemente, em vez de descobrir depois que o equipamento já está instalado.
Retificação: um modelo de linguagem rodando dentro da placa
Quando este artigo foi publicado, a leitura corrente — inclusive a nossa — era que “modelo de linguagem no microcontrolador” não existia: dentro da placa cabia classificador, e geração de texto era assunto de servidor. Isso foi refutado na prática, com hardware na bancada.
Um modelo de 28,9 milhões de parâmetros armazenados gera texto coerente dentro de um ESP32-S3 N16R8, sem internet, sem gateway e sem PC no meio. A aproximadamente 9,5 tokens por segundo de ponta a ponta (102,9 ms por passo do modelo).
O truque não é força bruta: é hierarquia de memória. Os parâmetros foram divididos conforme a velocidade de cada memória da placa:
- núcleo denso de 559 KB (a parte que roda a cada passo) cabendo no orçamento de SRAM interna;
- cabeça de saída encenada em int8 na PSRAM;
- tabela de 25 milhões de parâmetros mapeada direto na flash, consultada por token.
A medição no silício é o ponto central: uma linha aleatória de 512 B na flash custa 20,3 µs, e as 6 linhas por token somam ~0,12 ms — cerca de 0,7% do tempo de memória por token. Ou seja: a tabela gigante que mora na flash é praticamente de graça. Quem domina o custo é a cabeça de saída (~17,3 ms/token), que qualquer modelo pagaria.
O que isso significa — e o que não significa. Não é o ChatGPT dentro do ESP32, e não vira. É um modelo de domínio restrito (TinyStories), com coerência boa e capacidade limitada; “28,9M parâmetros” é contagem de parâmetros *armazenados* via divisão de memória, não multiplicador de capacidade. O parágrafo sobre modelos de fronteira continua valendo integralmente.
O que muda é o mapa. A fronteira do que roda dentro da placa não é mais “classificador de uma tarefa só”. Passa a incluir geração de linguagem em domínio fechado, offline, com resposta em dezenas de milissegundos por token — sem link, sem custo por consulta, sem chave de API gravada no firmware e sem dado saindo da rede. Os cinco pontos da seção “o que muda quando o projeto sai da bancada” simplesmente deixam de existir nessa arquitetura.
O passo a passo completo está em Um modelo de linguagem rodando no ESP32-S3: a armadilha da PSRAM que pega quase todo mundo na compra da placa, a hierarquia SRAM/PSRAM/flash explicada peça por peça e o código real fazendo o produto escalar vetorizado da ESP-DSP nos dois núcleos.
Então a pergunta do começo envelheceu. Não é mais “dá para colocar uma IA dentro do ESP32?”. É “qual modelo vale a pena colocar, e quanto da decisão pode deixar de depender da internet?”.
Continue a conversa
Se você trabalha com ESP32 em ambiente industrial ou está montando algo nessa linha, a gente mantém uma comunidade para trocar experiência sobre exatamente esse tipo de decisão de arquitetura.
E se o que você quer não é consultar um modelo pela API, e sim usar um assistente de IA para escrever o firmware que faz essa consulta, o fluxo que funciona está em Usar assistente de IA para programar ESP32.
