Bebedouro Automático Inteligente para Pets

Arduino + sensor ultrassônico + bomba d'água + app móvel para manter seu pet sempre hidratado

Intermediário/Avançado
Sofia Andrade

Sofia Andrade

Especialista em IA

Manter nossos pets bem hidratados é fundamental para a saúde deles, mas nossa rotina corrida às vezes nos faz esquecer de trocar a água ou recarregar o bebedouro. Este projeto resolve esse problema criando um sistema inteligente que monitora o nível da água e reabastece automaticamente quando necessário, além de enviar notificações para seu celular.

Visão Geral do Projeto

  • O que vamos construir: Sistema completo Arduino + sensores + bomba + app
  • Resultado: Bebedouro que funciona sozinho e mantém água sempre fresca
  • Nível de dificuldade: Intermediário/Avançado
  • Tempo de construção: 8 a 12 horas (distribuídas em um fim de semana)
  • Custo estimado: R$ 400 a R$ 700

Por que automatizar o bebedouro do seu pet?

Pets precisam de água fresca e limpa constantemente:

  • Hidratação constante: Cães precisam de 50-100ml por kg/dia
  • Saúde renal: Gatos são propensos a problemas renais por desidratação
  • Emergências: Sistema previne que o pet fique sem água
  • Tranquilidade: Monitoramento remoto quando você não está em casa
  • Água fresca: Renovação automática evita água parada

Material Necessário

Eletrônicos principais:

  • Arduino Uno R3 - R$ 60-90
  • Sensor ultrassônico HC-SR04 - R$ 15-30
  • Bomba d'água submersível 5V - R$ 35-60
  • Módulo relé 5V 1 canal - R$ 20-35
  • Display LCD 16x2 com I2C - R$ 25-45
  • ESP8266 NodeMCU (para WiFi) - R$ 35-50
  • Buzzer ativo 5V - R$ 5-10

Estrutura física:

  • Reservatório de água 5L - R$ 20-35
  • Tigela do pet (inox) - R$ 25-45
  • Mangueira silicone 8mm (2m) - R$ 15-25
  • Caixa plástica vedada - R$ 20-35
  • Suporte/base MDF - R$ 25-40

Componentes auxiliares:

  • Fonte 9V 2A - R$ 30-45
  • Protoboard + jumpers - R$ 20-30
  • Resistores + capacitores - R$ 8-20
  • Parafusos e conectores - R$ 15-25

Custo total: R$ 400-700

⚠️ Importante: As marcas mencionadas são citadas apenas para fins educativos e informativos. Não possuímos qualquer parceria comercial com essas empresas.

Como Funciona o Sistema

Fluxo de operação automática:

  1. Monitoramento: Sensor ultrassônico mede nível da água na tigela
  2. Análise: Arduino processa dados e determina se precisa reabastecer
  3. Ação: Bomba é acionada automaticamente para adicionar água
  4. Notificação: App móvel informa sobre reabastecimentos
  5. Display: LCD mostra status em tempo real
  6. Segurança: Sistema tem proteções contra operação a seco

Recursos inteligentes:

  • Reabastecimento automático quando água baixa
  • Horários programados para renovação da água
  • Contador de consumo diário do pet
  • Alertas de manutenção (limpeza, filtro)
  • Modo manual via app para forçar reabastecimento
  • Histórico de consumo para acompanhar saúde

Esquema de Ligações

Arduino Uno           Componente
=============         ==================
Digital 2          → HC-SR04 (Trigger)
Digital 3          → HC-SR04 (Echo)
Digital 4          → Relé bomba (IN)
Digital 5          → Buzzer
Digital 7          → LED Status (verde)
Digital 8          → LED Alerta (vermelho)
Digital 9          → Botão manual
A4 (SDA)          → Display LCD (SDA)
A5 (SCL)          → Display LCD (SCL)

5V                → Alimentação sensores
GND               → Terra comum

ESP8266 - Para conectividade WiFi:
ESP8266              Arduino/Componentes
=============        ==================
D1 (GPIO5)        → Arduino TX (pino 1)
D2 (GPIO4)        → Arduino RX (pino 0)
3.3V              → Alimentação própria
GND               → Terra comum

Sistema hidráulico:
Reservatório 5L → Mangueira → Bomba → Mangueira → Tigela Pet
     ↑                                                ↓
     └─────────── Recirculação (opcional) ←──────────┘

Código Principal Arduino

Programa completo do bebedouro:

Ver código completo
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

