VIXI, O ROBÔ GANHOU VIDA!

🧩 Integrando tudo: o protótipo completo

"O Robô Fofoqueiro ganha vida: integrando todos os módulos (som, fala, visão, IA, LEDs, display, mapa) em um único programa com menu interativo e modo automático."

Duração: 150 min (3 aulas)
Google Colab + Chromebook
BNCC: EM13CNT104 | EM13MAT503
🧩🤖✨
"O trem agora
é completo, vixi!"
Códigos BNCC

EM13CNT104 - Avaliar potencialidades de sistemas integrados.
EM13MAT503 - Implementar soluções computacionais para problemas reais.
Competências Gerais

Competência 5 - Compreender e usar tecnologias digitais.
Competência 6 - Trabalhar em equipe.
Etapas da Aula (150 minutos - 3 aulas)
Etapa Tempo Atividade
Abertura 10 min Revisar todos os módulos já construídos — "montar o quebra-cabeça".
Planejamento 20 min Em grupos, definir quem fica responsável por qual módulo na integração.
Codificação 60 min Construir o programa principal com menu (opções 1-9) e modo automático.
Teste integrado 40 min Executar o modo automático — simular barulho, fala, mão na câmera.
Fechamento 20 min Cada grupo demonstra seu programa rodando. Gerar README do robô.
Códigos RCP - Paraná

Programação - Projeto Integrador - Desenvolver sistemas completos com múltiplos componentes.
Trabalho Colaborativo - Organizar equipes para entregar produto funcional.
Módulos Integrados
Sensor de Som
Mede barulho da sala e gera alertas
Reconhecimento de Fala
Converte voz em texto com gírias
Visão Computacional
Detecta mãos e lê QR codes
IA Generativa
Conversa com personalidade paranaense
Display e LEDs
Alertas visuais simulados
Mapa do Inferno
Gráficos e heatmap do barulho
Materiais

  • Notebook Colab da aula anterior
  • Todos os códigos dos módulos prontos
  • Microfone e webcam (para testes reais)
Adaptações para inclusão

  • Grupos podem focar em diferentes partes e depois integrar
  • Alunos com mais dificuldade podem usar código base fornecido
robo_fofoqueiro_completo.py — Código completo da aula 8 download disponível
# ===================================================================
#            Robô Fofoqueiro - Protótipo Completo Integrado
# ===================================================================
# Objetivo: Integrar todos os módulos (som, fala, visão, IA, LEDs,
#           display, mapa) em um único programa com menu interativo
#           e modo automático. Esta é a versão final do projeto.
# Alunos: [A SER PREENCHIDO]
# Orientadora: Gisele Nunes
# Data  : 2026
# ===================================================================

# -*- coding: utf-8 -*-

# Importa o módulo sys para acessar funcionalidades do sistema,
# incluindo a verificação de módulos carregados.
import sys

# Importa o módulo os para manipular arquivos e pastas.
import os

# Importa o módulo time para adicionar pausas e temporizações.
import time

# Importa o módulo random para gerar valores aleatórios na simulação.
import random

# Importa o módulo json para salvar logs em formato estruturado.
import json

# Importa datetime para gerar timestamps precisos.
from datetime import datetime

# ============================================================
# BLOCO 1: VERIFICAÇÃO DO AMBIENTE
# ============================================================

def verifica_ambiente():
    """
    Verifica se o código está sendo executado no Google Colab ou em ambiente local.
    
    Retorna:
    str: 'colab' se estiver no Google Colab, 'local' caso contrário.
    """
    
    # Verifica se o módulo 'google.colab' está presente nos módulos carregados.
    if 'google.colab' in sys.modules:
        print("✅ Tamo no Colab! Vamos instalar as paradas com !pip.")
        return "colab"
    else:
        print("✅ Ambiente local detectado!")
        return "local"

# Chama a função para detectar o ambiente e armazena o resultado.
AMBIENTE = verifica_ambiente()

# ============================================================
# BLOCO 2: INSTALAÇÃO DAS BIBLIOTECAS
# ============================================================

print("\n📦 Verificando/Instalando as bibliotecas...")

# Se o ambiente for o Google Colab, instala todas as bibliotecas necessárias.
if AMBIENTE == "colab":
    # Instala todas as bibliotecas principais do projeto.
    !pip install speechrecognition gtts opencv-python-headless pandas numpy matplotlib seaborn qrcode[pil] pillow google-generativeai -q
    
    # Instala o ffmpeg para manipulação de áudio (necessário para pydub/gTTS).
    !apt-get install -y ffmpeg -qq
    
    print("✅ Bibliotecas instaladas.")
else:
    # Se for ambiente local, apenas avisa o que precisa ser instalado.
    print("⚠️ Ambiente local: certifique-se de ter instalado todas as bibliotecas.")

