INEMA.SOLUÇÕES
Solução 1 · Pet automático

Comedouro que serve na hora e avisa se o pet não comeu

Um servo abre a portinhola da ração nos horários que você escolhe. Uma balança embaixo do pote mede quanto o pet comeu, e uma boia avisa quando a água acaba. Serve para quem trabalha fora, viaja no feriado ou cuida de vários animais.

Kit R$ 120–200Dificuldade: médiaTudo em 3,3 V e 5 V

Como funciona

Serve, pesa, confere, avisa

Hora da refeição Servo abre a portinhola 3 horas depois Comeu Não comeu 7 h e 18 h, pelo relógio da internet 0,6 s; a balança pesa o pote o peso caiu pelo menos 10 g? soma no dia alerta no painel A boia avisa a qualquer hora se a água baixar.
Horários, tempo de abertura (0,6 s), espera (3 h) e mínimo (10 g) são pontos de partida. Ajuste depois dos testes com a ração e o pet de verdade.

O ESP32 pega a hora certa da internet. Na hora da refeição, gira o servo, que abre a portinhola de um reservatório (uma garrafa PET de boca para baixo serve) e solta a ração no pote. O pote fica em cima de uma célula de carga, uma barrinha de metal que entorta um pouco com o peso; o módulo HX711 transforma essa deformação em gramas. Três horas depois, o ESP32 compara o peso: se quase nada sumiu, marca "não comeu".

Peças

Lista de compras

PeçaPara que servePreço aprox.
ESP32 DevKit V1 (30 pinos)O cérebro, com Wi-Fi e relógio pela internetR$ 35–45
Servo MG90S (engrenagem de metal)Abre e fecha a portinhola. O SG90, de plástico, quebra com ração duraR$ 18–25
Célula de carga 1 kg + módulo HX711A balança embaixo do poteR$ 18–28
Sensor de nível tipo boia (chave boia)Avisa quando a água do bebedouro baixaR$ 12–18
Capacitor 470 µF 16 VSegura o pico de energia do servoR$ 2–3
Fonte 5 V 2 A com cabo USBAlimenta o ESP32 e o servoR$ 10–20
Protoboard, jumpersLigações sem soldaR$ 12–20
Comedouro: garrafa PET, pote, MDF ou caixa, parafusosReservatório, portinhola e base da balançaR$ 15–40
TotalR$ 120–200

Preços aproximados de loja online brasileira em outubro de 2026, a conferir antes de comprar. A câmera opcional (ESP32-CAM, seção de IA) não entra nesse total.

Ligação

O circuito, pino por pino

ESP32 3V3 GND VIN 5V GPIO 16 GPIO 17 GPIO 18 GPIO 27 HX711 · DT · SCK Servo · sinal Boia · fio 1 VCC 3V3 · GND DT no 16, SCK no 17 + no VIN · − no GND 470 µF entre + e − fio 2 no GND Célula de carga → HX711 (4 fios) Célula HX711 vermelho → E+ preto → E− branco → A− verde → A+
O servo puxa um pico de energia quando gira. O capacitor de 470 µF, ligado entre o + e o − do servo (perna mais curta no −), evita que o ESP32 reinicie.
ComponentePino do componenteLiga no ESP32
HX711VCC · GND · DT · SCK3V3 · GND · GPIO 16 · GPIO 17
Servo MG90S+ (vermelho) · − (marrom) · sinal (laranja)VIN (5 V do USB) · GND · GPIO 18
Boiafio 1 · fio 2 (tanto faz a ordem)GPIO 27 · GND
Célula de cargavermelho · preto · branco · verdeNo HX711: E+ · E− · A− · A+
Por que a boia não precisa de resistor? O código liga o resistor interno do GPIO 27 (INPUT_PULLUP). Com a boia fechada, o pino lê LOW; aberta, lê HIGH. Os pinos 34 a 39 não têm esse resistor, por isso a boia não vai neles.

Passo a passo