// =============== CONFIGURAÇÕES DOS PINOS ===============
#define TRIGGER_PIN 2
#define ECHO_PIN 3
#define RELAY_PUMP_PIN 4
#define BUZZER_PIN 5
#define LED_STATUS_PIN 7
#define LED_ALERT_PIN 8
#define BUTTON_PIN 9

// =============== CONFIGURAÇÕES DO SISTEMA ===============
#define WATER_LOW_LEVEL 15      // cm (quando ativar bomba)
#define WATER_HIGH_LEVEL 5      // cm (quando parar bomba)
#define PUMP_MAX_TIME 10000     // 10 segundos máximo
#define DAILY_REFRESH_HOUR 8    // Renovação diária às 8h
#define CONSUMPTION_RESET_HOUR 0 // Reset contador à meia-noite

// =============== OBJETOS GLOBAIS ===============
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial espSerial(10, 11); // RX, TX para ESP8266

// =============== VARIÁVEIS GLOBAIS ===============
float waterLevel = 0;           // cm
bool pumpActive = false;
unsigned long pumpStartTime = 0;
unsigned long lastMeasurement = 0;
unsigned long dailyConsumption = 0;  // ml
unsigned long totalRefills = 0;
unsigned long lastRefillTime = 0;

// Estados do sistema
enum SystemState {
  MONITORING,
  FILLING,
  ERROR,
  MAINTENANCE
};

SystemState currentState = MONITORING;
String lastError = "";

// =============== SETUP PRINCIPAL ===============
void setup() {
  Serial.begin(9600);
  espSerial.begin(9600);
  
  initializePins();
  initializeDisplay();
  
  // Teste inicial dos componentes
  testSystemComponents();
  
  currentState = MONITORING;
  Serial.println("Bebedouro iniciado - Modo monitoramento");
  
  displayWelcomeMessage();
  playStartupSound(
    </>);
}

// =============== LOOP PRINCIPAL ===============
void loop() {
  unsigned long currentTime = millis();
  
  // Leitura do sensor a cada 2 segundos
  if (currentTime - lastMeasurement >= 2000) {
    measureWaterLevel();
    lastMeasurement = currentTime;
  }
  
  // Processamento baseado no estado atual
  switch (currentState) {
    case MONITORING:
      processMonitoring();
      break;
      
    case FILLING:
      processFilling();
      break;
      
    case ERROR:
      processError();
      break;
      
    case MAINTENANCE:
      processMaintenance();
      break;
  }
  
  // Verificações de segurança
  checkSafetyConditions();
  
  // Atualização da interface
  updateDisplay();
  updateLEDs();
  
  // Processamento de comandos
  handleButtonPress();
  handleWiFiCommands();
  
  // Tarefas programadas
  checkScheduledTasks();
  
  delay(100);
}