# ============================================================
# BLOCO 3: IMPORTAÇÃO DAS BIBLIOTECAS
# ============================================================

# Importa numpy para operações matemáticas com arrays.
import numpy as np

# Importa pandas para manipulação de dados estruturados (DataFrames).
import pandas as pd

# Importa matplotlib.pyplot para criação de gráficos e visualizações.
import matplotlib.pyplot as plt

# Importa seaborn para visualizações estatísticas avançadas.
import seaborn as sns

# Tenta importar a biblioteca SpeechRecognition para reconhecimento de fala.
try:
    import speech_recognition as sr
    HAS_SPEECH = True   # Flag indicando que o módulo está disponível.
except ImportError:
    HAS_SPEECH = False  # Flag indicando que o módulo NÃO está disponível.
    print("⚠️ SpeechRecognition não disponível")

# Tenta importar OpenCV e MediaPipe para visão computacional.
try:
    import cv2
    import mediapipe as mp
    HAS_VISION = True   # Flag indicando que os módulos estão disponíveis.
except ImportError:
    HAS_VISION = False  # Flag indicando que os módulos NÃO estão disponíveis.
    print("⚠️ OpenCV/MediaPipe não disponível")

# Tenta importar a biblioteca Google Generative AI para o Gemini.
try:
    import google.generativeai as genai
    HAS_GEMINI = True   # Flag indicando que o módulo está disponível.
except ImportError:
    HAS_GEMINI = False  # Flag indicando que o módulo NÃO está disponível.
    print("⚠️ Google Generative AI não disponível")

print("\n🎉 Bibliotecas importadas! Bora integrar tudo, meu consagrado!")

# ============================================================
# BLOCO 4: ARTE ASCII DO ROBÔ (VERSÃO COMPLETA)
# ============================================================

# String com arte ASCII representando o robô na versão completa integrada.
# Inclui emojis de quebra-cabeça (🧩), robô (🤖) e brilho (✨).
ascii_robo_completo = r"""
╔══════════════════════════════════════════════════════════════════════════╗
║ 🧩🤖✨                                                                   ║
║ 🤖 ROBÔ FOFOQUEIRO - VERSÃO COMPLETA INTEGRADA 🤖                        ║
║ "O trem agora é completo, vixi! Bora fofocar com responsa!"              ║
║ "Acessibilidade com humor é possível, piá!"                             ║
╚══════════════════════════════════════════════════════════════════════════╝
"""

# Exibe a arte ASCII na tela.
print(ascii_robo_completo)

# ============================================================
# BLOCO 5: SENSOR DE SOM (SIMULADO E REAL)
# ============================================================

def medidor_som_simulado():
    """
    Simula a medição de intensidade sonora (decibéis).
    Usa valores aleatórios pré-definidos para demonstrar o comportamento.
    
    Retorna:
    int: valor simulado de intensidade sonora (entre aproximadamente 15 e 115 dB).
    """
    
    # Lista de níveis possíveis (exemplos).
    niveis = [20, 45, 60, 80, 95, 110]
    
    # Escolhe um nível aleatório e adiciona um pequeno ruído (-5 a +5).
    return random.choice(niveis) + random.randint(-5, 5)

def medidor_som_real():
    """
    Tenta medir som real com microfone usando PyAudio.
    Se falhar (biblioteca não instalada ou erro), usa o modo simulado.
    
    Retorna:
    float: valor medido em decibéis (0-120).
    """
    
    # Se o módulo SpeechRecognition não está disponível, usa simulação.
    if not HAS_SPEECH:
        return medidor_som_simulado()
    
    try:
        # Importa as bibliotecas necessárias (importação local para evitar erros).
        import pyaudio
        import numpy as np
        
        # Parâmetros de captura de áudio.
        DURACAO = 2                     # Duração da captura em segundos.
        TAXA_AMOSTRAGEM = 44100         # Taxa de amostragem (44.1 kHz).
        TAMANHO_BUFFER = 1024           # Tamanho do buffer de leitura.
        
        # Cria uma instância do PyAudio.
        audio = pyaudio.PyAudio()
        
        # Abre um stream de áudio para captura.
        stream = audio.open(
            format=pyaudio.paInt16,     # Formato 16 bits por sample.
            channels=1,                 # Mono (um canal).
            rate=TAXA_AMOSTRAGEM,       # Taxa de amostragem definida.
            input=True,                 # Modo captura.
            frames_per_buffer=TAMANHO_BUFFER
        )
        
        # Lista para armazenar os frames capturados.
        frames = []
        
        # Calcula quantos blocos são necessários para DURACAO segundos.
        for _ in range(0, int(TAXA_AMOSTRAGEM / TAMANHO_BUFFER * DURACAO)):
            # Lê um bloco de dados do microfone.
            data = stream.read(TAMANHO_BUFFER)
            # Converte bytes para array numpy de inteiros de 16 bits.
            dados_audio = np.frombuffer(data, dtype=np.int16)
            frames.append(dados_audio)
        
        # Para e fecha o stream de áudio.
        stream.stop_stream()
        stream.close()
        audio.terminate()
        
        # Concatena todos os frames em um único array.
        audio_data = np.concatenate(frames)
        
        # Calcula o RMS (Root Mean Square) do sinal de áudio.
        rms = np.sqrt(np.mean(audio_data**2))
        
        # Valor máximo possível para um sinal int16.
        max_rms = 32768
        
        # Converte RMS para escala simulada de decibéis (0-120).
        decibeis = (rms / max_rms) * 120
        
        # Garante que o valor esteja dentro dos limites 0-120.
        return min(120, max(0, decibeis))
    
    except Exception:
        # Se qualquer erro ocorrer, fallback para simulação.
        return medidor_som_simulado()

