Se você tem mais de um gato ou se preocupa com o peso do seu felino, este projeto é para você! O comedouro inteligente usa reconhecimento facial para identificar cada gato e liberar a porção exata de ração, evitando que o gato guloso coma a comida do mais tímido ou que gatos com dieta especial comam além da conta.
Visão Geral do Projeto
- O que vamos construir: Sistema automatizado que reconhece gatos e controla alimentação individual
- Resultado: Cada gato come apenas sua porção, no horário certo
- Nível de dificuldade: Iniciante/Intermediário
- Tempo de construção: 4-6 horas (perfeito para um sábado)
- Custo estimado: R$ 300-500
Por que seu gato precisa de um comedouro inteligente?
Problemas comuns na alimentação felina:
- Obesidade felina: 60% dos gatos domésticos estão acima do peso ideal, causando diabetes e problemas articulares
- Competição alimentar: Em casas com múltiplos gatos, o dominante come demais e o submisso fica desnutrido
- Dietas especiais: Gatos diabéticos, alérgicos ou idosos precisam de rações específicas
- Horários irregulares: Alimentação fora de hora prejudica a digestão e causa ansiedade
- Desperdício: Ração exposta resseca e perde nutrients, gerando custos extras
Benefícios do comedouro inteligente:
- Controle de peso: Porções exatas para cada gato
- Paz entre gatos: Cada um come sua própria comida
- Saúde monitorada: Histórico de alimentação detecta problemas cedo
- Ração sempre fresca: Compartimentos fechados preservam qualidade
- Tranquilidade: Alimentação garantida mesmo quando você viaja
Material Necessário
Componentes eletrônicos:
- Raspberry Pi 4 (2GB) - R$ 400-500
- Câmera para Raspberry Pi - R$ 50-80
- Servo motor MG996R (mais forte que SG90) - R$ 35-50
- Célula de carga 5kg + HX711 - R$ 25-40
- Display OLED 128x64 - R$ 20-35
- Buzzer ativo 5V - R$ 5-10
- LEDs RGB - R$ 8-15
Estrutura física:
- Potes de ração herméticos (4x) - R$ 40-60
- Base MDF 40x30cm - R$ 25-35
- Tigelas inox pequenas (2x) - R$ 20-30
- Funil de plástico - R$ 8-15
- Parafusos e suportes - R$ 15-25
Componentes auxiliares:
- Cartão microSD 32GB - R$ 30-40
- Fonte 5V 3A - R$ 35-50
- Jumpers e protoboard - R$ 15-25
- Caixa plástica vedada - R$ 20-30
Custo total: R$ 300-500
⚠️ Importante: Este projeto é mais barato que os anteriores pois não precisa de ESP8266 (WiFi nativo do Pi) nem bomba d'água.
Como Funciona o Sistema
Fluxo de operação inteligente:
- Detecção: Câmera identifica gato se aproximando
- Reconhecimento: IA compara com fotos cadastradas
- Verificação: Sistema checa se já comeu hoje/horário
- Liberação: Servo motor libera porção exata
- Pesagem: Célula de carga confirma quantidade
- Registro: Dados salvos no histórico nutricional
Recursos avançados:
- Múltiplos perfis: Até 6 gatos diferentes
- Porções personalizadas: 20g a 150g por refeição
- Horários flexíveis: 1-6 refeições por dia
- Controle de peso: Metas de ganho/perda
- Alertas veterinários: Mudanças no apetite
- Modo férias: Alimentação automática por dias
Distribuição do Tempo de Construção
Total: 4-6 horas
Montagem da estrutura (1-2 horas):
- Corte e furação do MDF: 30 minutos
- Montagem dos compartimentos: 45 minutos
- Fixação dos servos: 30 minutos
- Acabamento: 15 minutos
Montagem eletrônica (1-2 horas):
- Conexões dos servos: 30 minutos
- Instalação da câmera: 15 minutos
- Montagem da célula de carga: 30 minutos
- Testes de funcionamento: 45 minutos
Programação e IA (1-2 horas):
- Configuração do Raspberry Pi: 30 minutos
- Treinamento da IA: 45 minutos
- Calibração dos servos: 30 minutos
- Testes com fotos de gatos: 15 minutos
Calibração e ajustes (1 hora):
- Ajuste de porções: 20 minutos
- Teste do ciclo completo: 20 minutos
- Configuração dos perfis: 20 minutos
Esquema de Ligações
Raspberry Pi - Conexões principais:
Raspberry Pi Componente ============= ================== GPIO 18 → Servo 1 (Compartimento A) GPIO 19 → Servo 2 (Compartimento B) GPIO 20 → Servo 3 (Compartimento C) GPIO 21 → Servo 4 (Compartimento D) GPIO 16 → Buzzer GPIO 26 → LED Status SDA (GPIO 2) → Display OLED (SDA) SCL (GPIO 3) → Display OLED (SCL) GPIO 5 → HX711 (DT) GPIO 6 → HX711 (SCK) Camera Port → Módulo câmera Pi 5V → Alimentação servos GND → Terra comum
Layout físico sugerido:
[Câmera] ↓ ┌─────────────────────────┐ │ 🥫A 🥫B 🥫C 🥫D │ ← Compartimentos de ração │ │ │ [Display] │ │ │ │ 🍽️ Tigela 1 🍽️ Tigela 2 │ ← Tigelas dos gatos │ (Peso) │ └─────────────────────────┘
Código Principal (Python)
Programa completo do comedouro:
Ver código completo
import cv2 import time import numpy as np from datetime import datetime, timedelta import json import threading from gpiozero import Servo, Buzzer, LED import board import busio import adafruit_ssd1306 from PIL import Image, ImageDraw, ImageFont import RPi.GPIO as GPIO from hx711 import HX711 import tensorflow as tf # =============== CONFIGURAÇÕES DO SISTEMA =============== class Config: # Pinos GPIO SERVOS = [18, 19, 20, 21] # 4 compartimentos BUZZER_PIN = 16 LED_PIN = 26 HX711_DT = 5 HX711_SCK = 6 # Configurações de alimentação MIN_PORTION = 20 # gramas MAX_PORTION = 150 # gramas MAX_DAILY_MEALS = 6 WEIGHT_TOLERANCE = 5 # ±5g # Configurações da câmera CAMERA_WIDTH = 640 CAMERA_HEIGHT = 480 DETECTION_CONFIDENCE = 0.75 # =============== CLASSE PRINCIPAL =============== class SmartFeeder: def __init__(self): self.config = Config() self.setup_hardware() self.load_cat_profiles() self.feeding_history = self.load_history() self.current_cat = None self.system_status = "Aguardando gato..." def setup_hardware(self): """Inicializa todos os componentes de hardware""" # Servos dos compartimentos self.servos = [] for pin in self.config.SERVOS: servo = Servo(pin) servo.min() # Posição fechada self.servos.append(servo) # Buzzer e LED self.buzzer = Buzzer(self.config.BUZZER_PIN) self.led = LED(self.config.LED_PIN) # Display OLED i2c = busio.I2C(board.SCL, board.SDA) self.display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) self.display.fill(0) self.display.show() # Célula de carga self.scale = HX711(self.config.HX711_DT, self.config.HX711_SCK) self.calibrate_scale() # Câmera self.camera = cv2.VideoCapture(0) self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, self.config.CAMERA_WIDTH) self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, self.config.CAMERA_HEIGHT) # Carregar modelo de IA self.load_ai_model() print("✅ Hardware inicializado com sucesso!") def load_ai_model(self): """Carrega modelo treinado do Teachable Machine""" try: self.model = tf.keras.models.load_model('cat_recognition_model.h5') with open('cat_labels.txt', 'r') as f: self.cat_labels = [line.strip() for line in f.readlines()] print("✅ Modelo de IA carregado!") except: print("⚠️ Modelo não encontrado. Use modo manual.") self.model = None self.cat_labels = [] def calibrate_scale(self): """Calibra a célula de carga""" print("Calibrando balança... Remova qualquer peso.") time.sleep(3) self.scale.reset() self.scale.tare() # Calibração com peso conhecido (ex: 100g) # self.scale.set_scale_ratio(100) # Ajustar conforme necessário print("✅ Balança calibrada!") def load_cat_profiles(self): """Carrega perfis dos gatos salvos""" try: with open('cat_profiles.json', 'r') as f: self.cat_profiles = json.load(f) except FileNotFoundError: # Perfis padrão para demonstração self.cat_profiles = { "Mimi": { "portion_size": 60, # gramas "meals_per_day": 3, "meal_times": ["08:00", "14:00", "20:00"], "compartment": 0, "diet_type": "adulto", "weight_goal": "manter" }, "Felix": { "portion_size": 40, # gato menor "meals_per_day": 4, "meal_times": ["07:00", "12:00", "17:00", "21:00"], "compartment": 1, "diet_type": "light", "weight_goal": "perder" } } self.save_cat_profiles() print(f"✅ {len(self.cat_profiles)} perfis de gatos carregados!") def save_cat_profiles(self): """Salva perfis dos gatos""" with open('cat_profiles.json', 'w') as f: json.dump(self.cat_profiles, f, indent=2) def load_history(self): """Carrega histórico de alimentação""" try: with open('feeding_history.json', 'r') as f: return json.load(f) except FileNotFoundError: return {} def save_history(self): """Salva histórico de alimentação""" with open('feeding_history.json', 'w') as f: json.dump(self.feeding_history, f, indent=2) # =============== RECONHECIMENTO DE GATOS =============== def recognize_cat(self, frame): """Usa IA para reconhecer qual gato está na imagem""" if self.model is None: return None, 0.0 # Pré-processar imagem img = cv2.resize(frame, (224, 224)) img = np.expand_dims(img, axis=0) img = img.astype('float32') / 255.0 # Fazer predição predictions = self.model.predict(img) confidence = np.max(predictions) cat_index = np.argmax(predictions) if confidence > self.config.DETECTION_CONFIDENCE: cat_name = self.cat_labels[cat_index] return cat_name, confidence return None, confidence def detect_cat_presence(self): """Detecta se há um gato na frente da câmera""" ret, frame = self.camera.read() if not ret: return None, None # Detector simples de movimento/presença gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Usar detector de gato (versão simplificada) # Em uma implementação real, usaria YOLO ou similar # Por agora, detectar se há movimento significativo if hasattr(self, 'previous_frame'): diff = cv2.absdiff(self.previous_frame, gray) motion = np.sum(diff) > 50000 # Threshold de movimento if motion: cat_name, confidence = self.recognize_cat(frame) self.previous_frame = gray return cat_name, confidence self.previous_frame = gray return None, 0.0 # =============== CONTROLE DE ALIMENTAÇÃO =============== def can_cat_eat(self, cat_name): """Verifica se o gato pode comer agora""" if cat_name not in self.cat_profiles: return False, "Gato não cadastrado" profile = self.cat_profiles[cat_name] today = datetime.now().strftime('%Y-%m-%d') # Verificar histórico de hoje if today in self.feeding_history: today_meals = self.feeding_history[today].get(cat_name, []) # Verificar se já atingiu limite diário if len(today_meals) >= profile['meals_per_day']: return False, f"Já comeu {len(today_meals)} vezes hoje" # Verificar se passou tempo suficiente desde última refeição if today_meals: last_meal = datetime.strptime(today_meals[-1]['time'], '%H:%M:%S') now = datetime.now() time_diff = now - last_meal.replace(year=now.year, month=now.month, day=now.day) if time_diff.seconds < 3600: # Mínimo 1 hora entre refeições minutes_left = 60 - (time_diff.seconds // 60) return False, f"Aguarde {minutes_left} minutos" return True, "Pode comer!" def dispense_food(self, cat_name): """Libera comida para o gato específico""" if cat_name not in self.cat_profiles: return False profile = self.cat_profiles[cat_name] compartment = profile['compartment'] portion_size = profile['portion_size'] print(f"🍽️ Liberando {portion_size}g para {cat_name}") # Tocar som de alimentação self.play_feeding_sound() # Abrir compartimento servo = self.servos[compartment] servo.max() # Abrir # Aguardar tempo baseado na porção (aprox. 1 segundo por 20g) dispense_time = (portion_size / 20) * 1.0 time.sleep(dispense_time) # Fechar compartimento servo.min() # Verificar peso dispensado weight_dispensed = self.check_dispensed_weight() # Registrar no histórico self.record_feeding(cat_name, portion_size, weight_dispensed) print(f"✅ Alimentação concluída! Peso: {weight_dispensed}g") return True def check_dispensed_weight(self): """Verifica peso da ração dispensada""" time.sleep(1) # Aguardar estabilizar weight = self.scale.get_weight(5) # Média de 5 leituras return max(0, weight) # Não retornar peso negativo def record_feeding(self, cat_name, target_portion, actual_weight): """Registra alimentação no histórico""" today = datetime.now().strftime('%Y-%m-%d') current_time = datetime.now().strftime('%H:%M:%S') if today not in self.feeding_history: self.feeding_history[today] = {} if cat_name not in self.feeding_history[today]: self.feeding_history[today][cat_name] = [] feeding_record = { 'time': current_time, 'target_portion': target_portion, 'actual_weight': actual_weight, 'accuracy': abs(target_portion - actual_weight) <= self.config.WEIGHT_TOLERANCE } self.feeding_history[today][cat_name].append(feeding_record) self.save_history() # =============== INTERFACE E DISPLAY =============== def update_display(self): """Atualiza informações no display OLED""" # Limpar display image = Image.new('1', (128, 64)) draw = ImageDraw.Draw(image) # Fonte pequena try: font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 10) font_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 8) except: font = ImageFont.load_default() font_small = ImageFont.load_default() # Título draw.text((0, 0), "Comedouro Smart", font=font, fill=255) # Status atual draw.text((0, 15), f"Status: {self.system_status}", font=font_small, fill=255) # Gato atual (se detectado) if self.current_cat: draw.text((0, 25), f"Gato: {self.current_cat}", font=font_small, fill=255) # Próximas refeições draw.text((0, 40), "Próximas refeições:", font=font_small, fill=255) y_pos = 50 for cat_name in list(self.cat_profiles.keys())[:2]: # Mostrar só 2 next_meal = self.get_next_meal_time(cat_name) if next_meal: draw.text((0, y_pos), f"{cat_name}: {next_meal}", font=font_small, fill=255) y_pos += 8 # Mostrar no display self.display.image(image) self.display.show() def get_next_meal_time(self, cat_name): """Calcula próximo horário de refeição para o gato""" if cat_name not in self.cat_profiles: return None profile = self.cat_profiles[cat_name] meal_times = profile['meal_times'] current_time = datetime.now().time() for meal_time_str in meal_times: meal_time = datetime.strptime(meal_time_str, '%H:%M').time() if meal_time > current_time: return meal_time_str # Se passou de todos os horários de hoje, retornar primeiro de amanhã return meal_times[0] + " (amanhã)" # =============== SONS E ALERTAS =============== def play_feeding_sound(self): """Toca som durante alimentação""" for _ in range(3): self.buzzer.on() time.sleep(0.1) self.buzzer.off() time.sleep(0.1) def play_error_sound(self): """Toca som de erro""" for _ in range(2): self.buzzer.on() time.sleep(0.3) self.buzzer.off() time.sleep(0.2) def play_recognition_sound(self): """Toca som quando reconhece gato""" self.buzzer.on() time.sleep(0.05) self.buzzer.off() # =============== LOOP PRINCIPAL =============== def run(self): """Loop principal do sistema""" print("🐱 Comedouro iniciado! Aguardando gatos...") self.led.on() # Sistema ativo while True: try: # Detectar presença de gato cat_name, confidence = self.detect_cat_presence() if cat_name and confidence > self.config.DETECTION_CONFIDENCE: if cat_name != self.current_cat: self.current_cat = cat_name self.system_status = f"Gato detectado: {cat_name}" print(f"🐱 {cat_name} detectado! (confiança: {confidence:.2f})") self.play_recognition_sound() # Verificar se pode comer can_eat, reason = self.can_cat_eat(cat_name) if can_eat: self.system_status = f"Alimentando {cat_name}..." success = self.dispense_food(cat_name) if success: self.system_status = f"{cat_name} alimentado!" else: self.system_status = "Erro na alimentação" self.play_error_sound() else: self.system_status = f"{cat_name}: {reason}" print(f"🚫 {cat_name} não pode comer: {reason}") if "Aguarde" not in reason: # Não tocar som para "aguarde" self.play_error_sound() else: if self.current_cat is not None: self.current_cat = None self.system_status = "Aguardando gato..." # Atualizar display self.update_display() # Aguardar um pouco antes da próxima verificação time.sleep(0.5) except KeyboardInterrupt: print(" 🛑 Sistema interrompido pelo usuário") break except Exception as e: print(f"❌ Erro: {e}") self.system_status = f"Erro: {str(e)[:20]}" time.sleep(1) self.cleanup() def cleanup(self): """Limpa recursos ao encerrar""" self.camera.release() self.led.off() self.display.fill(0) self.display.show() print("✅ Recursos liberados. Sistema encerrado.") # =============== FUNÇÕES AUXILIARES =============== def create_cat_profile(): """Função para criar novo perfil de gato""" print("=== Criando novo perfil de gato ===") name = input("Nome do gato: ") portion_size = int(input("Porção por refeição (g): ")) meals_per_day = int(input("Refeições por dia: ")) meal_times = [] for i in range(meals_per_day): time_str = input(f"Horário da refeição {i+1} (HH:MM): ") meal_times.append(time_str) compartment = int(input("Compartimento (0-3): ")) diet_type = input("Tipo de dieta (adulto/light/premium): ") weight_goal = input("Meta de peso (manter/ganhar/perder): ") profile = { "portion_size": portion_size, "meals_per_day": meals_per_day, "meal_times": meal_times, "compartment": compartment, "diet_type": diet_type, "weight_goal": weight_goal } return name, profile def train_cat_recognition(): """Função para treinar reconhecimento de gatos""" print("=== Treinamento de IA para reconhecimento ===") print("1. Acesse teachablemachine.withgoogle.com") print("2. Escolha 'Image Project'") print("3. Crie uma classe para cada gato") print("4. Tire 30-50 fotos de cada gato em diferentes ângulos") print("5. Treine o modelo") print("6. Baixe como 'Keras' (.h5)") print("7. Renomeie para 'cat_recognition_model.h5'") print("8. Crie arquivo 'cat_labels.txt' com nomes dos gatos") # =============== PROGRAMA PRINCIPAL =============== if __name__ == "__main__": print("🐱 Comedouro Inteligente para Gatos v1.0") print("========================================") try: feeder = SmartFeeder() feeder.run() except Exception as e: print(f"💥 Erro fatal: {e}") import traceback traceback.print_exc()
Interface Web Simples
Servidor web para monitoramento:
Ver código completo
from flask import Flask, render_template, jsonify, request import json from datetime import datetime app = Flask(__name__) @app.route('/') def index(): return render_template('dashboard.html') @app.route('/api/status') def get_status(): """Retorna status atual do sistema""" try: with open('feeding_history.json', 'r') as f: history = json.load(f) with open('cat_profiles.json', 'r') as f: profiles = json.load(f) today = datetime.now().strftime('%Y-%m-%d') today_feedings = history.get(today, {}) return jsonify({ 'status': 'online', 'cats': list(profiles.keys()), 'today_feedings': today_feedings, 'profiles': profiles }) except: return jsonify({'status': 'error'}) @app.route('/api/feed/<cat_name>') def manual_feed(cat_name): """Alimentação manual via web""" # Aqui você adicionaria comando para alimentar manualmente return jsonify({'status': 'feeding', 'cat': cat_name}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
Template HTML (dashboard.html):
Ver código completo
<!DOCTYPE html> <html> <head> <title>🐱 Comedouro Smart</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { font-family: Arial, sans-serif; background: linear-gradient(135deg, #FF6B6B, #4ECDC4); color: white; margin: 0; padding: 20px; } .container { max-width: 800px; margin: 0 auto; background: rgba(0,0,0,0.3); padding: 30px; border-radius: 20px; backdrop-filter: blur(10px </>); } .cat-card { background: rgba(255,255,255,0.1); margin: 15px 0; padding: 20px; border-radius: 15px; display: flex; justify-content: space-between; align-items: center; } .cat-info h3 { margin: 0; font-size: 1.5em; } .cat-stats { font-size: 0.9em; opacity: 0.8; } .feed-btn { background: linear-gradient(45deg, #FF6B6B, #FF8E8E); color: white; border: none; padding: 10px 20px; border-radius: 25px; cursor: pointer; transition: transform 0.3s; } .feed-btn:hover { transform: scale(1.05); } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin: 20px 0; } .stat-card { background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px; text-align: center; } .stat-value { font-size: 2em; font-weight: bold; } .stat-label { font-size: 0.9em; opacity: 0.8; } </style> </head> <body> <div class="container"> <h1>🐱 Comedouro Inteligente</h1> <div class="stats-grid"> <div class="stat-card"> <div class="stat-value" id="totalCats">--</div> <div class="stat-label">Gatos cadastrados</div> </div> <div class="stat-card"> <div class="stat-value" id="todayFeedings">--</div> <div class="stat-label">Refeições hoje</div> </div> <div class="stat-card"> <div class="stat-value" id="systemStatus">--</div> <div class="stat-label">Status do sistema</div> </div> </div> <div id="catsList"></div> </div> <script> function updateDashboard() { fetch('/api/status') .then(response => response.json()) .then(data => { document.getElementById('totalCats').textContent = data.cats.length; document.getElementById('systemStatus').textContent = data.status; // Contar refeições de hoje let totalFeedings = 0; Object.values(data.today_feedings).forEach(catFeedings => { totalFeedings += catFeedings.length; }); document.getElementById('todayFeedings').textContent = totalFeedings; // Mostrar gatos const catsList = document.getElementById('catsList'); catsList.innerHTML = ''; data.cats.forEach(catName => { const profile = data.profiles[catName]; const todayMeals = data.today_feedings[catName] || []; const catCard = document.createElement('div'); catCard.className = 'cat-card'; catCard.innerHTML = ` <div class="cat-info"> <h3>🐱 ${catName}</h3> <div class="cat-stats"> Porção: ${profile.portion_size}g | Refeições hoje: ${todayMeals.length}/${profile.meals_per_day} | Dieta: ${profile.diet_type} </div> </div> <button class="feed-btn" onclick="feedCat('${catName}')"> 🍽️ Alimentar </button> `; catsList.appendChild(catCard); }); }) .catch(error => { document.getElementById('systemStatus').textContent = 'Erro'; }); } function feedCat(catName) { fetch(`/api/feed/${catName}`) .then(response => response.json()) .then(data => { alert(`Alimentando ${catName}...`); setTimeout(updateDashboard, 2000); }); } // Atualizar a cada 10 segundos setInterval(updateDashboard, 10000); updateDashboard(); </script> </body> </html>
Montagem Física Detalhada
Estrutura principal:
Vista Superior:
┌─────────────────────────────────────┐ │ [CAM] [DISPLAY] │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ A │ │ B │ │ C │ │ D │ │ ← Compartimentos │ │🥫 │ │🥫 │ │🥫 │ │🥫 │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ ↓ ↓ ↓ ↓ │ │ ┌─────────────────────────────────┐ │ │ │ Área de distribuição │ │ │ └─────────────────────────────────┘ │ │ │ │ 🍽️ Tigela 1 🍽️ Tigela 2 │ │ [PESO] │ │ │ │ [Eletrônica] [Fonte] │ └─────────────────────────────────────┘
Mecanismo de distribuição:
Vista Lateral de um Compartimento:
🥫 Ração ┌─────────┐ │ │ │ 🌾 │ ← Ração armazenada │ 🌾 │ └─────┬───┘ │ ┌─────▼─────┐ ← Servo motor com "porta" │ [SERVO] │ └─────┬─────┘ │ ┌────▼────┐ ← Funil direcionador │ /\_/\ │ └─────────┘ │ ▼ 🍽️ Tigela
Lista de cortes MDF:
- Base principal: 40x30cm
- Divisórias compartimentos: 4x (8x8x10cm)
- Suporte câmera: 10x5cm
- Caixa eletrônica: 15x10x8cm
Configuração Passo a Passo
1. Preparação do Raspberry Pi:
Ver código completo
# Atualizar sistema sudo apt update && sudo apt upgrade -y # Instalar dependências sudo apt install python3-pip python3-opencv -y pip3 install tensorflow gpiozero adafruit-circuitpython-ssd1306 pip3 install flask pillow hx711 RPi.GPIO # Habilitar câmera sudo raspi-config # Interface Options > Camera > Enable # Reiniciar sudo reboot
2. Treinamento da IA:
Ver código completo
# Script para capturar fotos de treinamento import cv2 import os def capture_training_photos(cat_name, num_photos=50): """Captura fotos para treinar a IA""" camera = cv2.VideoCapture(0) # Criar pasta para o gato os.makedirs(f'training_data/{cat_name}', exist_ok=True) print(f"Capturando fotos do {cat_name}...") print("Pressione ESPAÇO para tirar foto, ESC para sair") photo_count = 0 while photo_count < num_photos: ret, frame = camera.read() if not ret: break cv2.imshow(f'Treinamento - {cat_name}', frame) key = cv2.waitKey(1) & 0xFF if key == ord(' '): # Espaço para capturar filename = f'training_data/{cat_name}/photo_{photo_count:03d}.jpg' cv2.imwrite(filename, frame) photo_count += 1 print(f"Foto {photo_count}/{num_photos} capturada!") elif key == 27: # ESC para sair break camera.release() cv2.destroyAllWindows() print(f"✅ {photo_count} fotos capturadas para {cat_name}") # Usar assim: capture_training_photos("Mimi", 50) capture_training_photos("Felix", 50)
3. Calibração da célula de carga:
Ver código completo
def calibrate_scale_interactive(): """Calibração interativa da balança""" from hx711 import HX711 scale = HX711(5, 6) # DT, SCK pins print("=== Calibração da Balança ===") print("1. Remova qualquer peso da balança") input("Pressione ENTER quando pronto...") scale.reset() scale.tare() print("✅ Zero definido!") print("2. Coloque um peso conhecido (ex: 100g)") known_weight = float(input("Digite o peso em gramas: ")) input("Pressione ENTER quando o peso estiver na balança...") reading = scale.get_weight(10) ratio = reading / known_weight scale.set_scale_ratio(ratio) print(f"✅ Calibração concluída! Ratio: {ratio}") # Teste print("3. Teste com diferentes pesos") for _ in range(5): weight = scale.get_weight(5) print(f"Peso atual: {weight:.1f}g") time.sleep(2) calibrate_scale_interactive()
Recursos Avançados
1. Análise nutricional:
Ver código completo
class NutritionalAnalyzer: def __init__(self): self.load_food_database() def load_food_database(self): """Carrega base de dados nutricionais""" self.food_db = { "adulto": {"calories_per_g": 3.5, "protein": 32, "fat": 12}, "light": {"calories_per_g": 3.0, "protein": 35, "fat": 8}, "premium": {"calories_per_g": 4.0, "protein": 38, "fat": 15} } def calculate_daily_nutrition(self, cat_name, date): """Calcula nutrição diária do gato""" # Buscar histórico do dia with open('feeding_history.json', 'r') as f: history = json.load(f) if date not in history or cat_name not in history[date]: return None # Calcular totais total_food = sum(meal['actual_weight'] for meal in history[date][cat_name]) # Buscar tipo de ração do gato with open('cat_profiles.json', 'r') as f: profiles = json.load(f) diet_type = profiles[cat_name]['diet_type'] nutrition = self.food_db[diet_type] return { 'total_food_g': total_food, 'total_calories': total_food * nutrition['calories_per_g'], 'protein_g': total_food * (nutrition['protein'] / 100), 'fat_g': total_food * (nutrition['fat'] / 100) }
2. Integração com veterinário:
Ver código completo
def generate_health_report(cat_name, days=30): """Gera relatório de saúde para o veterinário""" with open('feeding_history.json', 'r') as f: history = json.load(f) # Analisar últimos 30 dias from datetime import datetime, timedelta end_date = datetime.now() start_date = end_date - timedelta(days=days) report = { 'cat_name': cat_name, 'period': f"{start_date.strftime('%d/%m/%Y')} - {end_date.strftime('%d/%m/%Y')}", 'daily_consumption': [], 'feeding_regularity': [], 'appetite_changes': [] } # Analisar cada dia current_date = start_date while current_date <= end_date: date_str = current_date.strftime('%Y-%m-%d') if date_str in history and cat_name in history[date_str]: daily_meals = history[date_str][cat_name] daily_total = sum(meal['actual_weight'] for meal in daily_meals) report['daily_consumption'].append({ 'date': date_str, 'total_g': daily_total, 'meals_count': len(daily_meals) }) current_date += timedelta(days=1) # Detectar mudanças no apetite if len(report['daily_consumption']) > 7: recent_avg = sum(day['total_g'] for day in report['daily_consumption'][-7:]) / 7 older_avg = sum(day['total_g'] for day in report['daily_consumption'][:7]) / 7 change_percent = ((recent_avg - older_avg) / older_avg) * 100 if abs(change_percent) > 20: report['appetite_changes'].append({ 'type': 'increase' if change_percent > 0 else 'decrease', 'percentage': abs(change_percent), 'recommendation': 'Consultar veterinário' if abs(change_percent) > 30 else 'Monitorar' }) return report
3. Integração com outros dispositivos:
Ver código completo
def integrate_with_smart_home(): """Integração com sistemas de casa inteligente""" import paho.mqtt.client as mqtt # Configurar MQTT para Home Assistant client = mqtt.Client() client.connect("localhost", 1883, 60) def publish_feeding_event(cat_name, portion): """Publica evento de alimentação no MQTT""" topic = f"pet_feeder/{cat_name}/fed" payload = json.dumps({ 'timestamp': datetime.now().isoformat(), 'cat_name': cat_name, 'portion_g': portion, 'device': 'smart_feeder' }) client.publish(topic, payload) def publish_low_food_alert(compartment): """Alerta de ração baixa""" topic = "pet_feeder/alerts/low_food" payload = json.dumps({ 'compartment': compartment, 'timestamp': datetime.now().isoformat(), 'message': f'Ração baixa no compartimento {compartment}' }) client.publish(topic, payload)
Solução de Problemas
Problemas comuns:
IA não reconhece gatos:
- Verificar iluminação: Precisa de luz adequada
- Retreinar modelo: Adicionar mais fotos variadas
- Ajustar confiança: Diminuir threshold de 0.75 para 0.6
- Limpar lente: Câmera suja afeta reconhecimento
Servo não abre/fecha:
- Verificar alimentação: Servos precisam de 5V estável
- Testar manualmente: servo.max() e servo.min()
- Calibrar posições: Ajustar ângulos no código
- Verificar obstruções: Ração pode estar travando
Balança lendo errado:
- Recalibrar: Usar peso conhecido
- Verificar conexões: HX711 é sensível
- Estabilizar base: Vibração afeta leitura
- Aguardar estabilização: 2-3 segundos após movimento
Gatos não usam o comedouro:
- Período de adaptação: 1-2 semanas é normal
- Misturar com antigo: Transição gradual
- Verificar altura: Deve estar confortável
- Limpar regularmente: Gatos são sensíveis a odores
Código de diagnóstico:
Ver código completo
def run_system_diagnostics(): """Diagnóstico completo do sistema""" print("=== DIAGNÓSTICO COMEDOURO ===") # Teste da câmera camera = cv2.VideoCapture(0) ret, frame = camera.read() print(f"Câmera: {'✅ OK' if ret else '❌ ERRO'}") camera.release() # Teste dos servos from gpiozero import Servo servos_ok = 0 for i, pin in enumerate([18, 19, 20, 21]): try: servo = Servo(pin) servo.max() time.sleep(0.5) servo.min() servos_ok += 1 print(f"Servo {i}: ✅ OK") except: print(f"Servo {i}: ❌ ERRO") # Teste da balança try: from hx711 import HX711 scale = HX711(5, 6) weight = scale.get_weight(3) print(f"Balança: ✅ OK ({weight:.1f}g)") except: print("Balança: ❌ ERRO") # Teste do display try: import board import busio import adafruit_ssd1306 i2c = busio.I2C(board.SCL, board.SDA) display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) display.fill(1) display.show() time.sleep(1) display.fill(0) display.show() print("Display: ✅ OK") except: print("Display: ❌ ERRO") print("==============================") return servos_ok == 4 run_system_diagnostics()
Manutenção e Cuidados
Rotina de manutenção:
Diariamente:
- Verificar nível de ração nos compartimentos
- Limpar tigelas dos gatos
- Conferir funcionamento via app
Semanalmente:
- Limpeza completa dos compartimentos
- Verificação dos servos (lubrificar se necessário)
- Backup do histórico de alimentação
- Limpeza da lente da câmera
Mensalmente:
- Calibração da balança
- Atualização do software
- Verificação das conexões elétricas
- Análise do histórico nutricional
Trimestralmente:
- Retreinamento da IA (novas fotos)
- Limpeza profunda da estrutura
- Verificação do desgaste dos servos
- Backup completo do sistema
Comparação Final dos 3 Projetos
Aspecto | Porta Pet | Bebedouro | Comedouro |
---|---|---|---|
Dificuldade | Iniciante/Inter. | Inter./Avançado | Iniciante/Inter. |
Tempo | 4-6 horas | 8-12 horas | 4-6 horas |
Custo | R$ 600-900 | R$ 400-700 | R$ 300-500 |
IA Complexidade | Simples | Básica | Intermediária |
Riscos | Baixos | Água + energia | Baixíssimos |
Impacto Saúde | Exercício | Hidratação | Nutrição |
Manutenção | Baixa | Média | Baixa |
ROI | Alto | Muito Alto | Altíssimo |
Conclusão
O Comedouro Inteligente para Gatos é o projeto perfeito para completar sua jornada em automação pet tech! Com investimento de apenas R$ 300-500, você cria um sistema que:
Benefícios Imediatos:
- Controle total da alimentação de cada gato
- Prevenção da obesidade felina
- Paz entre gatos (cada um come sua porção)
- Monitoramento nutricional 24/7
Por que é ideal para iniciantes:
- Sem riscos elétricos (apenas 5V)
- Sem sistemas hidráulicos complexos
- IA acessível (Teachable Machine)
- Resultados imediatos e visíveis
Evolução natural:
- Mais simples que o bebedouro (sem água)
- Mais útil que a porta (impacto na saúde)
- Base para projetos futuros (alimentador + bebedouro integrados)
Próximos passos:
- Comece com 1 gato para testar
- Expanda para múltiplos gatos conforme confiança
- Integre com outros projetos da série
- Considere versão comercial (potencial de negócio!)
Este projeto fecha com chave de ouro sua trilogia DIY pet tech. Seus gatos terão nutrição controlada, você terá tranquilidade, e ainda aprenderá conceitos valiosos de IA e automação. É o investimento perfeito em tecnologia, saúde e felicidade felina!
Série Completa: Automação Inteligente para Pets
Este comedouro faz parte de uma série completa de projetos para criar um ecossistema inteligente para seu pet. Confira os outros projetos:
💧 Bebedouro Automático Inteligente
Sistema completo que mantém seu pet sempre hidratado com água fresca, monitoramento remoto e reabastecimento automático.
- • Reabastecimento automático
- • Monitoramento via app
- • Controle de consumo
- • R$ 400-700 | 8-12 horas
🚪 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
🎯 Por que começar pelo comedouro?
Mais fácil e seguro: Sem riscos elétricos (apenas 5V), sem sistemas hidráulicos, e resultados imediatos. É o projeto perfeito para desenvolver confiança antes de partir para os mais complexos bebedouro e porta automática.