// =============== INICIALIZAÇÃO ===============
void initializePins() {
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(RELAY_PUMP_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_STATUS_PIN, OUTPUT);
  pinMode(LED_ALERT_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  
  // Estado inicial seguro
  digitalWrite(RELAY_PUMP_PIN, LOW);
  digitalWrite(LED_STATUS_PIN, HIGH);
  digitalWrite(LED_ALERT_PIN, LOW);
}

void initializeDisplay() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void testSystemComponents() {
  lcd.setCursor(0, 0);
  lcd.print("Testando...");
  
  // Teste do sensor ultrassônico
  measureWaterLevel();
  if (waterLevel > 0 && waterLevel < 50) {
    lcd.setCursor(0, 1);
    lcd.print("Sensor: OK");
  } else {
    lcd.setCursor(0, 1);
    lcd.print("Sensor: ERRO");
    lastError = "Sensor ultrassônico";
  }
  
  delay(2000);
  
  // Teste da bomba (1 segundo)
  lcd.setCursor(0, 1);
  lcd.print("Bomba: Teste...");
  digitalWrite(RELAY_PUMP_PIN, HIGH);
  delay(1000);
  digitalWrite(RELAY_PUMP_PIN, LOW);
  
  lcd.setCursor(0, 1);
  lcd.print("Bomba: OK      ");
  delay(1000);
}

// =============== MEDIÇÃO DE NÍVEL ===============
void measureWaterLevel() {
  // Enviar pulso ultrassônico
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  
  // Medir tempo de retorno
  unsigned long duration = pulseIn(ECHO_PIN, HIGH);
  
  // Calcular distância em cm
  float distance = (duration * 0.034) / 2;
  
  // Filtro simples para evitar leituras erráticas
  if (distance > 0 && distance < 50) {
    waterLevel = (waterLevel * 0.8) + (distance * 0.2); // Filtro passa-baixa
  }
  
  // Debug
  Serial.print("Nível água: ");
  Serial.print(waterLevel);
  Serial.println(" cm");
}

// =============== PROCESSAMENTO DE ESTADOS ===============
void processMonitoring() {
  // Verificar se precisa reabastecer
  if (waterLevel >= WATER_LOW_LEVEL) {
    startRefilling("Nível baixo detectado");
  }
  
  // Modo standby normal
  digitalWrite(LED_STATUS_PIN, HIGH);
  digitalWrite(LED_ALERT_PIN, LOW);
}

void processFilling() {
  unsigned long elapsedTime = millis() - pumpStartTime;
  
  // Verificar se atingiu nível adequado
  if (waterLevel <= WATER_HIGH_LEVEL) {
    stopRefilling("Nível adequado atingido");
    return;
  }
  
  // Timeout de segurança
  if (elapsedTime >= PUMP_MAX_TIME) {
    stopRefilling("Timeout de segurança");
    currentState = ERROR;
    lastError = "Bomba não conseguiu reabastecer";
    return;
  }
  
  // Indicação visual durante reabastecimento
  digitalWrite(LED_STATUS_PIN, (millis() / 500) % 2); // Piscar a cada 500ms
}

void processError() {
  // Piscar LED de alerta
  digitalWrite(LED_ALERT_PIN, (millis() / 300) % 2);
  digitalWrite(LED_STATUS_PIN, LOW);
  
  // Som de alerta a cada 10 segundos
  static unsigned long lastAlert = 0;
  if (millis() - lastAlert >= 10000) {
    playErrorSound();
    lastAlert = millis();
  }
  
  // Permitir reset manual
  if (digitalRead(BUTTON_PIN) == LOW) {
    delay(100); // Debounce
    if (digitalRead(BUTTON_PIN) == LOW) {
      currentState = MONITORING;
      lastError = "";
      Serial.println("Estado de erro resetado manualmente");
    }
  }
}

void processMaintenance() {
  // Modo manutenção - sistema pausado
  digitalWrite(LED_STATUS_PIN, LOW);
  digitalWrite(LED_ALERT_PIN, (millis() / 1000) % 2); // Piscar lento
  
  // Sair da manutenção com botão
  if (digitalRead(BUTTON_PIN) == LOW) {
    delay(2000); // Pressão longa
    if (digitalRead(BUTTON_PIN) == LOW) {
      currentState = MONITORING;
      Serial.println("Saindo do modo manutenção");
    }
  }
}

// =============== CONTROLE DA BOMBA ===============
void startRefilling(String reason) {
  if (pumpActive) return; // Já está reabastecendo
  
  pumpActive = true;
  pumpStartTime = millis();
  currentState = FILLING;
  
  digitalWrite(RELAY_PUMP_PIN, HIGH);
  
  Serial.println("Reabastecimento iniciado: " + reason);
  sendNotification("Reabastecendo", reason);
  
  // Estimativa de volume adicionado (aproximada)
  float volumeToAdd = (WATER_LOW_LEVEL - WATER_HIGH_LEVEL) * 10; // cm para ml (aprox)
  dailyConsumption += volumeToAdd;
  totalRefills++;
  lastRefillTime = millis();
}

void stopRefilling(String reason) {
  if (!pumpActive) return;
  
  pumpActive = false;
  currentState = MONITORING;
  
  digitalWrite(RELAY_PUMP_PIN, LOW);
  
  Serial.println("Reabastecimento parado: " + reason);
  sendNotification("Concluído", reason);
  
  playCompletionSound();
}

// =============== VERIFICAÇÕES DE SEGURANÇA ===============
void checkSafetyConditions() {
  // Verificar se sensor está funcionando
  if (waterLevel <= 0 || waterLevel > 50) {
    if (currentState != ERROR) {
      currentState = ERROR;
      lastError = "Sensor fora de alcance";
      digitalWrite(RELAY_PUMP_PIN, LOW); // Parar bomba por segurança
    }
  }
  
  // Verificar se bomba não está travada
  if (pumpActive && (millis() - pumpStartTime) > PUMP_MAX_TIME) {
    currentState = ERROR;
    lastError = "Bomba com problema";
    digitalWrite(RELAY_PUMP_PIN, LOW);
  }
}

// =============== INTERFACE E DISPLAY ===============
void updateDisplay() {
  lcd.clear();
  
  // Primeira linha: Status principal
  lcd.setCursor(0, 0);
  switch (currentState) {
    case MONITORING:
      lcd.print("Agua: ");
      lcd.print(20 - waterLevel, 1); // Converter para nível em %
      lcd.print("cm OK");
      break;
      
    case FILLING:
      lcd.print("Reabastecendo...");
      break;
      
    case ERROR:
      lcd.print("ERRO: ");
      lcd.print(lastError.substring(0, 9));
      break;
      
    case MAINTENANCE:
      lcd.print("Manutencao");
      break;
  }
  
  // Segunda linha: Informações adicionais
  lcd.setCursor(0, 1);
  if (currentState == FILLING) {
    unsigned long elapsed = (millis() - pumpStartTime) / 1000;
    lcd.print("Tempo: ");
    lcd.print(elapsed);
    lcd.print("s");
  } else if (currentState == MONITORING) {
    lcd.print("Consumo:");
    lcd.print(dailyConsumption);
    lcd.print("ml");
  } else if (currentState == ERROR) {
    lcd.print("Botao p/ reset");
  }
}

void updateLEDs() {
  // LEDs já são controlados nos estados individuais
  // Esta função pode ser expandida para padrões mais complexos
}

void displayWelcomeMessage() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Bebedouro Smart");
  lcd.setCursor(0, 1);
  lcd.print("Pet System v1.0");
  delay(3000);
}