# ============================================================
# BLOCO 6: RECONHECIMENTO DE FALA
# ============================================================

def reconhecer_fala():
    """
    Reconhece fala do microfone usando a API do Google Speech Recognition.
    Retorna o texto reconhecido ou None em caso de erro.
    
    Retorna:
    str or None: texto reconhecido ou None se falhou.
    """
    
    # Se o módulo SpeechRecognition não está disponível, avisa e retorna None.
    if not HAS_SPEECH:
        print("⚠️ Modo simulado: use o menu para testar com digitação")
        return None
    
    try:
        # Cria uma instância do reconhecedor de fala.
        recognizer = sr.Recognizer()
        
        # Abre o microfone como fonte de áudio.
        with sr.Microphone() as source:
            print("🎤 Fale alguma coisa...")
            
            # Ajusta o reconhecedor para o ruído ambiente (0.5 segundo).
            recognizer.adjust_for_ambient_noise(source, duration=0.5)
            
            # Escuta o áudio (timeout=5s, phrase_time_limit=5s).
            audio = recognizer.listen(source, timeout=5, phrase_time_limit=5)
            
            # Tenta reconhecer usando a API do Google em português do Brasil.
            texto = recognizer.recognize_google(audio, language="pt-BR")
            return texto
    
    except sr.UnknownValueError:
        # O Google não entendeu o áudio.
        print("❌ Não entendi o que você disse!")
        return None
    
    except sr.RequestError:
        # Erro de conexão com a API do Google.
        print("❌ Erro na requisição ao Google!")
        return None
    
    except Exception as e:
        # Qualquer outro erro.
        print(f"❌ Erro: {e}")
        return None

# ============================================================
# BLOCO 7: VISÃO COMPUTACIONAL (SIMULADO)
# ============================================================

def modo_visao_simulado():
    """
    Versão simulada da visão computacional.
    Gera aleatoriamente um número de dedos levantados (0-5) e
    um QR code simulado com mensagens engraçadas.
    
    Retorna:
    dict: dicionário com 'dedos' e 'qr_code'.
    """
    
    print("\n🎭 MODO VISÃO SIMULADO")
    print("="*40)
    
    # Simula detecção de mão com número aleatório de dedos (0-5).
    dedos = random.randint(0, 5)
    
    # Dicionário com mensagens para cada quantidade de dedos.
    mensagens = {
        0: "✊ Nenhum dedo! Tá com raiva, piá?",
        1: "☝️ 1 dedo! Tá apontando pra alguém?",
        2: "✌️ 2 dedos! Vitória, é ou não é bagulho doido?",
        3: "🤟 3 dedos! Rock and roll, tchê!",
        4: "🤙 4 dedos! Hang loose, descolado!",
        5: "🖐️ 5 dedos! Tchau pra fofoca, guria!"
    }
    
    # Exibe a mensagem correspondente (ou genérica se não encontrada).
    print(f"🤚 Mão detectada: {mensagens.get(dedos, '🤚 Mão detectada!')}")
    
    # Lista de QR codes simulados (mensagens engraçadas).
    qrs_simulados = [
        "Curitiba é a capital da Russia brasileira kkk",
        "https://projetosgn.com.br/acessibilidade",
        "Vixi, o Robô Fofoqueiro é bagulho doido!",
        "Acessibilidade com humor é possível!"
    ]
    
    # Escolhe um QR code aleatório.
    qr_simulado = random.choice(qrs_simulados)
    print(f"📱 QR Code lido: {qr_simulado}")
    
    # Retorna os resultados em um dicionário.
    return {"dedos": dedos, "qr_code": qr_simulado}

# ============================================================
# BLOCO 8: IA GENERATIVA (COM FALLBACK)
# ============================================================

# Lista de gírias paranaenses para usar nas respostas offline.
GIRIAS = ["vixi", "égua", "piá", "guria", "bagulho doido", "ó o trem", "tchê", "bah"]