Da garrafa PET ao primeiro aviso

  1. Prepare a Arduino IDE. Instale a Arduino IDE 2 e, em Gerenciador de Placas, "esp32" (Espressif). Em Bibliotecas, instale "ESP32Servo" (Kevin Harrington) e "HX711" (Bogdan Necula).
  2. Monte a balança. Parafuse a célula de carga entre duas tábuas: uma ponta presa na base, a outra presa no prato onde fica o pote. A seta gravada na célula aponta para baixo, no sentido do peso.
  3. Ligue o HX711 e calibre. Grave o código com FATOR = 1.0 e o pote vazio no prato. No Monitor Serial (115200) aparece um número grande. Ponha um objeto de peso conhecido (pese na balança de cozinha, por exemplo 200 g) e anote o número. FATOR = número ÷ gramas. Troque no código e grave de novo.
  4. Monte a portinhola. Corte uma lâmina de plástico ou MDF que tampe a boca da garrafa e prenda no braço do servo. Em 0° fica fechada, em 90° abre.
  5. Ligue o servo com o capacitor e teste: o servo tem que girar só na hora da refeição. Para testar sem esperar, mude um horário de REFEICOES para a hora atual.
  6. Ajuste a porção. Encha o reservatório e veja quantos gramas caem em cada abertura. Aumente ou diminua ABRE_MS até chegar na porção que o veterinário indicou.
  7. Instale a boia no bebedouro, na altura mínima de água, e confira no painel: água baixa aparece como "BAIXA".
  8. Abra o painel. O Monitor Serial mostra o IP (ex.: 192.168.0.50). Digite no navegador do celular, na mesma rede Wi-Fi.

Código

Arduino IDE para ESP32

Troque o nome e a senha da rede, coloque o seu FATOR e os horários. Ligue o ESP32 sempre com o pote vazio no prato: ele zera a balança ao ligar.

// Pet automático — ESP32, Arduino IDE
// Bibliotecas: "ESP32Servo" (Kevin
// Harrington) e "HX711" (Bogdan Necula)
#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Servo.h>
#include <HX711.h>
#include <time.h>

const char* REDE  = "NOME_DA_REDE";
const char* SENHA = "SENHA_DA_REDE";

// GPIO 18: sinal do servo (portinhola)
const int PINO_SERVO = 18;
// GPIO 16: DT do HX711
const int PINO_DT = 16;
// GPIO 17: SCK do HX711
const int PINO_SCK = 17;
// GPIO 27: boia (outro fio no GND)
const int PINO_BOIA = 27;

// Calibração: comece com 1.0
// FATOR = número lido / gramas do peso
float FATOR = 1.0;

// horas das refeições (horário de Brasília)
const int N_REF = 2;
const int REFEICOES[N_REF] = {7, 18};
// tempo com a portinhola aberta
const int ABRE_MS = 600;
// confere 3 h depois de servir
const unsigned long CONFERE_MS =
  3UL * 3600 * 1000;
// sumiu menos que isso = "não comeu"
const float MINIMO_G = 10;

Servo porta;
HX711 balanca;
WebServer servidor(80);
float peso = 0, servido = 0;
float comidoHoje = 0;
bool jaServiu[N_REF];
bool aguaOk = true, naoComeu = false;
bool conferir = false;
unsigned long horaServiu = 0;
unsigned long ultimaLeitura = 0;
int diaAtual = -1, refeicoes = 0;

float lerPeso() {
  if (!balanca.is_ready()) return peso;
  // média de 5 leituras
  return balanca.get_units(5);
}

void servir() {
  // abre, espera, fecha
  porta.write(90);
  delay(ABRE_MS);
  porta.write(0);
  // ração assenta no pote
  delay(2000);
  servido = lerPeso();
  horaServiu = millis();
  conferir = true;
  naoComeu = false;
  refeicoes++;
}

// /dados: JSON para o painel e para a IA
void dados() {
  String j = "{\"peso\":" + String(peso, 0);
  j += ",\"servido\":" + String(servido, 0);
  j += ",\"comido_hoje\":" +
       String(comidoHoje, 0);
  j += ",\"refeicoes\":" + String(refeicoes);
  j += ",\"agua_ok\":";
  j += aguaOk ? "true" : "false";
  j += ",\"nao_comeu\":";
  j += naoComeu ? "true" : "false";
  j += "}";
  servidor.send(200, "application/json", j);
}