// =============== SONS E ALERTAS ===============
void playStartupSound() {
  tone(BUZZER_PIN, 1000, 200);
  delay(250);
  tone(BUZZER_PIN, 1500, 200);
  delay(250);
  tone(BUZZER_PIN, 2000, 200);
}

void playCompletionSound() {
  tone(BUZZER_PIN, 800, 100);
  delay(150);
  tone(BUZZER_PIN, 1000, 100);
  delay(150);
  tone(BUZZER_PIN, 1200, 100);
}

void playErrorSound() {
  for (int i = 0; i < 3; i++) {
    tone(BUZZER_PIN, 400, 200);
    delay(300);
  }
}

// =============== ENTRADA DO USUÁRIO ===============
void handleButtonPress() {
  static unsigned long lastPress = 0;
  
  if (digitalRead(BUTTON_PIN) == LOW && (millis() - lastPress) > 500) {
    lastPress = millis();
    
    if (currentState == MONITORING) {
      // Reabastecimento manual
      startRefilling("Acionamento manual");
    } else if (currentState == ERROR) {
      // Reset de erro
      currentState = MONITORING;
      lastError = "";
      Serial.println("Erro resetado pelo usuário");
    }
  }
}

// =============== COMUNICAÇÃO WiFi ===============
void handleWiFiCommands() {
  if (espSerial.available()) {
    String command = espSerial.readStringUntil('\n');
    command.trim();
    
    if (command == "STATUS") {
      sendStatusToApp();
    } else if (command == "REFILL") {
      startRefilling("Comando do app");
    } else if (command == "RESET") {
      currentState = MONITORING;
      lastError = "";
    } else if (command == "MAINTENANCE") {
      currentState = MAINTENANCE;
    }
  }
}

void sendStatusToApp() {
  String status = "";
  status += "LEVEL:" + String(20 - waterLevel) + ";";
  status += "STATE:" + String(currentState) + ";";
  status += "CONSUMPTION:" + String(dailyConsumption) + ";";
  status += "REFILLS:" + String(totalRefills) + ";";
  
  espSerial.println(status);
  Serial.println("Status enviado: " + status);
}

void sendNotification(String title, String message) {
  String notification = "NOTIFY:" + title + ":" + message;
  espSerial.println(notification);
  Serial.println("Notificação: " + notification);
}

// =============== TAREFAS PROGRAMADAS ===============
void checkScheduledTasks() {
  static unsigned long lastDailyCheck = 0;
  
  // Verificar tarefas uma vez por minuto
  if (millis() - lastDailyCheck >= 60000) {
    lastDailyCheck = millis();
    
    // Aqui você pode adicionar verificação de hora real (RTC)
    // Por simplicidade, usando apenas contadores
    
    // Reset diário do consumo (simula meia-noite)
    static unsigned long dayStart = millis();
    if (millis() - dayStart >= 86400000) { // 24 horas
      dailyConsumption = 0;
      totalRefills = 0;
      dayStart = millis();
      Serial.println("Contador diário resetado");
    }
  }
}

App Móvel Básico (ESP8266)

Código para ESP8266 - Conectividade WiFi:

Ver código completo
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SoftwareSerial.h>

// Configurações WiFi
const char* ssid = "SUA_REDE_WIFI";
const char* password = "SUA_SENHA";