def responder_sem_ia(pergunta):
    """
    Respostas offline sem API (fallback quando o Gemini não está disponível).
    Usa templates pré-definidos combinados com gírias aleatórias.
    
    Parâmetros:
    pergunta: str - a pergunta feita pelo usuário.
    
    Retorna:
    str - uma resposta gerada offline.
    """
    
    # Lista de templates de resposta.
    respostas = [
        f"Vixi, não tô conectado na nuvem hoje, mas sei que {pergunta[:30]}... é bagulho doido! {random.choice(GIRIAS)}!",
        f"Piá, sem API eu fico limitado, mas posso te contar que {pergunta[:30]} é coisa séria. {random.choice(GIRIAS)}!",
        f"Ó o trem, meu consagrado! Mesmo offline eu sei que {pergunta[:30]} é importante pra acessibilidade. {random.choice(GIRIAS)}!",
        f"Tchê, num instalei a inteligência hoje, mas vai uma fofoca: {pergunta[:30]} é massa! {random.choice(GIRIAS)}!"
    ]
    
    # Escolhe e retorna uma resposta aleatória.
    return random.choice(respostas)

def responder_com_ia(pergunta, modelo):
    """
    Gera resposta usando IA (Gemini) ou fallback offline.
    
    Parâmetros:
    pergunta: str - a pergunta feita pelo usuário.
    modelo: GenerativeModel or None - modelo configurado ou None para offline.
    
    Retorna:
    str - a resposta gerada.
    """
    
    # Se o modelo existe e é válido, tenta usar IA.
    if modelo and modelo != False:
        try:
            # Constrói o prompt com a personalidade do robô.
            prompt = f"""
Você é o ROBÔ FOFOQUEIRO DA ACESSIBILIDADE, um assistente bem-humorado com sotaque do Paraná.
Características: usa gírias como vixi, égua, piá, guria, bagulho doido, ó o trem, tchê.
Respostas curtas e engraçadas. Fala sobre acessibilidade digital.

Usuário: {pergunta}
Robô Fofoqueiro:"""
            
            # Gera a resposta usando o modelo Gemini.
            resposta = modelo.generate_content(prompt)
            texto = resposta.text.strip()
            
            # Garante que a resposta tenha pelo menos uma gíria.
            if not any(g in texto.lower() for g in GIRIAS[:3]):
                texto += f" {random.choice(GIRIAS)}!"
            
            return texto
        
        except Exception as e:
            # Se ocorrer erro na API, usa fallback offline.
            print(f"⚠️ Erro na IA: {e}")
            return responder_sem_ia(pergunta)
    
    else:
        # Se o modelo não está disponível, usa fallback offline.
        return responder_sem_ia(pergunta)

# ============================================================
# BLOCO 9: DISPLAY E LEDS SIMULADOS
# ============================================================

class DisplayLCDSimulado:
    """
    Classe que simula um display LCD 16x2 usando texto no terminal.
    Versão simplificada para o protótipo completo.
    """
    
    def __init__(self):
        """Inicializa o display com duas linhas vazias (16 espaços cada)."""
        self.linhas = [" " * 16, " " * 16]
    
    def escrever_linha(self, linha, texto):
        """
        Escreve um texto em uma linha específica (0 ou 1).
        
        Parâmetros:
        linha: int - 0 para linha superior, 1 para linha inferior.
        texto: str - o texto a ser exibido (será truncado para 16 caracteres).
        """
        
        # Verifica se a linha é válida (0 ou 1).
        if linha in [0, 1]:
            # Trunca o texto para 16 caracteres e alinha à esquerda.
            self.linhas[linha] = texto[:16].ljust(16)
        
        # Atualiza a exibição.
        self._mostrar()
    
    def escrever_mensagem(self, mensagem):
        """
        Exibe uma mensagem no display (apenas na primeira linha).
        
        Parâmetros:
        mensagem: str - a mensagem a ser exibida.
        """
        
        print(f"\n📟 DISPLAY: {mensagem[:16]}")
        self.escrever_linha(0, mensagem[:16])
        self.escrever_linha(1, "🤖 Robô Ativo")
    
    def alerta_sonoro(self, intensidade):
        """
        Exibe alerta visual no display baseado na intensidade do som.
        
        Parâmetros:
        intensidade: float - nível de decibéis (0-120).
        """
        
        if intensidade > 75:
            self.escrever_mensagem("🚨 SILÊNCIO!")
            print("🔴🔴🔴 LED VERMELHO PISCANDO! 🔴🔴🔴")
        elif intensidade > 50:
            self.escrever_mensagem("⚠️ FICANDO ALTO")
            print("🟡 LED AMARELO ACESO!")
        else:
            self.escrever_linha(1, f"🔊 {intensidade:.0f} dB")
    
    def _mostrar(self):
        """Desenha o display no terminal com moldura."""
        print(f"┌────────────────┐")
        print(f"│{self.linhas[0]}│")
        print(f"│{self.linhas[1]}│")
        print(f"└────────────────┘")