// /: página que abre no celular (5 em 5 s)
void painel() {
  String h = "<meta name=viewport "
    "content='width=device-width'>"
    "<meta http-equiv=refresh content=5>";
  h += "<h2>Comedouro</h2><p>No pote: ";
  h += String(peso, 0) + " g";
  h += "<br>Comeu hoje: ";
  h += String(comidoHoje, 0) + " g";
  h += "<br>Água: ";
  h += aguaOk ? "ok" : "BAIXA";
  if (naoComeu) h += "<br><b>NÃO COMEU</b>";
  h += "</p>";
  servidor.send(200, "text/html", h);
}

void setup() {
  Serial.begin(115200);
  pinMode(PINO_BOIA, INPUT_PULLUP);
  porta.setPeriodHertz(50);
  porta.attach(PINO_SERVO, 500, 2400);
  // começa fechada
  porta.write(0);
  balanca.begin(PINO_DT, PINO_SCK);
  balanca.set_scale(FATOR);
  // zera com o pote vazio no prato
  balanca.tare();
  WiFi.begin(REDE, SENHA);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // relógio pela internet, fuso -3 h
  configTime(-3 * 3600, 0, "pool.ntp.org");
  Serial.print("\nPainel em http://");
  Serial.println(WiFi.localIP());
  servidor.on("/", painel);
  servidor.on("/dados", dados);
  servidor.begin();
}

void loop() {
  servidor.handleClient();
  if (millis() - ultimaLeitura < 2000) return;
  ultimaLeitura = millis();
  peso = lerPeso();
  // boia fechada (LOW) = água no nível
  aguaOk = digitalRead(PINO_BOIA) == LOW;
  Serial.printf("peso=%.1f agua=%d\n",
                peso, aguaOk);

  struct tm t;
  if (!getLocalTime(&t, 10)) return;
  // virou o dia: zera a contagem
  if (t.tm_yday != diaAtual) {
    diaAtual = t.tm_yday;
    comidoHoje = 0;
    refeicoes = 0;
    for (int i = 0; i < N_REF; i++)
      jaServiu[i] = false;
  }
  for (int i = 0; i < N_REF; i++) {
    if (t.tm_hour == REFEICOES[i] &&
        !jaServiu[i]) {
      jaServiu[i] = true;
      servir();
    }
  }
  bool passou =
    millis() - horaServiu > CONFERE_MS;
  if (conferir && passou) {
    conferir = false;
    float comeu = servido - peso;
    if (comeu > 0) comidoHoje += comeu;
    naoComeu = comeu < MINIMO_G;
  }
}

A camada de IA

O que a IA faz neste projeto

Aviso de "não comeu"

A regra simples já está no código. Na versão 2, guarde os gramas de cada dia e peça à IA para comparar com a média: "hoje ele comeu 40% menos que na semana". Mudança de apetite é motivo para ir ao veterinário.

Resumo do dia

Um script no computador lê os dados do ESP32 e pede a um modelo de IA um resumo curto para mandar ao dono que está viajando.

Câmera que reconhece o pet

Opcional: uma ESP32-CAM tira foto quando o peso muda. Um modelo de visão diz se foi o gato, o cachorro ou nenhum animal. Com dois pets, você descobre quem comeu.

Script de resumo, em Python, rodando no computador na mesma rede:

# resumo.py — roda no computador,
# na mesma rede do ESP32
import json, urllib.request

# troque pelo IP do seu ESP32
URL = "http://192.168.0.50/dados"
dados = json.load(urllib.request.urlopen(URL))
prompt = (
    "Você ajuda a cuidar de um gato. "
    "Dados do comedouro hoje: "
    + json.dumps(dados) + ". "
    "peso = gramas no pote agora, "
    "servido = gramas logo após servir, "
    "comido_hoje = gramas comidas no dia, "
    "agua_ok = bebedouro com água. "
    "Escreva em português, em até 3 frases, "
    "um resumo para o dono que está viajando."
)
print(prompt)
# Mande o prompt ao modelo que você usa:
# - cole no chat do serviço de IA; ou
# - use a biblioteca oficial do serviço,
#   com a SUA chave numa variável de
#   ambiente (nunca escrita no código); ou
# - rode um modelo local no PC, sem chave.
Chave de IA é como senha. Nunca escreva a chave dentro do código do ESP32 nem em arquivo que vai para o GitHub. Guarde numa variável de ambiente do computador e siga a documentação do serviço que você escolheu.
Câmera tem regra. Aponte a câmera só para o comedouro, de cima para baixo, sem pegar o rosto de quem passa. Avise as pessoas da casa que há câmera, não publique as fotos e apague as que não precisar no fim do dia.