// Comunicação com Arduino
SoftwareSerial arduinoSerial(D1, D2); // RX, TX

AsyncWebServer server(80);

// Dados recebidos do Arduino
String currentLevel = "0";
String systemState = "0";
String dailyConsumption = "0";
String totalRefills = "0";

void setup() {
  Serial.begin(115200);
  arduinoSerial.begin(9600);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  
  Serial.println("WiFi conectado: " + WiFi.localIP().toString());
  
  setupWebServer();
}

void loop() {
  // Processar comandos do Arduino
  if (arduinoSerial.available()) {
    String data = arduinoSerial.readStringUntil('\n');
    processArduinoData(data);
  }
  
  // Solicitar status a cada 10 segundos
  static unsigned long lastRequest = 0;
  if (millis() - lastRequest >= 10000) {
    arduinoSerial.println("STATUS");
    lastRequest = millis();
  }
  
  delay(100);
}

void setupWebServer() {
  // Página principal
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    String html = getMainPage();
    request->send(200, "text/html", html);
  });
  
  // API para dados do bebedouro
  server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
    String json = "{";
    json += "\"level\":\"" + currentLevel + "\",";
    json += "\"state\":\"" + systemState + "\",";
    json += "\"consumption\":\"" + dailyConsumption + "\",";
    json += "\"refills\":\"" + totalRefills + "\"";
    json += "}";
    
    request->send(200, "application/json", json);
  });
  
  // Comando para reabastecer
  server.on("/api/refill", HTTP_POST, [](AsyncWebServerRequest *request){
    arduinoSerial.println("REFILL");
    request->send(200, "application/json", "{\"status\":\"ok\"}");
  });
  
  server.begin();
}

String getMainPage() {
  return R"rawliteral(
<!DOCTYPE html>
<html>
<head>
    <title>Bebedouro Pet Smart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #4A90E2, #7B68EE);
            color: white;
            text-align: center;
            padding: 20px;
            margin: 0;
        }
        .container {
            max-width: 400px;
            margin: 0 auto;
            background: rgba(0,0,0,0.3);
            padding: 30px;
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
        }
        .status-card {
            background: rgba(255,255,255,0.1);
            margin: 15px 0;
            padding: 20px;
            border-radius: 15px;
            backdrop-filter: blur(10px);
        }
        .level-display {
            font-size: 3em;
            font-weight: bold;
            margin: 20px 0;
            color: #4CAF50;
        }
        .btn {
            background: linear-gradient(45deg, #4CAF50, #45a049);
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 25px;
            font-size: 1.1em;
            cursor: pointer;
            margin: 10px;
            transition: all 0.3s;
        }
        .btn:hover { transform: translateY(-2px); }
        .stats { display: flex; justify-content: space-around; }
        .stat { text-align: center; }
        .stat-value { font-size: 1.5em; font-weight: bold; }
        .stat-label { font-size: 0.9em; opacity: 0.8; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Bebedouro Smart</h1>
        
        <div class="status-card">
            <div>Nível da Água</div>
            <div class="level-display" id="waterLevel">--</div>
            <div id="statusText">Carregando...</div>
        </div>
        
        <div class="status-card">
            <div class="stats">
                <div class="stat">
                    <div class="stat-value" id="consumption">--</div>
                    <div class="stat-label">ml hoje</div>
                </div>
                <div class="stat">
                    <div class="stat-value" id="refills">--</div>
                    <div class="stat-label">reabastecimentos</div>
                </div>
            </div>
        </div>
        
        <button class="btn" onclick="refillNow()">Reabastecer Agora</button>
        <button class="btn" onclick="location.reload()">Atualizar</button>
    </div>

    <script>
        function updateStatus() {
            fetch('/api/status')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('waterLevel').textContent = data.level + ' cm';
                    document.getElementById('consumption').textContent = data.consumption;
                    document.getElementById('refills').textContent = data.refills;
                    
                    let status = '';
                    switch(data.state) {
                        case '0': status = 'Monitorando'; break;
                        case '1': status = 'Reabastecendo'; break;
                        case '2': status = 'Erro'; break;
                        case '3': status = 'Manutenção'; break;
                        default: status = 'Desconhecido';
                    }
                    document.getElementById('statusText').textContent = status;
                })
                .catch(error => {
                    document.getElementById('statusText').textContent = 'Erro de conexão';
                });
        }
        
        function refillNow() {
            fetch('/api/refill', {method: 'POST'})
                .then(response => response.json())
                .then(data => {
                    alert('Reabastecimento iniciado!');
                    setTimeout(updateStatus, 1000);
                });
        }
        
        // Atualizar a cada 5 segundos
        setInterval(updateStatus, 5000);
        updateStatus();
    </script>