class LedRGBSimulado:
    """
    Classe que simula um LED RGB usando emojis no terminal.
    Versão simplificada para o protótipo completo.
    """
    
    def __init__(self):
        """Inicializa o LED com a cor desligada (⚫)."""
        self.cor_atual = "⚫"
    
    def alerta_som(self, intensidade):
        """
        Altera a cor do LED baseado na intensidade do som.
        
        Parâmetros:
        intensidade: float - nível de decibéis (0-120).
        """
        
        if intensidade > 75:
            self.cor_atual = "🔴"
            print(f"💡 LED: {self.cor_atual} VERMELHO PISCANDO!")
        elif intensidade > 50:
            self.cor_atual = "🟡"
            print(f"💡 LED: {self.cor_atual} AMARELO")
        elif intensidade > 30:
            self.cor_atual = "🟢"
            print(f"💡 LED: {self.cor_atual} VERDE")
        else:
            self.cor_atual = "🔵"
            print(f"💡 LED: {self.cor_atual} AZUL")
    
    def desligar(self):
        """Desliga o LED."""
        self.cor_atual = "⚫"
        print("💡 LED desligado")

# ============================================================
# BLOCO 10: MAPA DO INFERNO ACÚSTICO
# ============================================================

def gerar_mapa_barulho():
    """
    Gera gráficos do mapa de barulho (evolução ao longo do dia).
    Cria um gráfico de linha com zonas coloridas (verde, amarelo, vermelho).
    """
    
    print("\n📊 GERANDO MAPA DO INFERNO ACÚSTICO")
    
    # Gera dados simulados de medição para cada hora (8h às 17h).
    horarios = [f"{h:02d}:00" for h in range(8, 18)]
    dados = []
    
    for i, horario in enumerate(horarios):
        # Extrai a hora do horário.
        hora = int(horario[:2])
        
        # Define o nível base de acordo com o horário.
        if hora == 12:  # Horário de intervalo.
            db = 85 + random.randint(-10, 10)
        elif 9 <= hora <= 11:  # Meio da manhã.
            db = 70 + random.randint(-15, 15)
        else:  # Outros horários.
            db = 50 + random.randint(-15, 15)
        
        # Garante que o valor fique entre 20 e 120 dB.
        dados.append({"Horario": horario, "dB": max(20, min(120, db))})
    
    # Converte a lista de dicionários em um DataFrame do pandas.
    df = pd.DataFrame(dados)
    
    # Cria o gráfico de linha.
    plt.figure(figsize=(12, 6))
    
    # Adiciona zonas coloridas de fundo.
    plt.axhspan(0, 40, alpha=0.2, color='green', label='Silêncio')
    plt.axhspan(40, 75, alpha=0.2, color='yellow', label='Atenção')
    plt.axhspan(75, 120, alpha=0.2, color='red', label='Alerta')
    
    # Plota a linha principal.
    plt.plot(df['Horario'], df['dB'], 'b-o', linewidth=2, markersize=6)
    
    # Adiciona linha pontilhada no limite de alerta (75 dB).
    plt.axhline(y=75, color='red', linestyle='--', label='Limite 75 dB')
    
    # Configura os rótulos e título.
    plt.title('📊 Mapa do Inferno Acústico - Evolução do Barulho')
    plt.xlabel('Horário')
    plt.ylabel('Decibéis (dB)')
    
    # Rotaciona os rótulos do eixo X para melhor legibilidade.
    plt.xticks(rotation=45)
    
    # Adiciona legenda.
    plt.legend()
    
    # Ajusta o layout e salva o gráfico.
    plt.tight_layout()
    plt.savefig('mapa_inferno_acustico.png', dpi=150)
    plt.show()
    
    print("💾 Gráfico salvo como 'mapa_inferno_acustico.png'")
    
    # Calcula e exibe estatísticas.
    media = df['dB'].mean()
    alertas = len(df[df['dB'] > 75])
    print(f"\n📈 Estatísticas: Média={media:.0f}dB | Alertas={alertas}")
    print(f"🔴 Horário mais barulhento: {df.loc[df['dB'].idxmax(), 'Horario']} ({df['dB'].max():.0f}dB)")

# ============================================================
# BLOCO 11: MODO AUTOMÁTICO
# ============================================================