Teste e melhore

Confira antes de deixar o pet com ele

Checklist
  • Com o pote vazio, o painel marca perto de 0 g; com o peso conhecido, marca o peso certo (erro de até 5 g).
  • O servo abre e fecha só no horário, e a portinhola fecha de verdade (sem ração escorrendo).
  • Cada abertura solta sempre mais ou menos a mesma porção. Teste 5 vezes e anote.
  • Tirando a ração do pote com a mão, o painel não mostra "NÃO COMEU" na conferência.
  • Tirando a água, aparece "BAIXA" em até 2 segundos.
  • Uma semana inteira com você em casa antes do primeiro feriado.
Erro comumCausa provávelComo resolver
Peso negativo ou que sobe sozinhoBalança zerada com o pote cheio, ou célula montada ao contrárioLigue com o pote vazio; confira a seta da célula e os parafusos
Peso sempre 0DT e SCK trocados, ou fio da célula soltoDT no GPIO 16, SCK no GPIO 17; confira as 4 cores no HX711
ESP32 reinicia quando o servo giraPico de energia do servoCapacitor de 470 µF no servo e fonte de 2 A
Ração trava na portinholaGrão grande, boca estreita ou abertura curtaBoca mais larga, rampa inclinada, aumente ABRE_MS
Serve na hora erradaFuso horário ou ESP32 sem internet ao ligarConfira o -3 * 3600; o relógio só funciona depois de pegar a hora da internet
Água "BAIXA" com o pote cheioBoia montada ao contrárioVire a boia ou troque LOW por HIGH na linha da boia

Caderno de testes. Cada vez que mudar alguma coisa, anote numa linha. A tabela da porção certa para cada ração vira argumento de venda.

DataVersãoO que mudouResultado
20/10v1Abertura de 0,6 sCaíram 15 g, pouco para um gato adulto
21/10v2Abertura de 1,2 s e rampa no funilCaíram de 38 g a 44 g em 5 testes
…v3Comparar o dia com a média da semanaAnote aqui

Segurança

Pet, peça que mexe e fio

O pet não pode alcançar fio nem peça móvel. O servo e a portinhola ficam dentro da caixa, longe da pata e do focinho; o pet só alcança o pote. Passe os fios por dentro da caixa ou por um tubo espiral: cachorro e gato roem cabo. Use só a fonte de 5 V pronta, nunca fio de tomada emendado.
O aparelho não substitui uma pessoa. Ração pode travar e Wi-Fi pode cair. Deixe sempre uma reserva de água, peça a alguém para passar a cada um ou dois dias e não use o comedouro como única fonte de comida em viagem longa.

Ficha de negócio

Como vender o pet automático

Quem compraDono de pet que trabalha fora ou viaja no feriado, pet shop que revende com a marca da loja, hotelzinho e creche de pet (vários comedouros num painel só)
Custo do kitR$ 120–200 (lista acima, a conferir)
Preço sugeridoR$ 300–450 o comedouro montado, calibrado e testado (sugestão)
Mão de obra1 hora para instalar, calibrar a porção com a ração do cliente, programar os horários e ensinar o painel
Assinatura opcionalR$ 10–20 por mês: alertas, resumo da semana e ajuste da porção (sugestão)
Argumento de economiaMostre o número: custo da ração por dia = gramas comidas × preço do quilo ÷ 1000. Compare com o preço de uma visita de cuidador no feriado (pergunte o valor na sua cidade)
Venda para o pet shop. Um pet shop que revende ganha um produto com a marca dele, e você ganha vários clientes de uma vez. Leve um comedouro funcionando e o caderno de testes com as porções medidas.

Para ir além

Próximos passos

Para entender como um modelo reconhece o pet numa foto, siga o curso Visão e ação (VLA). Para controlar servos e sensores com mais precisão, veja Robótica. Todos os cursos são abertos e gratuitos no INEMA.CLUB.