</body>
</html>
)rawliteral";
}

void processArduinoData(String data) {
  // Processar dados no formato "LEVEL:10;STATE:0;CONSUMPTION:250;REFILLS:5;"
  if (data.startsWith("LEVEL:")) {
    int levelStart = data.indexOf("LEVEL:") + 6;
    int levelEnd = data.indexOf(";", levelStart);
    currentLevel = data.substring(levelStart, levelEnd);
    
    int stateStart = data.indexOf("STATE:") + 6;
    int stateEnd = data.indexOf(";", stateStart);
    systemState = data.substring(stateStart, stateEnd);
    
    int consStart = data.indexOf("CONSUMPTION:") + 12;
    int consEnd = data.indexOf(";", consStart);
    dailyConsumption = data.substring(consStart, consEnd);
    
    int refillStart = data.indexOf("REFILLS:") + 8;
    int refillEnd = data.indexOf(";", refillStart);
    totalRefills = data.substring(refillStart, refillEnd);
  }
}

Montagem Física

Estrutura do bebedouro:

  • Base principal: MDF 40x30cm com furos para componentes
  • Reservatório: Fixado na parte traseira, elevado
  • Tigela: Posicionada na frente, com sensor acima
  • Eletrônica: Caixa vedada na lateral
  • Mangueiras: Conexões silicone entre reservatório e tigela

Instalação hidráulica:

Reservatório (5L) → Válvula → Bomba → Filtro → Tigela Pet
                      ↑                           ↓
                   Eletrônica ←──── Sensor ←─────┘

Cuidados importantes:

  • Vedação: Proteger eletrônica da umidade
  • Alimentação: Fonte estável e filtrada
  • Limpeza: Acesso fácil para manutenção
  • Segurança: Cabos protegidos dos pets

Distribuição do Tempo de Construção

Total: 8-12 horas

Montagem eletrônica (3-4 horas):

  • Soldagem dos componentes: 1-2 horas
  • Conexões e testes: 1 hora
  • Montagem na caixa vedada: 1 hora

Programação e testes (2-3 horas):

  • Upload do código Arduino: 30 minutos
  • Configuração ESP8266 e WiFi: 1 hora
  • Testes de comunicação: 30 minutos
  • Calibração do sensor: 1 hora

Sistema hidráulico (2-3 horas):

  • Instalação da bomba: 1 hora
  • Conexão das mangueiras: 1 hora
  • Testes de vedação: 30 minutos
  • Ajustes de pressão: 30 minutos

Estrutura física (1-2 horas):

  • Corte e montagem da base MDF: 1 hora
  • Fixação dos componentes: 30 minutos
  • Acabamento: 30 minutos

Calibração e ajustes finais (1-2 horas):

  • Calibração precisa do sensor: 30 minutos
  • Teste do ciclo completo: 30 minutos
  • Ajustes de software: 30 minutos
  • Documentação das configurações: 30 minutos

Configuração e Calibração

Calibração do sensor:

  • Medir distâncias: Tigela vazia vs. cheia
  • Ajustar constantes no código
  • Testar ciclo completo de reabastecimento
  • Validar precisão com medições manuais

Configuração WiFi:

Ver código completo
// Configurar no ESP8266
const char* ssid = "SUA_REDE_WIFI";
const char* password = "SUA_SENHA";