def modo_automatico():
    """
    Executa o ciclo completo automaticamente, demonstrando
    todas as funcionalidades do robô em sequência.
    """
    
    print("\n" + "="*60)
    print("🤖 MODO AUTOMÁTICO - Robô Fofoqueiro em Ação!")
    print("="*60)
    
    # 1. Sensor de som
    print("\n🔊 1. MEDINDO O BARULHO DA SALA...")
    intensidade = medidor_som_simulado()
    print(f"   Nível: {intensidade:.0f} dB")
    
    # 2. Display e LEDs
    print("\n💡 2. ATUALIZANDO DISPLAY E LEDS...")
    display = DisplayLCDSimulado()
    led = LedRGBSimulado()
    display.alerta_sonoro(intensidade)
    led.alerta_som(intensidade)
    
    # 3. Reconhecimento de fala (simulado)
    print("\n🗣️ 3. RECONHECENDO FALA (simulado)...")
    falas = ["Vixi, que legal!", "O robô está funcionando!", "Acessibilidade é importante!"]
    fala_simulada = random.choice(falas)
    print(f"   🎤 Usuário disse: '{fala_simulada}'")
    print(f"   🤖 Robô respondeu: '{responder_sem_ia(fala_simulada)}'")
    
    # 4. Visão computacional
    print("\n👁️ 4. VISÃO COMPUTACIONAL...")
    visao = modo_visao_simulado()
    
    # 5. Mapa do barulho
    print("\n📊 5. GERANDO MAPA DO BARULHO...")
    gerar_mapa_barulho()
    
    # 6. Salvando log da sessão
    print("\n📝 6. SALVANDO LOG DA SESSÃO...")
    log = {
        "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "nivel_som": intensidade,
        "fala_usuario": fala_simulada,
        "visao_dedos": visao.get("dedos", 0),
        "visao_qr": visao.get("qr_code", "")
    }
    
    # Garante que a pasta logs existe e salva o log em formato JSON.
    os.makedirs("logs", exist_ok=True)
    with open("logs/sessao_automatica.json", "a", encoding="utf-8") as f:
        json.dump(log, f, ensure_ascii=False)
        f.write("\n")  # Adiciona quebra de linha entre logs.
    
    print("\n" + "="*60)
    print("✅ MODO AUTOMÁTICO CONCLUÍDO COM SUCESSO!")
    print("="*60)
    print("\n💾 Logs salvos na pasta 'logs/'")
    print("📁 Gráfico salvo como 'mapa_inferno_acustico.png'")

# ============================================================
# BLOCO 12: DIAGNÓSTICO DO ROBÔ
# ============================================================

def diagnosticar_robo():
    """
    Verifica o status de todos os módulos do robô.
    Exibe disponibilidade de bibliotecas, estrutura de pastas e dados salvos.
    """
    
    print("\n" + "="*60)
    print("🔧 DIAGNÓSTICO DO ROBÔ FOFOQUEIRO")
    print("="*60)
    
    # Verifica o status de cada módulo.
    modulos = {
        "SpeechRecognition": HAS_SPEECH,
        "OpenCV": HAS_VISION,
        "MediaPipe": HAS_VISION,
        "Google Generative AI": HAS_GEMINI
    }
    
    for modulo, status in modulos.items():
        if status:
            print(f"✅ {modulo}: disponível")
        else:
            print(f"❌ {modulo}: não disponível")
    
    # Verifica/ Cria a estrutura de pastas.
    print("\n📁 Estrutura de pastas:")
    pastas = ["logs", "sons", "imagens", "codigos"]
    for pasta in pastas:
        if os.path.exists(pasta):
            print(f"✅ {pasta}/ existe")
        else:
            os.makedirs(pasta, exist_ok=True)
            print(f"📁 {pasta}/ criada")
    
    # Verifica se existem medições salvas.
    print("\n📊 Total de medições salvas:")
    if os.path.exists("log_fofoqueiro.csv"):
        df = pd.read_csv("log_fofoqueiro.csv")
        print(f"   {len(df)} medições registradas")
    else:
        print("   Nenhuma medição encontrada")
    
    print("="*60)

# ============================================================
# BLOCO 13: GERAR README DO PROJETO
# ============================================================

def gerar_readme():
    """
    Gera o arquivo README.md do projeto com documentação completa.
    Inclui descrição do projeto, módulos, tecnologias, BNCC e equipe.
    """
    
    # Conteúdo do README em formato Markdown.
    readme_content = f"""# 🤖 Robô Fofoqueiro da Acessibilidade

## 🎯 Sobre o Projeto
"O Robô Fofoqueiro da Acessibilidade" é um projeto desenvolvido por estudantes do Ensino Médio que integra programação, inteligência artificial, visão computacional e hardware para criar um assistente robótico com personalidade paranaense.

## 📚 Módulos do Sistema

| Módulo | Funcionalidade | Status |
|--------|----------------|--------|
| Sensor de Som | Mede barulho e gera alertas | ✅ |
| Reconhecimento de Fala | Converte voz em texto com gírias | ✅ |
| Visão Computacional | Detecta mãos e lê QR codes | ✅ |
| IA Generativa | Conversa com personalidade | ✅ |
| Display e LEDs | Alertas visuais simulados | ✅ |
| Mapa do Inferno | Gráficos e heatmap do barulho | ✅ |

## 🛠️ Tecnologias Utilizadas
- Python
- Google Colab
- SpeechRecognition / gTTS
- OpenCV / MediaPipe
- Google Gemini API
- Pandas / Matplotlib / Seaborn

## 🎯 BNCC Trabalhadas
- EM13CNT104 - Sistemas integrados
- EM13MAT503 - Soluções computacionais
- EM13LGG702 - IA generativa
- EM13CNT101 - Modelos físicos

## 👥 Equipe
Desenvolvido por estudantes sob orientação da Tutora Gisele Nunes.

## 📅 Data de Conclusão
{datetime.now().strftime("%d/%m/%Y")}

---
*"O trem agora é completo, vixi! Bora fofocar com responsa sobre acessibilidade!" - Robô Fofoqueiro 🤖*
"""
    
    # Salva o README em um arquivo.
    with open("README_ROBO_FOFOQUEIRO.md", "w", encoding="utf-8") as f:
        f.write(readme_content)
    
    print("\n💾 README gerado como 'README_ROBO_FOFOQUEIRO.md'")
    print(readme_content[:500] + "...\n")

# ============================================================
# BLOCO 14: MENU PRINCIPAL INTEGRADO
# ============================================================

def main():
    """
    Função principal com menu interativo integrando TODOS os módulos.
    Retorna True para continuar no loop, False para sair.
    """
    
    print("\n" + "="*60)
    print("🤖 ROBÔ FOFOQUEIRO - VERSÃO COMPLETA INTEGRADA")
    print("="*60)
    print("1 - Sensor de Som (medir barulho da sala)")
    print("2 - Reconhecimento de Fala (falar com o robô)")
    print("3 - Visão Computacional (mãos e QR codes)")
    print("4 - IA Generativa (conversar com o robô inteligente)")
    print("5 - Display e LEDs (alertas visuais simulados)")
    print("6 - Mapa do Inferno Acústico (gráficos e heatmap)")
    print("7 - MODO AUTOMÁTICO (roda tudo sozinho!)")
    print("8 - Diagnóstico do robô")
    print("9 - Gerar README do projeto")
    print("0 - Sair")
    print("="*60)
    
    # Solicita a opção do usuário.
    opcao = input("👉 Escolha uma opção (0-9): ").strip()
    
    # Sensor de Som
    if opcao == '1':
        print("\n🔊 SENSOR DE SOM")
        intensidade = medidor_som_simulado()
        print(f"🎤 Nível de barulho: {intensidade:.1f} dB")
        
        if intensidade > 75:
            print("🚨 INFERNO ACÚSTICO! TÁ MUITO ALTO, PIÁ!")
        elif intensidade > 50:
            print("⚠️ TÁ FICANDO BARULHENTO, ATENÇÃO!")
        else:
            print("🤫 Silêncio absoluto... até assusta!")
    
    # Reconhecimento de Fala
    elif opcao == '2':
        print("\n🗣️ RECONHECIMENTO DE FALA")
        
        if HAS_SPEECH:
            texto = reconhecer_fala()
            if texto:
                print(f"✅ Você disse: {texto}")
                os.makedirs("logs", exist_ok=True)
                with open("logs/falas_reconhecidas.txt", "a", encoding="utf-8") as f:
                    f.write(f"{datetime.now()} - {texto}\n")
        else:
            # Modo simulado: permite digitar a frase.
            print("⚠️ Modo simulado: digite uma frase:")
            texto = input("🧑 Você: ")
            print(f"✅ Frase registrada: {texto}")
    
    # Visão Computacional
    elif opcao == '3':
        modo_visao_simulado()
    
    # IA Generativa
    elif opcao == '4':
        print("\n🧠 IA GENERATIVA")
        modelo = None
        
        # Tenta configurar o Gemini se disponível.
        if HAS_GEMINI:
            try:
                # Tenta pegar a chave da API da variável de ambiente.
                chave = os.environ.get("GEMINI_API_KEY", "")
                if chave:
                    genai.configure(api_key=chave)
                    modelo = genai.GenerativeModel('gemini-1.5-flash')
                    print("✅ IA online!")
                else:
                    print("⚠️ Modo offline (sem chave da API)")
            except Exception:
                print("⚠️ Modo offline")
        else:
            print("⚠️ Modo offline")
        
        # Solicita a pergunta e gera resposta.
        pergunta = input("🧑 Você: ")
        resposta = responder_com_ia(pergunta, modelo)
        print(f"🤖 Robô: {resposta}")
    
    # Display e LEDs
    elif opcao == '5':
        print("\n💡 DISPLAY E LEDS SIMULADOS")
        display = DisplayLCDSimulado()
        led = LedRGBSimulado()
        intensidade = medidor_som_simulado()
        print(f"🔊 Nível simulado: {intensidade:.0f} dB")
        display.alerta_sonoro(intensidade)
        led.alerta_som(intensidade)
    
    # Mapa do Inferno Acústico
    elif opcao == '6':
        gerar_mapa_barulho()
    
    # Modo Automático
    elif opcao == '7':
        modo_automatico()
    
    # Diagnóstico
    elif opcao == '8':
        diagnosticar_robo()
    
    # Gerar README
    elif opcao == '9':
        gerar_readme()
    
    # Sair
    elif opcao == '0':
        print("\n👋 Até a próxima, piá! Não esquece: acessibilidade é coisa séria!")
        print(" (e se ouvir uma fofoca, já sabe... conta pro robô!)")
        return False  # Retorna False para sair do loop.
    
    # Opção inválida
    else:
        print("\n❌ Opção inválida! Tente novamente.")
    
    return True  # Retorna True para continuar o loop.