// Para primeira configuração, criar hotspot próprio:
void setupWiFiManager() {
  WiFiManager wifiManager;
  wifiManager.autoConnect("BebedouroPet_Setup");
  
  Serial.println("WiFi configurado!");
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

Ajustes do sistema:

Ver código completo
// Personalizar para seu pet:
#define WATER_LOW_LEVEL 15      // Ajustar conforme tamanho da tigela
#define WATER_HIGH_LEVEL 5      // Nível máximo desejado  
#define PUMP_MAX_TIME 10000     // Tempo máximo de bomba ligada
#define PET_CONSUMPTION_DAILY 500 // ml esperado por dia

Recursos Avançados Opcionais

1. Sensor de qualidade da água:

Ver código completo
#define TDS_SENSOR_PIN A1       // Sensor de sólidos dissolvidos

void checkWaterQuality() {
  int tdsValue = analogRead(TDS_SENSOR_PIN);
  float tdsConcentration = tdsValue * (5.0 / 1024.0) * 1000;
  
  if (tdsConcentration > 300) {  // PPM muito alto
    currentState = MAINTENANCE;
    lastError = "Trocar filtro";
    sendNotification("Alerta", "Água precisa ser trocada");
  }
}

2. Integração com assistentes de voz:

Ver código completo
// Comandos Alexa via IFTTT
server.on("/alexa/refill", HTTP_GET, [](AsyncWebServerRequest *request){
  arduinoSerial.println("REFILL");
  request->send(200, "text/plain", "Reabastecimento iniciado");
});

server.on("/alexa/status", HTTP_GET, [](AsyncWebServerRequest *request){
  String response = "Nível da água: " + currentLevel + " centímetros. ";
  response += "Consumo hoje: " + dailyConsumption + " mililitros.";
  request->send(200, "text/plain", response);
});

3. Histórico e análise de dados:

Ver código completo
#include <EEPROM.h>

struct DailyData {
  unsigned long date;
  int consumption;
  int refills;
  float avgLevel;
};

void saveDailyData() {
  DailyData today;
  today.date = millis() / 86400000;  // Dias desde inicialização
  today.consumption = dailyConsumption;
  today.refills = totalRefills;
  today.avgLevel = 20 - waterLevel;
  
  // Salvar no EEPROM (último endereço disponível)
  int address = EEPROM.length() - sizeof(DailyData);
  EEPROM.put(address, today);
  EEPROM.commit();
}

Solução de Problemas

Problemas comuns e soluções:

Sensor ultrassônico lendo errado:

  • Verificar alimentação 5V estável
  • Limpar sensores (poeira interfere)
  • Ajustar posicionamento (evitar superfícies inclinadas)
  • Adicionar filtro por software (média móvel)

Bomba não liga:

  • Testar relé manualmente (digitalWrite(RELAY_PUMP_PIN, HIGH))
  • Verificar alimentação da bomba (5V ou 12V)
  • Confirmar conexões do relé (IN, VCC, GND)
  • Verificar se bomba não está travada

App não conecta:

  • Confirmar ESP8266 na mesma rede WiFi
  • Verificar IP no monitor serial
  • Testar ping para o ESP8266
  • Verificar firewall/roteador

Pet não usa o bebedouro:

  • Posicionar na altura correta
  • Manter água sempre fresca
  • Limpeza regular da tigela
  • Transição gradual do bebedouro antigo

Código de diagnóstico:

Ver código completo
void runDiagnostics() {
  Serial.println("=== DIAGNÓSTICO BEBEDOURO ===");
  
  // Teste sensor
  measureWaterLevel();
  Serial.print("Sensor: ");
  Serial.println(waterLevel > 0 && waterLevel < 50 ? "OK" : "ERRO");
  
  // Teste bomba
  Serial.print("Bomba: ");
  digitalWrite(RELAY_PUMP_PIN, HIGH);
  delay(500);
  digitalWrite(RELAY_PUMP_PIN, LOW);
  Serial.println("Testada");
  
  // Teste WiFi
  Serial.print("WiFi: ");
  Serial.println(WiFi.status() == WL_CONNECTED ? "Conectado" : "Desconectado");
  
  // Teste display
  lcd.clear();
  lcd.print("Teste Display");
  Serial.println("Display: Testado");
  
  Serial.println("=============================");
}

Manutenção e Cuidados

Rotina de manutenção:

Diariamente:

  • Verificar nível do reservatório
  • Observar comportamento do pet
  • Conferir funcionamento via app

Semanalmente:

  • Limpeza completa da tigela
  • Verificação das mangueiras
  • Teste manual do sistema

Mensalmente:

  • Limpeza do reservatório
  • Calibração do sensor
  • Backup dos dados
  • Verificação das conexões elétricas

Trimestralmente:

  • Troca/limpeza do filtro de água
  • Lubrificação da bomba (se necessário)
  • Atualização do firmware
  • Revisão geral do sistema

Sinais de alerta:

Ver código completo
void checkMaintenanceAlerts() {
  static unsigned long lastClean = 0;
  
  // Alerta limpeza (7 dias)
  if (millis() - lastClean > 604800000) {
    sendNotification("Manutenção", "Hora de limpar o sistema");
    lastClean = millis();
  }
  
  // Consumo anormal
  if (dailyConsumption < PET_CONSUMPTION_DAILY * 0.3) {
    sendNotification("Alerta", "Pet bebendo pouco - verificar saúde");
  }
  
  if (dailyConsumption > PET_CONSUMPTION_DAILY * 2.0) {
    sendNotification("Alerta", "Consumo alto - possível vazamento");
  }
}

Análise de Custos e Benefícios

Comparação de investimento:

ItemDIYComercial Premium
Custo inicialR$ 400-700R$ 1.200-2.500
CustomizaçãoTotalLimitada
ManutençãoBarataAssistência técnica
RecursosExpandívelFixos
AprendizadoAltoZero

ROI estimado:

  • Economia vs. comercial: R$ 800-1.800
  • Tempo economizado: 5-10 min/dia
  • Tranquilidade: Inestimável
  • Payback: Imediato (qualidade de vida)

Benefícios para o pet:

  • Hidratação constante: Água sempre disponível
  • Saúde melhorada: Prevenção de problemas renais
  • Água limpa: Renovação automática
  • Monitoramento: Detecção precoce de problemas

Expansões Futuras

Versão 2.0 - Melhorias planejadas:

Ver código completo
// Recursos futuros a implementar:
// - Sensor de presença do pet
// - Análise de padrões de consumo
// - Integração com veterinário
// - Filtro UV para esterilização
// - Aquecimento para inverno
// - Câmera para monitoramento visual

Integração com outros projetos:

  • Alimentador automático: Sincronizar horários
  • Monitoramento de saúde: Análise integrada
  • Casa inteligente: Integração MQTT/Home Assistant
  • App unificado: Controle de todos os dispositivos pet

Código QR para configuração rápida:

Gerar QR code com:

  • SSID da rede WiFi
  • Senha da rede
  • IP do bebedouro
  • Link para manual online

Comparação: Bebedouro vs. Porta Pet

AspectoPorta PetBebedouro
DificuldadeIniciante/IntermediárioIntermediário/Avançado
Tempo4-6 horas8-12 horas
CustoR$ 600-900R$ 400-700
ProgramaçãoPython simplesArduino + ESP8266
RiscosBaixosÁgua + eletricidade
ManutençãoBaixaMédia
Impacto na saúdeExercícioHidratação vital

Conclusão

Com investimento de R$ 400-700, você cria um sistema completo que:

Benefícios imediatos:

  • Hidratação automática do pet 24/7
  • Monitoramento remoto via celular
  • Alertas de manutenção e problemas
  • Água sempre fresca e limpa

Vantagens técnicas:

  • Sistema expandível e customizável
  • Manutenção simples e barata
  • Código aberto para modificações
  • Integração com casa inteligente

Tranquilidade para o dono:

  • Pet nunca fica sem água
  • Monitoramento de saúde básico
  • Controle total mesmo longe de casa
  • Base para outros projetos pet

Próximos passos:

  • Monte o protótipo em protoboard primeiro
  • Teste por 1-2 semanas para ajustes
  • Implemente a versão final
  • Documente personalizações específicas
  • Considere evoluir para o alimentador automático

Este projeto é o primeiro passo perfeito para criar um ecossistema completo de automação para pets. Seu amigo de quatro patas vai adorar ter água fresca sempre disponível, e você ficará tranquilo sabendo que ele está sempre bem hidratado!

Por que este projeto é mais desafiador que a porta pet:

  • Múltiplos sistemas: Eletrônico + hidráulico + software
  • Segurança crítica: Combinação água + eletricidade
  • Calibração complexa: Sensores precisam ajuste fino
  • Estados de sistema: Lógica de controle mais elaborada
  • Comunicação dupla: Arduino ↔ ESP8266 ↔ App

Mas não se deixe intimidar! O resultado é extremamente gratificante e seu pet terá um sistema de hidratação que rivaliza com produtos comerciais de milhares de reais.

Série Completa: Automação Inteligente para Pets

Este bebedouro faz parte de uma série completa de projetos para criar um ecossistema inteligente para seu pet. Confira os outros projetos:

🍽️ Comedouro Inteligente com IA

Sistema que reconhece cada gato e controla a alimentação individual. Ideal para múltiplos pets ou dietas especiais.

  • • Reconhecimento facial por IA
  • • Controle de porções personalizadas
  • • Monitoramento nutricional
  • • R$ 300-500 | 4-6 horas
Ver Projeto Completo →

🚪 Porta Inteligente com IA

Porta automática que reconhece especificamente seu pet, permitindo entrada e saída seguras e controladas.

  • • Reconhecimento visual do pet
  • • Abertura automática
  • • Controle de horários
  • • R$ 600-900 | 4-6 horas
Ver Projeto Completo →

💡 Dica de Implementação

Ordem recomendada: Comece com o comedouro (mais simples), depois o bebedouro (intermediário) e por último a porta (requer mais instalação). Dessa forma você desenvolve experiência gradualmente e pode integrar os sistemas no final.