# ============================================================
# BLOCO 15: MENSAGEM DE AVALIAÇÃO FINAL
# ============================================================

def mensagem_avaliacao_final():
    """
    Exibe uma mensagem para autoavaliação dos alunos.
    Perguntas para reflexão sobre o projeto e aprendizado.
    """
    
    print("\n" + "="*60)
    print("📝 AUTOAVALIAÇÃO - PROJETO ROBÔ FOFOQUEIRO")
    print("="*60)
    print("Responda para você mesmo(a):")
    print()
    print("1. Consegui integrar todos os módulos em um único programa?")
    print("2. O menu funciona e chama cada funcionalidade corretamente?")
    print("3. O modo automático executa o ciclo completo sem erros?")
    print("4. Eu entendo como cada módulo (som, fala, visão, IA, dados) funciona?")
    print("5. Consigo explicar para um colega como o robô foi construído?")
    print("6. O que eu aprendi de mais legal neste projeto?")
    print("7. O que eu melhoraria se fosse fazer o Robô Fofoqueiro 2.0?")
    print("="*60)
    print("💬 Registre suas respostas no diário de bordo da turma!")
    print("🎉 Parabéns por concluir o Robô Fofoqueiro da Acessibilidade!")

# ============================================================
# PONTO DE ENTRADA
# ============================================================

# Verifica se o script está sendo executado diretamente (não importado como módulo).
if __name__ == "__main__":
    # Garante que a pasta logs existe antes de começar.
    os.makedirs("logs", exist_ok=True)
    
    # Executa o menu em loop até o usuário escolher sair (opção 0).
    continuar = True
    while continuar:
        continuar = main()
        # Se não saiu, aguarda ENTER antes de mostrar o menu novamente.
        if continuar:
            input("\n👉 Pressione ENTER para voltar ao menu...")
    
    # Exibe a mensagem de autoavaliação ao final.
    mensagem_avaliacao_final()
    
    # Mensagem final de encerramento.
    print("\n🎉 Fim da Aula 8 - Robô Fofoqueiro VERSÃO COMPLETA!")
    print(" (Ele agora é oficialmente o robô mais fofoqueiro do Brasil!)")

Checklist de avaliação - Aluno

  • Menu funcional com todas as opções (0-9)?
  • Modo automático executando ciclo completo?
  • README do projeto gerado com sucesso?
  • Demonstração para a turma realizada?
  • Todos os módulos integrados funcionam?
  • Participou da autoavaliação e debate final?
Avaliação

  • Menu funcional com todas as opções
  • Modo automático executando ciclo completo
  • README do projeto gerado
  • Demonstração para a turma

Dica: "O trem agora é completo, vixi! Bora fofocar com responsa sobre acessibilidade!"

Plano de Aula - Docente

Título: "O Robô Fofoqueiro ganha vida: integrando todos os módulos"

Códigos BNCC: EM13CNT104, EM13MAT503 | RCP - Paraná: Programação - Projeto Integrador, Trabalho Colaborativo

Duração: 3 aulas (150 minutos)

Materiais: Notebook Colab, todos os códigos dos módulos prontos


Dicas de mediação
  • Abertura (10min): Revisar todos os módulos já construídos — "montar o quebra-cabeça"
  • Planejamento (20min): Em grupos, definir quem fica responsável por qual módulo na integração
  • Codificação (60min): Construir o programa principal com menu (opções 1-9) e modo automático
  • Teste integrado (40min): Executar o modo automático — simular barulho, fala, mão na câmera
  • Fechamento (20min): Cada grupo demonstra seu programa rodando. Gerar README do robô
👩‍🏫🧑‍🏫

Kit do Professor

Simulador Integrado - Menu do Robô Fofoqueiro

🧩🤖 "Menu do Robô Fofoqueiro"
Saída do Robô
🤖 Clique em um módulo para testar...
Nota: Este é um simulador visual do menu integrado. O código Python completo deve ser executado no Google Colab para todas as funcionalidades reais.