Fechamento do ano — Arduino e IoT — semana 15 do 3o trimestre
Semana 15 de 15· 3o trimestre · 05/09 a 10/12
Fechamento do ano
Encerramento, duvidas e a ponte para o que vem depois.
Aula 1 — Apresentacao dos projetos e feedback
Objetivos
final em quatro minutos, com a placa na bancada rodando o firmware entregue.
- Dar
elogio específicoa um projeto de colega, citando a decisão técnica e não a impressão. - Fazer
crítica construtivacom caminho: dizer o problema e dizer onde mexer. - Responder uma pergunta da turma em voz alta, e registrar a que ninguém soube responder.
- Ler em voz alta o que eu faria diferente, com o motivo em cada frase.
Material
- 1 ESP32 DevKit V1 por aluno, com o firmware do projeto final gravado e o cabo USB
- Projetor, com o monitor serial da placa de apresentação e o terminal do projeto lado a lado
- Folha por aluno com o roteiro de 4 minutos, o bloco de elogio e o bloco de pergunta
- Folha do professor com a lista de elogio, crítica e pergunta escrita antes de começar
- Cronômetro de parede, porque quatro minutos por aluno é o que segura o dia em 50
Conceitos
A apresentação é uma prova de entrega, e a placa é a prova
O projeto final do ano é a entrega de um sistema com as sete camadas que o sketch lista: hardware, firmware, rede, servidor, banco, entrega e o próprio projeto. O que muda na última semana não é o escopo — é o que a turma precisa demonstrar.
A placa está na bancada por um motivo técnico, e não por enfeite: o monitor serial com a VERSAO_FIRMWARE gravada é a prova viva de que o firmware do aluno ainda roda depois de entregue. Um repositório no ar prova que alguém escreveu o arquivo; a placa subindo prova que o arquivo compila, gravou e está executando diante da turma. Se a placa não subir, o aluno descobre isso na apresentação — que é exatamente onde a informação é útil.
Os quatro minutos por aluno não são generousidade. Com seis alunos e cinquenta minutos, sobram vinte e seis minutos para discussão, e a discussão é a parte que transforma apresentação em feedback. O professor cronometra em voz alta, e o aluno que passou do tempo sabe onde cortar no ensaio de hoje à noite.
Elogio específico e crítica com caminho
O que distingue esta aula das outras trinta é que o feedback aqui é o conteúdo, e não um extra. A regra do sketch tem três partes, e a ordem delas é o que evita que a crítica soe como ataque:
| Parte | O que é | O que não é |
|---|---|---|
| elogio específico | "a consulta do histórico tem índice e página" | "bom trabalho" |
| crítica construtiva | o problema e o caminho | só o problema |
| uma pergunta que fica | "e se a consulta estourar o tempo?" | um veredito sobre o projeto |
"Bom trabalho" não é elogio, e a razão é mecânica: não diz o que foi bom e não muda o comportamento de ninguém. Um elogio que não muda comportamento é elogio nenhum com palavras a mais. O elogio útil aponta uma decisão e explica por que ela é boa — a chave de idempência que evitou o alerta duplo, o README com o passo de instalação que funciona, o health check que não consulta o banco.
A crítica construtiva é a parte mais difícil para quem apresenta e a mais fácil para quem avalia. Crítica sem caminho é só decoração: "faltou teste" sem dizer qual teste e sem dizer onde. O caminho é o que faz a crítica ser útil — e é por isso que o professor escreve na lousa a frase inteira, não a metade ruim.
A pergunta da turma é o que o aluno leva para casa
O feedback que permanece é a pergunta da turma, não o elogio. A pergunta é a única parte da apresentação que o aluno ainda não sabe responder, e é a única que muda o comportamento dele.
O sketch separa as perguntas respondidas das que não foram. Uma das três perguntas fica com respondida: falso, e isso é proposital: a pergunta sem resposta não é falta do aluno, é a que ele vai descobrir em casa com o código na mão. O professor anota na lousa e cobra na próxima aula, se a turma voltar. Responder pergunta é a habilidade que fecha o ano, e ela é a oitava do inventário de ontem, a que ficou sem consolidada: ela só se prova aqui, em voz alta, para alguém que não conhece o código.
A cena que o professor provoca quando ninguém sabe responder é a que vale: alguém da turma precisa ensinar o outro, e é isso que a apresentação cobra de todo mundo. Ensinar exige ordenar a ideia para caber em duas frases, e a ordem das frases revela o que a pessoa realmente entendeu. Quem consegue explicar em voz alta consolidou; quem lê o código e gagueja, ainda não.
E é essa a resposta à pergunta que a lousa faz no começo da aula: demonstrar o projeto, ou mostrar o projeto. A diferença é de foco: demonstrar é rodar o sistema diante da turma e deixar que ela tire a conclusão; mostrar é apontar a decisão e dizer por que ela ficou daquela maneira. O aluno que apenas demonstra com a placa ligada passa a impressão de que o projeto funciona; o aluno que mostra diz qual parte é difícil e por que ela ficou do jeito que ficou — e é essa frase que faz a turma aprender com um projeto que não é o dele.
E é por isso que a apresentação é do projeto da turma inteiro, e não só do aluno que está falando. Cada aluno mostra o projeto dele, mas o que a turma precisa ver de todos é a leitura de conjunto: seis sistemas que compartilham as mesmas camadas, apontando para a lista que a placa imprimiu no fim da sessão. O professor anota na lousa, ao lado do nome de cada aluno, três palavras: o que a decisão foi, por que foi boa, e a pergunta que ficou. São três palavras porque é o que cabe numa folha e é o que o aluno vai consultar em dezembro quando lembrar do ano.
O que eu faria diferente: a pergunta mais difícil do curso
"O que eu faria diferente" é a pergunta mais difícil do curso, e é a última porque ela é a única que o aluno não pode responder lendo o material. Ela tem três partes e o professor cobra as três:
- o que eu trocaria no meu projeto — com nome, não com adjetivo
- o que eu aprendi com o projeto de vocês — algo que o projeto dos outros ensinou
- o que eu levaria para o próximo ano — uma mudança concreta no curso, com o motivo
O que torna a pergunta útil não é a resposta, é o formato. "Faria diferente" sem o motivo é o mesmo "faria diferente" com mais palavras: só muda a superfície. Com o motivo, a frase vira decisão de projeto, e decisão de projeto é o que o professor consegue ler no painel de amanhã e reconhecer.
E há um efeito colateral que o professor explica em voz alta: responder essa pergunta em público ensina a turma que o professor também já entregou projeto com defeito. Ninguém aprende a pedir crítica num curso em que o professor nunca admite uma.
Atividade
Montagem: botao com pull-up no pino 0 para avançar de aluno, jumper de saída no pino 2 para o LED de status, ground no GND. A placa fica com o firmware do projeto final do aluno gravado antes da aula começar; o sketch da resolução é o roteiro da sessão, e o botao avança o LED a cada apresentação.
- Grave o sketch da resolução e rode no serial. Anote a versão do firmware que a placa imprimiu e compare com a versão do seu projeto final. As duas batem?
- Escreva o roteiro da sua apresentação em quatro minutos: o que você mostra, em que ordem, e o que você mostra se sobrar tempo. Ensaiar com cronômetro, não a olho.
- Apresente. Enquanto fala, aponte a placa na tela pelo menos uma vez, e diga a versão do firmware rodando. Diga de onde nasce o dado (sensor ou painel) e onde ele termina (banco ou tela).
- Ao terminar, escreva o
elogio específicodo projeto de um colega: cite a decisão técnica dele e explique por que ela é boa. Releia e confira que não tem "bom trabalho" em nenhum ponto. - Ao terminar, escreva a
crítica construtivadesse mesmo projeto: o problema e o caminho, em duas frases. Se você só escreveu o problema, reescreva com o caminho. - Escreva a pergunta que você levaria para esse projeto e a resposta que você daria. Releia a resposta em voz alta, como se o colega estivesse perguntando. Se você gaguejar, a resposta ainda não está pronta.
- Leia em voz alta a resposta de "o que eu faria diferente", nas três partes: o que trocaria, o que aprendeu com os projetos dos outros, o que levaria para o próximo ano.
- Marque no seu inventário de ontem a oitava habilidade — explicar para o outro — e diga em uma frase em qual das suas respostas você conseguiu sem olhar o material.
Nota: 12 pontos. Critério de fim: elogio específico com a decisão técnica nomeada, crítica com caminho escrito, e a oitava habilidade do inventário marcada com o exemplo que a prova.
Resolucao
// Aula 1 do dia 15: apresentacao dos projetos e feedback. // // A placa e a mesa de som da apresentacao. Enquanto cada aluno mostra o // projeto, a placa roda o roteiro da sessao e imprime o que o professor // anotou na lousa: o que foi demonstrado, o elogio especifico e a pergunta // que a turma fez. // // Por que a placa faz parte de uma apresentacao: e o unico jeito de o // aluno mostrar que o firmware DELE continua rodando depois de entregar. O // monitor serial com a versao 2.0.0 e a prova viva de que a entrega nao foi // so um arquivo. // // A regra de feedback que o professor escreve na lousa e a aula inteira: // elogio especifico, critica construtiva, e uma pergunta que o aluno leva // para casa. "Bom trabalho" nao e elogio: nao diz o que foi bom e nao muda // o comportamento de ninguem. #include <Arduino.h> // Versao do firmware do aluno. O professor compara com a da lousa. #define VERSAO_FIRMWARE "2.0.0" #define ID_DISPOSITIVO "esp32-bancada-01" // Quantos alunos apresentam. A turma do trimestre tem este tamanho, e o // numero define o tempo: 4 minutos por aluno, com sobra para a duvida. const int TOTAL_DE_ALUNOS = 6; // Minutos por apresentacao. Com 6 alunos e 50 minutos, 4 minutos por aluno // deixa 26 minutos de discussao, que e onde a aula vale. const int MINUTOS_POR_APRESENTACAO = 4; // ------------------------------------------------------------------ pinos const int PIN_LED_STATUS = 2; const int PIN_BOTAO_PROXIMO = 0; // ------------------------------------------------------------------ tipos struct Aluno { const char* nome; const char* projeto; const char* oQueMostrou; const char* elogio; const char* perguntaDaTurma; const char* respostaDoAluno; bool respondeuTudo; }; struct BlocoDoDia { const char* quando; const char* oQue; int minutos; }; struct Pergunta { const char* deQuem; const char* oQue; const char* respostaEsperada; bool respondida; }; // ------------------------------------------------------------- montagem Aluno alunos[TOTAL_DE_ALUNOS]; int totalDeAlunos = 0; BlocoDoDia blocos[5]; int totalDeBlocos = 0; Pergunta perguntas[3]; int totalDePerguntas = 0; int perguntasRespondidas = 0; void montarAlunos() { // Os nomes sao de exemplo: o professor troca pela lista da turma. O que // importa e a estrutura do feedback, que e a mesma para todo mundo. alunos[0].nome = "aluno 1"; alunos[0].projeto = "estacao com login e historico"; alunos[0].oQueMostrou = "cadastro, sessao, painel com grafico"; alunos[0].elogio = "a consulta do historico tem indice e pagina"; alunos[0].perguntaDaTurma = "e se a consulta estourar o tempo?"; alunos[0].respostaDoAluno = "tem o tempo de resposta no log, e pagina de 20"; alunos[0].respondeuTudo = true; alunos[1].nome = "aluno 2"; alunos[1].projeto = "alerta de temperatura com fila"; alunos[1].oQueMostrou = "grafico historico e alerta em tempo real"; alunos[1].elogio = "a chave de idempotencia evitou o alerta duplo"; alunos[1].perguntaDaTurma = "e se o broker cair?"; alunos[1].respostaDoAluno = "a placa guarda a leitura e reenvia com a mesma chave"; alunos[1].respondeuTudo = true; alunos[2].nome = "aluno 3"; alunos[2].projeto = "portao e automacao com dois papeis"; alunos[2].oQueMostrou = "login, painel, migracao e teste"; alunos[2].elogio = "o README tem o passo de instalacao que funciona"; alunos[2].perguntaDaTurma = "quem da o papel de administrador?"; alunos[2].respostaDoAluno = "so quem ja e admin, checado no servidor"; alunos[2].respondeuTudo = true; alunos[3].nome = "aluno 4"; alunos[3].projeto = "monitor de energia com deep sleep"; alunos[3].oQueMostrou = "medicao de consumo e tempo de bateria"; alunos[3].elogio = "mediu antes de otimizar, e o numero esta no README"; alunos[3].perguntaDaTurma = "quanto dura a bateria de verdade?"; alunos[3].respostaDoAluno = "uns 30 dias no modo de sono profundo"; alunos[3].respondeuTudo = true; alunos[4].nome = "aluno 5"; alunos[4].projeto = "trilha de auditoria com log estruturado"; alunos[4].oQueMostrou = "busca por identificador e filtro no log"; alunos[4].elogio = "achou o erro de um dispositivo pelo id, em dois minutos"; alunos[4].perguntaDaTurma = "e se o id for do cliente e nao do dispositivo?"; alunos[4].respostaDoAluno = "o id propaga; o do dispositivo vai no cabecalho"; alunos[4].respondeuTudo = false; alunos[5].nome = "aluno 6"; alunos[5].projeto = "API documentada e deploy com health check"; alunos[5].oQueMostrou = "OpenAPI, container e health check"; alunos[5].elogio = "o health check nao consulta o banco, como deve ser"; alunos[5].perguntaDaTurma = "e se o health check ficar verde e o banco cair?"; alunos[5].respostaDoAluno = "a rota de dependencia responde separadamente"; alunos[5].respondeuTudo = true; totalDeAlunos = 6; } void montarBlocos() { blocos[0].quando = "0 a 6 min"; blocos[0].oQue = "abertura: o que a turma construiu em 30 aulas"; blocos[0].minutos = 6; blocos[1].quando = "6 a 30 min"; blocos[1].oQue = "as 6 apresentacoes, 4 minutos cada"; blocos[1].minutos = 24; blocos[2].quando = "30 a 38 min"; blocos[2].oQue = "as 3 perguntas da turma, uma por aluno sorteado"; blocos[2].minutos = 8; blocos[3].quando = "38 a 44 min"; blocos[3].oQue = "o que eu faria diferente, lido em voz alta"; blocos[3].minutos = 6; blocos[4].quando = "44 a 50 min"; blocos[4].oQue = "o professor le as anotacoes da placa, uma por uma"; blocos[4].minutos = 6; totalDeBlocos = 5; } void montarPerguntas() { perguntas[0].deQuem = "aluno 1"; perguntas[0].oQue = "qual camada do seu projeto demorou mais e por que"; perguntas[0].respostaEsperada = "o banco, porque a migracao foi feita depois da regra"; perguntas[0].respondida = true; perguntas[1].deQuem = "aluno 4"; perguntas[1].oQue = "qual numero voce mediu antes de escolher o deep sleep"; perguntas[1].respostaEsperada = "o consumo em modo acordada, em microamperes"; perguntas[1].respondida = true; perguntas[2].deQuem = "aluno 5"; perguntas[2].oQue = "o que faltou responder da sua pergunta da turma"; perguntas[2].respostaEsperada = "a propagacao do id no log, que ele vaia implementar"; perguntas[2].respondida = false; totalDePerguntas = 3; perguntasRespondidas = 2; } // ------------------------------------------------------------------ saida void imprimirRoteiro() { Serial.println("========================================"); Serial.println(" o roteiro da sessao"); Serial.println("========================================"); int soma = 0; for (int i = 0; i < totalDeBlocos; i++) { Serial.println(" " + String(blocos[i].quando) + " | " + String(blocos[i].minutos) + " min | " + String(blocos[i].oQue)); soma += blocos[i].minutos; } Serial.println(); Serial.println("soma: " + String(soma) + " min | por aluno: " + String(MINUTOS_POR_APRESENTACAO) + " min"); Serial.println(); } void imprimirAlunos() { Serial.println("========================================"); Serial.println(" quem apresenta o que"); Serial.println("========================================"); for (int i = 0; i < totalDeAlunos; i++) { Serial.println(); Serial.println(" " + String(alunos[i].nome) + " — " + String(alunos[i].projeto)); Serial.println(" mostrou: " + String(alunos[i].oQueMostrou)); Serial.println(" elogio: " + String(alunos[i].elogio)); Serial.println(" pergunta: " + String(alunos[i].perguntaDaTurma)); Serial.println(" resposta: " + String(alunos[i].respostaDoAluno)); } Serial.println(); } void imprimirRegraDoFeedback() { Serial.println("========================================"); Serial.println(" a regra do feedback, em tres partes"); Serial.println("========================================"); Serial.println(); Serial.println("1. ELOGIO ESPECIFICO"); Serial.println(" 'a consulta do historico tem indice e pagina'"); Serial.println(" 'bom trabalho' nao e elogio: nao diz o que foi bom e nao"); Serial.println(" muda o comportamento de ninguem. elogio generico e o mesmo"); Serial.println(" que elogio nenhum, so que com palavras a mais."); Serial.println(); Serial.println("2. CRITICA CONSTRUTIVA"); Serial.println(" 'o health check consulta o banco' + 'tire essa consulta e"); Serial.println(" faca a dependencia aparecer em outra rota'"); Serial.println(" critica sem caminho e so quedacao. o caminho e o que faz a"); Serial.println(" critica ser util."); Serial.println(); Serial.println("3. UMA PERGUNTA QUE FICA"); Serial.println(" 'e se a consulta estourar o tempo?'"); Serial.println(" pergunta e o que o aluno leva para casa. elogio e o que o"); Serial.println(" aluno ja sabe; pergunta e o que ele ainda nao sabe."); Serial.println(); Serial.println("a ordem importa: elogio especifico primeiro, para o elogio"); Serial.println("nao soar como consolo; depois a critica, que precisa de um"); Serial.println("elogio antes para nao soar como ataque; depois a pergunta."); Serial.println(); } void imprimirPerguntas() { Serial.println("========================================"); Serial.println(" as perguntas da turma"); Serial.println("========================================"); for (int i = 0; i < totalDePerguntas; i++) { Serial.println(); Serial.println(" " + String(perguntas[i].deQuem) + " pergunta: " + String(perguntas[i].oQue)); Serial.println(" resposta esperada: " + String(perguntas[i].respostaEsperada)); Serial.println(" respondida: " + String(perguntas[i].respondida ? "sim" : "NAO")); } Serial.println(); Serial.println("respondidas: " + String(perguntasRespondidas) + " de " + String(totalDePerguntas)); Serial.println(); Serial.println("a pergunta nao respondida nao e falta do aluno: e a que"); Serial.println("ele vai descobrir em casa, com o codigo na mao. o professor"); Serial.println("anota na lousa e cobra na proxima aula, se a turma voltar."); Serial.println(); } void imprimirOQueFariaDiferente() { Serial.println("========================================"); Serial.println(" o que eu faria diferente"); Serial.println("========================================"); Serial.println("o professor pede esta parte em voz alta, para a turma inteira."); Serial.println("serve para duas coisas: mostra que o professor tambem teve"); Serial.println("projeto com defeito, e mostra o formato de uma resposta util."); Serial.println(); Serial.println(" 1. o que eu trocaria no MEU projeto"); Serial.println(" 'eu comecaria pelo teste da regra, e nao pela migration'"); Serial.println(); Serial.println(" 2. o que eu aprendi com o projeto de voces"); Serial.println(" 'a duvida real de vcs foi de escopo, e nao de sintaxe'"); Serial.println(); Serial.println(" 3. o que eu levaria para o proximo ano"); Serial.println(" 'mais tempo em migration, que e onde a turma mais travou'"); Serial.println(); Serial.println("resposta em tres frases, com nome proprio e com o motivo."); Serial.println("'faria diferente' sem o motivo e so o 'faria diferente'"); Serial.println("com mais palavras."); Serial.println(); } // ---------------------------------------------------------------- setup void setup() { Serial.begin(115200); delay(300); pinMode(PIN_LED_STATUS, OUTPUT); pinMode(PIN_BOTAO_PROXIMO, INPUT_PULLUP); digitalWrite(PIN_LED_STATUS, HIGH); Serial.println(); Serial.println("========================================"); Serial.println(" apresentacao dos projetos — v" + String(VERSAO_FIRMWARE)); Serial.println("========================================"); Serial.println("dispositivo do aluno: " + String(ID_DISPOSITIVO)); Serial.println("cpu: " + String(getCpuFrequencyMhz()) + " MHz | heap: " + String(ESP.getFreeHeap()) + " bytes"); Serial.println("esta placa e a prova viva de que o firmware do aluno roda."); Serial.println(); montarAlunos(); montarBlocos(); montarPerguntas(); imprimirRoteiro(); imprimirAlunos(); imprimirRegraDoFeedback(); imprimirPerguntas(); imprimirOQueFariaDiferente(); Serial.println("========================================"); Serial.println(" anotacoes prontas para a lousa"); Serial.println("========================================"); Serial.println("alunos: " + String(totalDeAlunos) + " | perguntas respondidas: " + String(perguntasRespondidas) + "/" + String(totalDePerguntas)); Serial.println("o botao avanca o LED de apresentacao a apresentacao."); } void loop() { digitalWrite(PIN_LED_STATUS, !digitalRead(PIN_LED_STATUS)); static unsigned long ultimoToque = 0; if (digitalRead(PIN_BOTAO_PROXIMO) == LOW && millis() - ultimoToque > 1500) { ultimoToque = millis(); Serial.println("[apresentacao] proximo aluno | heap " + String(ESP.getFreeHeap()) + " B | perguntas " + String(perguntasRespondidas) + "/" + String(totalDePerguntas)); } Serial.println("[apresentacao] viva | v" + String(VERSAO_FIRMWARE) + " | heap " + String(ESP.getFreeHeap()) + " B | LED " + String(digitalRead(PIN_LED_STATUS) ? "aceso" : "apago") + " | alunos " + String(totalDeAlunos)); delay(6000); }
Por que assim e não de outro jeito. Uma aula de apresentação não teria sketch nenhum, e essa seria a escolha óbvia: a placa não é necessária para alguém falar por quatro minutos. Ela é necessária porque o monitor serial é o instrumento de aula, e o que esta aula precisa medir é se o firmware do aluno continua rodando depois da entrega. O sketch não é exemplo de sala: ele é a mesa de som da sessão, e o que ele imprime é o que o professor anotou na lousa.
A placa não simula nada: os seis alunos, os seis projetos, os elogios e as perguntas são a lista real da turma, e o professor troca os nomes. O que importa é a estrutura do feedback, que é a mesma para todo mundo — e é por isso que a placa pode ensaiar a apresentação de alguém que ainda não apresentou.
A struct Aluno tem seis campos, e o quinto e sexto são os que estruturam a aula: a pergunta que a turma fez e a resposta que o aluno deu. O campo respondeuTudo é o que separa o que já se provou do que ainda está em aberto, e é ele que alimenta a linha de resumo no fim do setup com 2/3 — o número que o professor lê em voz alta ao encerrar.
A montagem em três funções separadas (montarAlunos, montarBlocos, montarPerguntas) não é estilo: o setup fica legível de cima a baixo, e quem vai trocar os nomes da turma não precisa ler o resto do arquivo para achar a lista. É a mesma disciplina do dia 10 aula 1, e a razão é a mesma: quem troca dado de pessoa em pessoa acaba procurando dentro de uma função de duzentas linhas.
Os blocos do roteiro são somados e impressos, e a soma aparece na tela. O professor projecta essa linha e mostra que o dia fecha em cinquenta: seis minutos de abertura, vinte e quatro de apresentações, oito de perguntas, seis de reflexão e seis de leitura das anotações. A tabela do roteiro e o que a placa imprime são o mesmo número por dois caminhos independentes, e a conferência é o critério de fim da aula.
O loop alterna o LED a cada seis segundos e imprime a placa viva com versão e heap. O que segura o botão para o cronômetro é o millis() com guarda de mil e quinhentos milissegundos, e não um delay fixo: apertar o botão quatro vezes seguidas não gera quatro linhas duplicadas, e isso importa quando o botão é o avanço de uma apresentação para a outra.
O ESP.getFreeHeap() aparece em toda linha viva, e essa é a escolha que o professor explica: o número muda ao longo da sessão, e é a prova de que a placa está viva e de que o firmware do aluno não está vazando memória. O aluno que fez o projeto de alerta com fila precisa notar que o heap dele não cai de forma geral ao longo das apresentações; se cair, o String está acumulando.
Criterios de correcao
| Critério | Pontos |
|---|---|
| Versão do firmware anotada e comparada com a do projeto final, com a diferença explicada se houver | 1 ponto |
| Roteiro de 4 minutos escrito e ensaiado, com o que sobra se sobrar tempo | 2 pontos |
| Apresentação feita, com a placa apontada na tela e a versão dita | 2 pontos |
| Elogio específico de um colega, citando a decisão técnica e sem "bom trabalho" | 2 pontos |
| Crítica construtiva com problema e caminho, em duas frases | 2 pontos |
| Pergunta e resposta do projeto, lidas em voz alta como se fossem respondidas | 2 pontos |
| "O que eu faria diferente" nas três partes, com o motivo em cada | 1 ponto |
Erros comuns
| Erro | Como aparece | Correcao |
|---|---|---|
| "Bom trabalho" como elogio | o aluno escreve "gostei, estava muito bom" | "Isso não é elogio: não diz o que foi bom e não muda o comportamento de ninguém. Nomeie a decisão — 'a consulta tem índice e página' — e diga por que ela é boa." |
| Elogio que elogia a pessoa, não o trabalho | "você é muito dedicado" | "Elogio ao esforço não diz nada sobre o código. Aprova o critério é a decisão técnica que funciona, e essa é a única que o colega pode repetir no projeto dele." |
| Crítica só com o problema | "faltou teste no seu projeto" | "Crítica sem caminho é só decoração. Diga o problema e onde mexer: 'o alerta dispara duas vezes porque a chave de idempotência não está na tabela — usa a chave da leitura como chave única'." |
| Crítica que soa como ataque | "isso está errado, refaz" | "A ordem importa: elogio específico primeiro, para o elogio não soar como consolo; crítica depois, que precisa de elogio antes para não soar como ataque; pergunta por último." |
| "Não sei" como resposta completa | o aluno se cala depois de duas palavras | "'Não sei' sem o resto é abandono. Diga o que você acharia, o que não sabe e o que precisaria ler para responder. Resposta parcial com o caminho é resposta." |
| Apresentar pelo código, tela a tela | vinte minutos mostrando arquivo | "Quatro minutos é o ensaio de um produto. Mostre o que o sistema faz, mostre a decisão que importa, e cite o código como quem aponta para uma linha conhecida." |
| Não apontar a placa na tela | a apresentação não menciona a versão | "A placa subindo é a prova de que a entrega funciona. Diga a versão do firmware em voz alta — é o que separa 'entreguei um arquivo' de 'entreguei um sistema'." |
| Falar do projeto do colega e não do seu | o aluno apresenta o deploy do colega | "A apresentação é do seu projeto. Se você for apresentar o do colega como comparação, diga em uma linha por que comparou — comparação é argumento, não desvio." |
| Fechar sem dizer o que falta | o aluno termina e a turma fica sem saber o próximo passo | "Termine nomeando o que falta. Dizer 'está faltando a migração reversível' é o que permite o colega continuar depois da aula." |
| Elogio e crítica da mesma coisa | "está bom, mas faltou índice" | "Elogio e crítica precisam ser de coisas diferentes. Se o índice é o problema, o elogio é outra decisão — a paginação, o log com identificador, o teste da regra." |
| Fingir que não tem nada a critiquear | o aluno diz "não tenho nada a apontar" | "Todo projeto tem um 'daqui a pouco' ou um 'isso quebra quando'. Dizer qual é transforma a apresentação em conversa e é o que faz a turma aprender com o projeto do colega." |
| Ler o elogio da placa no modo automático | o aluno recita a struct sem entender | "A placa tem a anotação, você tem o motivo. Se você não sabe dizer por que aquele elogio é justo, o elogio não era seu — e o da placa era só exemplo." |
| Tremer a voz no bloco de pergunta | o aluno fica em silêncio e a turma espera | "Pergunta sem resposta ainda é a pergunta mais útil da apresentação. Diga que vai descobrir com o código na mão e passe para a turma: alguém da turma sabe responder?" |
Desafio extra
Pegue o projeto de um colega do seu grupo, com o consentimento dele, e escreva uma revisão de duas páginas com quatro partes: o que está funcionando e por quê, um defeito real com o caminho para corrigir, uma pergunta que você não soube responder, e uma sugestão de escopo para a próxima entrega. Depois devolva a ele e peça uma resposta escrita. Meça quanto tempo a revisão levou e quanto tempo ele levou para responder, e escreva uma frase sobre o que isso revela da diferença entre dar e receber crítica em trabalho de verdade.
>A resolucao, compilada
// Aula 1 do dia 15: apresentacao dos projetos e feedback. // // A placa e a mesa de som da apresentacao. Enquanto cada aluno mostra o // projeto, a placa roda o roteiro da sessao e imprime o que o professor // anotou na lousa: o que foi demonstrado, o elogio especifico e a pergunta // que a turma fez. // // Por que a placa faz parte de uma apresentacao: e o unico jeito de o // aluno mostrar que o firmware DELE continua rodando depois de entregar. O // monitor serial com a versao 2.0.0 e a prova viva de que a entrega nao foi // so um arquivo. // // A regra de feedback que o professor escreve na lousa e a aula inteira: // elogio especifico, critica construtiva, e uma pergunta que o aluno leva // para casa. "Bom trabalho" nao e elogio: nao diz o que foi bom e nao muda // o comportamento de ninguem. #include <Arduino.h> // Versao do firmware do aluno. O professor compara com a da lousa. #define VERSAO_FIRMWARE "2.0.0" #define ID_DISPOSITIVO "esp32-bancada-01" // Quantos alunos apresentam. A turma do trimestre tem este tamanho, e o // numero define o tempo: 4 minutos por aluno, com sobra para a duvida. const int TOTAL_DE_ALUNOS = 6; // Minutos por apresentacao. Com 6 alunos e 50 minutos, 4 minutos por aluno // deixa 26 minutos de discussao, que e onde a aula vale. const int MINUTOS_POR_APRESENTACAO = 4; // ------------------------------------------------------------------ pinos const int PIN_LED_STATUS = 2; const int PIN_BOTAO_PROXIMO = 0; // ------------------------------------------------------------------ tipos struct Aluno { const char* nome; const char* projeto; const char* oQueMostrou; const char* elogio; const char* perguntaDaTurma; const char* respostaDoAluno; bool respondeuTudo; }; struct BlocoDoDia { const char* quando; const char* oQue; int minutos; }; struct Pergunta { const char* deQuem; const char* oQue; const char* respostaEsperada; bool respondida; }; // ------------------------------------------------------------- montagem Aluno alunos[TOTAL_DE_ALUNOS]; int totalDeAlunos = 0; BlocoDoDia blocos[5]; int totalDeBlocos = 0; Pergunta perguntas[3]; int totalDePerguntas = 0; int perguntasRespondidas = 0; void montarAlunos() { // Os nomes sao de exemplo: o professor troca pela lista da turma. O que // importa e a estrutura do feedback, que e a mesma para todo mundo. alunos[0].nome = "aluno 1"; alunos[0].projeto = "estacao com login e historico"; alunos[0].oQueMostrou = "cadastro, sessao, painel com grafico"; alunos[0].elogio = "a consulta do historico tem indice e pagina"; alunos[0].perguntaDaTurma = "e se a consulta estourar o tempo?"; alunos[0].respostaDoAluno = "tem o tempo de resposta no log, e pagina de 20"; alunos[0].respondeuTudo = true; alunos[1].nome = "aluno 2"; alunos[1].projeto = "alerta de temperatura com fila"; alunos[1].oQueMostrou = "grafico historico e alerta em tempo real"; alunos[1].elogio = "a chave de idempotencia evitou o alerta duplo"; alunos[1].perguntaDaTurma = "e se o broker cair?"; alunos[1].respostaDoAluno = "a placa guarda a leitura e reenvia com a mesma chave"; alunos[1].respondeuTudo = true; alunos[2].nome = "aluno 3"; alunos[2].projeto = "portao e automacao com dois papeis"; alunos[2].oQueMostrou = "login, painel, migracao e teste"; alunos[2].elogio = "o README tem o passo de instalacao que funciona"; alunos[2].perguntaDaTurma = "quem da o papel de administrador?"; alunos[2].respostaDoAluno = "so quem ja e admin, checado no servidor"; alunos[2].respondeuTudo = true; alunos[3].nome = "aluno 4"; alunos[3].projeto = "monitor de energia com deep sleep"; alunos[3].oQueMostrou = "medicao de consumo e tempo de bateria"; alunos[3].elogio = "mediu antes de otimizar, e o numero esta no README"; alunos[3].perguntaDaTurma = "quanto dura a bateria de verdade?"; alunos[3].respostaDoAluno = "uns 30 dias no modo de sono profundo"; alunos[3].respondeuTudo = true; alunos[4].nome = "aluno 5"; alunos[4].projeto = "trilha de auditoria com log estruturado"; alunos[4].oQueMostrou = "busca por identificador e filtro no log"; alunos[4].elogio = "achou o erro de um dispositivo pelo id, em dois minutos"; alunos[4].perguntaDaTurma = "e se o id for do cliente e nao do dispositivo?"; alunos[4].respostaDoAluno = "o id propaga; o do dispositivo vai no cabecalho"; alunos[4].respondeuTudo = false; alunos[5].nome = "aluno 6"; alunos[5].projeto = "API documentada e deploy com health check"; alunos[5].oQueMostrou = "OpenAPI, container e health check"; alunos[5].elogio = "o health check nao consulta o banco, como deve ser"; alunos[5].perguntaDaTurma = "e se o health check ficar verde e o banco cair?"; alunos[5].respostaDoAluno = "a rota de dependencia responde separadamente"; alunos[5].respondeuTudo = true; totalDeAlunos = 6; } void montarBlocos() { blocos[0].quando = "0 a 6 min"; blocos[0].oQue = "abertura: o que a turma construiu em 30 aulas"; blocos[0].minutos = 6; blocos[1].quando = "6 a 30 min"; blocos[1].oQue = "as 6 apresentacoes, 4 minutos cada"; blocos[1].minutos = 24; blocos[2].quando = "30 a 38 min"; blocos[2].oQue = "as 3 perguntas da turma, uma por aluno sorteado"; blocos[2].minutos = 8; blocos[3].quando = "38 a 44 min"; blocos[3].oQue = "o que eu faria diferente, lido em voz alta"; blocos[3].minutos = 6; blocos[4].quando = "44 a 50 min"; blocos[4].oQue = "o professor le as anotacoes da placa, uma por uma"; blocos[4].minutos = 6; totalDeBlocos = 5; } void montarPerguntas() { perguntas[0].deQuem = "aluno 1"; perguntas[0].oQue = "qual camada do seu projeto demorou mais e por que"; perguntas[0].respostaEsperada = "o banco, porque a migracao foi feita depois da regra"; perguntas[0].respondida = true; perguntas[1].deQuem = "aluno 4"; perguntas[1].oQue = "qual numero voce mediu antes de escolher o deep sleep"; perguntas[1].respostaEsperada = "o consumo em modo acordada, em microamperes"; perguntas[1].respondida = true; perguntas[2].deQuem = "aluno 5"; perguntas[2].oQue = "o que faltou responder da sua pergunta da turma"; perguntas[2].respostaEsperada = "a propagacao do id no log, que ele vaia implementar"; perguntas[2].respondida = false; totalDePerguntas = 3; perguntasRespondidas = 2; } // ------------------------------------------------------------------ saida void imprimirRoteiro() { Serial.println("========================================"); Serial.println(" o roteiro da sessao"); Serial.println("========================================"); int soma = 0; for (int i = 0; i < totalDeBlocos; i++) { Serial.println(" " + String(blocos[i].quando) + " | " + String(blocos[i].minutos) + " min | " + String(blocos[i].oQue)); soma += blocos[i].minutos; } Serial.println(); Serial.println("soma: " + String(soma) + " min | por aluno: " + String(MINUTOS_POR_APRESENTACAO) + " min"); Serial.println(); } void imprimirAlunos() { Serial.println("========================================"); Serial.println(" quem apresenta o que"); Serial.println("========================================"); for (int i = 0; i < totalDeAlunos; i++) { Serial.println(); Serial.println(" " + String(alunos[i].nome) + " — " + String(alunos[i].projeto)); Serial.println(" mostrou: " + String(alunos[i].oQueMostrou)); Serial.println(" elogio: " + String(alunos[i].elogio)); Serial.println(" pergunta: " + String(alunos[i].perguntaDaTurma)); Serial.println(" resposta: " + String(alunos[i].respostaDoAluno)); } Serial.println(); } void imprimirRegraDoFeedback() { Serial.println("========================================"); Serial.println(" a regra do feedback, em tres partes"); Serial.println("========================================"); Serial.println(); Serial.println("1. ELOGIO ESPECIFICO"); Serial.println(" 'a consulta do historico tem indice e pagina'"); Serial.println(" 'bom trabalho' nao e elogio: nao diz o que foi bom e nao"); Serial.println(" muda o comportamento de ninguem. elogio generico e o mesmo"); Serial.println(" que elogio nenhum, so que com palavras a mais."); Serial.println(); Serial.println("2. CRITICA CONSTRUTIVA"); Serial.println(" 'o health check consulta o banco' + 'tire essa consulta e"); Serial.println(" faca a dependencia aparecer em outra rota'"); Serial.println(" critica sem caminho e so quedacao. o caminho e o que faz a"); Serial.println(" critica ser util."); Serial.println(); Serial.println("3. UMA PERGUNTA QUE FICA"); Serial.println(" 'e se a consulta estourar o tempo?'"); Serial.println(" pergunta e o que o aluno leva para casa. elogio e o que o"); Serial.println(" aluno ja sabe; pergunta e o que ele ainda nao sabe."); Serial.println(); Serial.println("a ordem importa: elogio especifico primeiro, para o elogio"); Serial.println("nao soar como consolo; depois a critica, que precisa de um"); Serial.println("elogio antes para nao soar como ataque; depois a pergunta."); Serial.println(); } void imprimirPerguntas() { Serial.println("========================================"); Serial.println(" as perguntas da turma"); Serial.println("========================================"); for (int i = 0; i < totalDePerguntas; i++) { Serial.println(); Serial.println(" " + String(perguntas[i].deQuem) + " pergunta: " + String(perguntas[i].oQue)); Serial.println(" resposta esperada: " + String(perguntas[i].respostaEsperada)); Serial.println(" respondida: " + String(perguntas[i].respondida ? "sim" : "NAO")); } Serial.println(); Serial.println("respondidas: " + String(perguntasRespondidas) + " de " + String(totalDePerguntas)); Serial.println(); Serial.println("a pergunta nao respondida nao e falta do aluno: e a que"); Serial.println("ele vai descobrir em casa, com o codigo na mao. o professor"); Serial.println("anota na lousa e cobra na proxima aula, se a turma voltar."); Serial.println(); } void imprimirOQueFariaDiferente() { Serial.println("========================================"); Serial.println(" o que eu faria diferente"); Serial.println("========================================"); Serial.println("o professor pede esta parte em voz alta, para a turma inteira."); Serial.println("serve para duas coisas: mostra que o professor tambem teve"); Serial.println("projeto com defeito, e mostra o formato de uma resposta util."); Serial.println(); Serial.println(" 1. o que eu trocaria no MEU projeto"); Serial.println(" 'eu comecaria pelo teste da regra, e nao pela migration'"); Serial.println(); Serial.println(" 2. o que eu aprendi com o projeto de voces"); Serial.println(" 'a duvida real de vcs foi de escopo, e nao de sintaxe'"); Serial.println(); Serial.println(" 3. o que eu levaria para o proximo ano"); Serial.println(" 'mais tempo em migration, que e onde a turma mais travou'"); Serial.println(); Serial.println("resposta em tres frases, com nome proprio e com o motivo."); Serial.println("'faria diferente' sem o motivo e so o 'faria diferente'"); Serial.println("com mais palavras."); Serial.println(); } // ---------------------------------------------------------------- setup void setup() { Serial.begin(115200); delay(300); pinMode(PIN_LED_STATUS, OUTPUT); pinMode(PIN_BOTAO_PROXIMO, INPUT_PULLUP); digitalWrite(PIN_LED_STATUS, HIGH); Serial.println(); Serial.println("========================================"); Serial.println(" apresentacao dos projetos — v" + String(VERSAO_FIRMWARE)); Serial.println("========================================"); Serial.println("dispositivo do aluno: " + String(ID_DISPOSITIVO)); Serial.println("cpu: " + String(getCpuFrequencyMhz()) + " MHz | heap: " + String(ESP.getFreeHeap()) + " bytes"); Serial.println("esta placa e a prova viva de que o firmware do aluno roda."); Serial.println(); montarAlunos(); montarBlocos(); montarPerguntas(); imprimirRoteiro(); imprimirAlunos(); imprimirRegraDoFeedback(); imprimirPerguntas(); imprimirOQueFariaDiferente(); Serial.println("========================================"); Serial.println(" anotacoes prontas para a lousa"); Serial.println("========================================"); Serial.println("alunos: " + String(totalDeAlunos) + " | perguntas respondidas: " + String(perguntasRespondidas) + "/" + String(totalDePerguntas)); Serial.println("o botao avanca o LED de apresentacao a apresentacao."); } void loop() { digitalWrite(PIN_LED_STATUS, !digitalRead(PIN_LED_STATUS)); static unsigned long ultimoToque = 0; if (digitalRead(PIN_BOTAO_PROXIMO) == LOW && millis() - ultimoToque > 1500) { ultimoToque = millis(); Serial.println("[apresentacao] proximo aluno | heap " + String(ESP.getFreeHeap()) + " B | perguntas " + String(perguntasRespondidas) + "/" + String(totalDePerguntas)); } Serial.println("[apresentacao] viva | v" + String(VERSAO_FIRMWARE) + " | heap " + String(ESP.getFreeHeap()) + " B | LED " + String(digitalRead(PIN_LED_STATUS) ? "aceso" : "apago") + " | alunos " + String(totalDeAlunos)); delay(6000); }
Sem saída de compilação gravada. Rode python3 validar.py -t 3 dia15 aula1.
Aula 2 — Encerramento do ano e o passo depois
Objetivos
letivo` entregou, camada por camada, sem olhar para o caderno.
- Conferir no inventário de material quais peças quebraram e quais faltaram comprar, e separar as duas coisas.
- Ordenar as sugestões de mudança para o próximo ano por prioridade, com o motivo junto.
- Calcular o custo de abrir uma vaga na turma, e explicar por que esse número não é o custo do material.
- Escrever a
próxima etapacom prazo, e dizer o que acontinuidade do cursosignifica para quem não volta.
Material
- 1 ESP32 DevKit V1 por aluno, com o cabo USB, na bancada para a conferência final
- 1 botao com pull-up no pino 0, que imprime a placa de encerramento com a data da gravação
- O inventário do laboratório escrito à mão, com a coluna de situação de cada peça
- Folha por aluno com as quatro sugestões de mudança, para assinar no fim da aula
- Monitor serial a 115200, aberto na tela do projetor durante a leitura das anotações
Conceitos
O que fecha: as sete camadas e a pergunta que separa quem fez o curso
O encerramento de um curso é a aula em que o professor faz a única coisa que a sequência inteira preparou: somar. E a soma não é a lista de conteúdos — é a pergunta que atravessa todas as camadas.
O sketch imprime sete camadas com a marca de entregue, e sete de sete é o número que o professor projeta:
| Camada | O que entregou |
|---|---|
| hardware | sensor, display e saída digital, com fiação certa |
| firmware | C++ que compila, com tempo limite e log |
| rede | WiFi que reconecta, HTTP com código de status |
| servidor | Node com login, sessão, permissão e log com identificador |
| banco | MySQL com repository, migração e paginação |
| entrega | teste, segurança, deploy e README que roda |
| projeto final | sistema completo, apresentado e revisado |
A pergunta que o professor faz ao encerrar é uma só, e é a que divide a turma: onde o dado começa e onde ele termina. Quem responde "no DHT11 e termina na linha do MySQL, passando pelo painel" fez o curso. Quem responde "no ESP32" parou na metade, e essa metade é a que serve para a bancada e não para produto.
O ciclo que fecha é o ano letivo: treze dias no primeiro trimestre, dezesseis no segundo e quinze no terceiro, com duas aulas por semana. É um número de calendário, e ele importa por um motivo pequeno e concreto: ele é a medida do que cabe em um curso com professor e com bancada. Quem planeja o próximo curso precisa desse número como limite, não como estimativa.
O inventário: o que quebrou é dado, não azar
A parte que o professor diz que é a lista mais útil do ano não vai para o portal do aluno: é o inventário de material. Peça por peça, com a situação real e a marca de precisa comprar ou não.
O inventário do laboratório é o que separa material que faltou de kit que quebrou, e a distinção é a primeira coisa que o professor ensina antes de ler a lista. As duas frases da atividade do ano aparecem separadas na placa, e é essa separação que muda o que a coordenação compra:
| Situação | Frase da placa | O que ela significa |
|---|---|---|
kit que quebrou | "funcionando, 2 com o cabo frouxo" | a peça estava no armário e deixou de funcionar |
material que faltou | "faltaram 3 kits, repuser do armário" | nunca houve peça suficiente para a turma |
O que comprar sai dessas duas frases juntas, e por isso a lista da placa tem uma coluna só — precisaComprar — mas as situações são narradas de maneiras diferentes. O professor aponta essa diferença e pede que a turma não misture: dizer que "faltou DHT11" quando o que houve foram dois DHT11 que falharam muda a decisão de compra no mesmo orçamento.
O que a placa imprime tem seis itens, e o professor comenta os três que mudam a decisão:
| Item | Situação | Comprar |
|---|---|---|
ESP32 DevKit V1 | 12, funcionando, 2 com o cabo frouxo | sim |
cabo USB | 12, funcionando, 1 na troca | sim |
DHT11 | 12, 2 falhando, leitura travada em 0 | sim |
display OLED com I2C | 12, funcionando, 1 com cabo solto no VCC | não |
| jumpers | faltaram 3 kits, repuser do armário | sim |
| fonte de bancada | 1, queimou em março, falta reposição | sim |
O display está na lista com não precisa comprar, e essa linha é o exemplo que o professor usa: uma peça com defeito não é automaticamente peça para comprar. O cabo solto se resolve com o cabo, e o cabo está na lista. Quem compra peça porque viu uma com defeito gasta dinheiro dobrado.
E o item que mais custa não é o mais caro: é a fonte de bancada que queimou em março. Uma peça quebrada é uma placa fora de uso; a fonte é a bancada inteira fora de uso, e a próxima turma não começa sem ela. Por isso a ordem da compra é o que o professor leva para a coordenação, e não a lista.
O custo real de abrir uma vaga, e a mudança que vem depois
A placa imprime o custo do kit por aluno e a conta da turma, e o professor usa os dois números para dizer a mesma coisa de duas maneiras. O CUSTO_DO_KIT_POR_ALUNO de R$ 145,00 é o que a escola gasta em material por aluno. A conta da turma de doze é esse número multiplicado.
E o número que importa é outro, e é o que o professor dita duas vezes para que ninguém anote o primeiro: o custo real de uma vaga aberta é o de uma placa que quebrou na semana 3 e o que a aula não virou naquele dia. Uma placa que parou custou o material e custou a aula — e a aula repetida custa a turma inteira de novo. Material é a parte mensurável; aula perdida é a parte que não aparece em nota fiscal e é a que dói.
Por isso a sugestão de comprar um kit de reserva vem antes de comprar sensor novo: o sensor custa vinte reais e a placa reserva evita a repetição de uma aula. O critério é o custo de indisponibilidade, e ele é sempre maior que o preço da peça.
E é do custo de uma aula perdida que saem as melhorias para o próximo ano, que são quatro, com o professor projetando a coluna de prioridade com a mesma força com que projeta as notas:
| Prioridade | Mudança | Por quê |
|---|---|---|
| 1 | aumentar a aula de migração para duas | a turma mais travou em migration, não em sintaxe |
| 1 | comprar um kit de reserva antes de comprar sensor | placa que quebra para a aula inteira, sensor custa vinte reais |
| 2 | guardar os 3 kits de jumper no armário com etiqueta | faltou material três vezes no mesmo trimestre |
| 2 | começar o segundo trimestre com revisão de 1 aula | quem entrou depois da semana 2 não acompanhou a camada de rede |
A separação é o que dá valor à lista: prioridade 1 muda o ano, e prioridade 2 só tira trabalho. Uma lista de dez itens sem prioridade é reclamação; uma lista de quatro com duas marcadas é plano.
E o porquê é o que transforma sugestão de melhoria em dado. "Aumentar a aula de migração" é opinião; "a turma mais travou em migration, não em sintaxe" é observação, e observação é o que o professor consegue defender na coordenação sem ter que convencer ninguém de nada. A pergunta que o professor faz à turma antes de ler a lista em voz alta é: em que assunto vocês mais travaram? E a resposta que a turma dá é, quase sempre, a mesma que a lista já tem.
O encerramento: o ciclo fecha, a continuidade não
O encerramento do ano letivo tem duas metades, e confundi-las é o erro mais comum de quem escreve a própria despedida.
A primeira metade é o ciclo que fecha: as aulas dadas, as camadas entregues, o inventário conferido, as sugestões anotadas. Nada disso volta, e é exatamente por isso que precisa ser escrito — a memória de um curso é pior que a memória de um banco, e o banco tem índice.
A segunda metade é a próxima etapa, e ela é do aluno, não da escola. A continuidade do curso é o que continua depois da última aula: o projeto pessoal publicado, a sequência de três passos do plano de noventa dias, e a próxima turma que recebe o mesmo kit com as correções desta lista aplicadas. Quem tem as três coisas com data continua; quem tem "quando der" não começa nada, e o professor diz isso olhando para a turma e não para a lousa.
O que fica na placa é a última versão gravada, com a data e a hora da gravação, e é o registro do ano: quando o laboratório for aberto de novo, o monitor serial mostra qual era a última entrega. Um obrigado verdadeiro não precisa de placa nenhuma — e o professor diz o dele em voz alta, sem ler da tela, porque é a única coisa da aula que não é conteúdo.
Atividade
Montagem: botao com pull-up no pino 0 para imprimir a placa de encerramento, jumper de saída no pino 2 para o LED de status, ground no GND. A placa fica na bancada durante a leitura das listas, e a última versão gravada é a que fica no arquivo do laboratório.
- Grave o sketch da resolução e rode no serial. Anote os três números da primeira seção: trimestres, dias letivos e aulas. Eles batem com o calendário que a escola imprimiu? Multiplique os dias pelas duas aulas e confira o total: o número que a placa imprime é o mesmo que a sua conta dá?
- Na lista das sete camadas, conte quantas têm a marca de entregue. Qual camada, se alguma, você não acha que ficou? Escreva o que falta para ela ficar.
- Pegue o inventário escrito à mão e compare com o que a placa imprimiu. Bate? Marque a diferença, se houver — e diga se o erro foi de lista ou de memória.
- Escreva o custo de abrir uma vaga nova, em duas partes: o que é material e o que é aula perdida. Qual das duas partes é maior, e por que essa não aparece na nota fiscal?
- Ordene as quatro sugestões com as suas próprias palavras. As duas de prioridade um mudam o ano ou só tiram trabalho? Justifique a ordem em duas frases.
- Escreva a
próxima etapacom prazo: uma data, uma coisa e um número de horas. Anote a data. Se a sua data é "quando der", escreva isso e diga o que precisa mudar para ela virar uma data. - Em uma frase, diga o que a
próxima turmarecebe de você e de mim, além do material. Guarde essa frase: ela é a última do ano.
Nota: 12 pontos. Critério de fim: o inventário conferido contra a lista da placa, e a próxima etapa escrita com data e horas.
Resolucao
// Aula 2 do dia 15: encerramento do ano e o passo depois. // // Ultima aula do ano. Nao ha codigo novo para aprender e nao ha prova: ha // um ciclo fechando e duas perguntas que so o titular pode responder. // // A placa faz o fechamento contábil do ano. Ela conta o que o ciclo entregou // (as 30 aulas, os 15 dias, as 3 trilhas), e ela recolhe o que faltou — o // inventário de material, que e a parte que o professor leva para a // coordinate e que costuma ser ignorada. // // Os dois blocos que o professor precisa ler em voz alta: // // 1. O QUE FECHOU: o ciclo que fecha, o que a turma entregou, e o numero // que responde "valeu a pena". // 2. O QUE FALTOU: o material que quebrou, o que faltou comprar, e as // tres sugestoes de mudanca que mudam o ano que vem. // // A segunda lista e a que o professor vai agradecer. E a unica aula do ano // em que o aluno escreve no codigo, e a escrita e sobre a escola, nao sobre // o firmware. #include <Arduino.h> // Versao do firmware. Ultima gravacao do ano: e o que fica na placa quando // a turma toda apagada e o laboratorio fecha. #define VERSAO_FIRMWARE "2.0.0" #define ID_DISPOSITIVO "esp32-bancada-01" // ------------------------------------------------------------------ pinos const int PIN_LED_STATUS = 2; const int PIN_BOTAO_FECHAMENTO = 0; // -------------------------------------------------------------- configuracao // Numero de aulas do ano. Soma dos tres trimestres do eixo: 13 + 16 + 15 // dias, com 2 aulas por dia. O numero e medido no eixo, nao escolhido. const int DIAS_DO_ANO = 44; const int TOTAL_DE_AULAS_DO_ANO = 88; const int TRIMESTRES = 3; // Custo do material, em reais. Valor de referencia do kit da bancada, e o // que o professor usa para calcular quanto custa matricular um aluno novo. const float CUSTO_DO_KIT_POR_ALUNO = 145.00; // ------------------------------------------------------------------ tipos struct OQueFechou { const char* item; const char* como; bool entregue; }; struct Material { const char* item; const char* situacao; int quantidade; bool precisaComprar; }; struct Sugestao { const char* mudanca; const char* porque; int prioridade; }; // --------------------------------------------------------------- montagem OQueFechou fechamento[7]; int totalDoFechamento = 0; Material materiais[6]; int totalDeMateriais = 0; Sugestao sugestoes[4]; int totalDeSugestoes = 0; void montarFechamento() { fechamento[0].item = "a camada de hardware"; fechamento[0].como = "sensor, display e saida digital, com fiaçao certa"; fechamento[0].entregue = true; fechamento[1].item = "a camada de firmware"; fechamento[1].como = "C++ que compila, com tempo limite e log"; fechamento[1].entregue = true; fechamento[2].item = "a camada de rede"; fechamento[2].como = "WiFi que reconecta, HTTP com codigo de status"; fechamento[2].entregue = true; fechamento[3].item = "a camada de servidor"; fechamento[3].como = "Node com login, sessao, permissao e log com id"; fechamento[3].entregue = true; fechamento[4].item = "a camada de banco"; fechamento[4].como = "MySQL com repository, migracao e paginacao"; fechamento[4].entregue = true; fechamento[5].item = "a camada de entrega"; fechamento[5].como = "teste, seguranca, deploy e README que roda"; fechamento[5].entregue = true; fechamento[6].item = "o projeto final"; fechamento[6].como = "sistema completo, apresentado e revisado"; fechamento[6].entregue = true; totalDoFechamento = 7; } void montarMateriais() { materiais[0].item = "ESP32 DevKit V1"; materiais[0].situacao = "funcionando, 2 com o cabo frouxo"; materiais[0].quantidade = 12; materiais[0].precisaComprar = true; materiais[1].item = "cabo USB"; materiais[1].situacao = "funcionando, 1 na troca"; materiais[1].quantidade = 12; materiais[1].precisaComprar = true; materiais[2].item = "DHT11"; materiais[2].situacao = "2 falhando, leitura travada em 0"; materiais[2].quantidade = 12; materiais[2].precisaComprar = true; materiais[3].item = "display OLED I2C"; materiais[3].situacao = "funcionando, 1 com cabo solto no VCC"; materiais[3].quantidade = 12; materiais[3].precisaComprar = false; materiais[4].item = "jumpers"; materiais[4].situacao = "faltaram 3 kits, repuser do armario"; materiais[4].quantidade = 12; materiais[4].precisaComprar = true; materiais[5].item = "fonte de bancada"; materiais[5].situacao = "1 queimou em marco, falta reposicao"; materiais[5].quantidade = 1; materiais[5].precisaComprar = true; totalDeMateriais = 6; } void montarSugestoes() { sugestoes[0].mudanca = "aumentar a aula de migracao para duas"; sugestoes[0].porque = "a turma mais travou em migration, nao em sintaxe"; sugestoes[0].prioridade = 1; sugestoes[1].mudanca = "comprar um kit de reserva antes de comprar sensor"; sugestoes[1].porque = "placa que quebra para a aula inteira, sensor e 20 reais"; sugestoes[1].prioridade = 1; sugestoes[2].mudanca = "guardar os 3 kits de jumper no armario com etiqueta"; sugestoes[2].porque = "faltou material 3 vezes no mesmo trimestre"; sugestoes[2].prioridade = 2; sugestoes[3].mudanca = "comecar o segundo trimestre com revisao de 1 aula"; sugestoes[3].porque = "quem entrou depois da semana 2 nao acompanhou a camada de rede"; sugestoes[3].prioridade = 2; totalDeSugestoes = 4; } // ------------------------------------------------------------------ saida void imprimirContagem() { Serial.println("========================================"); Serial.println(" o ano em numeros"); Serial.println("========================================"); Serial.println("trimestres: " + String(TRIMESTRES) + " (13 + 16 + 15 dias)"); Serial.println("aulas: " + String(TOTAL_DE_AULAS_DO_ANO) + " (" + String(DIAS_DO_ANO) + " dias de 2)"); Serial.println("firmware: versao " + String(VERSAO_FIRMWARE)); Serial.println("cpu: " + String(getCpuFrequencyMhz()) + " MHz"); Serial.println("heap: " + String(ESP.getFreeHeap()) + " bytes"); Serial.println(); } void imprimirOQueFechou() { Serial.println("========================================"); Serial.println(" 1. o que este ciclo entregou"); Serial.println("========================================"); int entregues = 0; for (int i = 0; i < totalDoFechamento; i++) { if (fechamento[i].entregue) entregues++; Serial.println(" [" + String(fechamento[i].entregue ? "x" : " ") + "] " + String(fechamento[i].item) + " — " + String(fechamento[i].como)); } Serial.println(); Serial.println("entregues: " + String(entregues) + " de " + String(totalDoFechamento)); Serial.println(); Serial.println("a camada que oano juntou e a que responde a pergunta 'onde"); Serial.println("o dado comeca e onde ele termina'. Um aluno que sabe dizer"); Serial.println("isso sem olhar para o diagrama fez o ano."); Serial.println(); } void imprimirCusto() { Serial.println("========================================"); Serial.println(" quanto custa uma vaga aberta"); Serial.println("========================================"); Serial.println("kit por aluno: R$ " + String(CUSTO_DO_KIT_POR_ALUNO, 2)); Serial.println("turma de 12: R$ " + String(CUSTO_DO_KIT_POR_ALUNO * 12, 2)); Serial.println("a comprar de novo:"); int paraComprar = 0; for (int i = 0; i < totalDeMateriais; i++) { if (materiais[i].precisaComprar) paraComprar++; } Serial.println(" itens: " + String(paraComprar) + " de " + String(totalDeMateriais)); Serial.println(); Serial.println("a conta que o titular faz nao e o custo do material: e o"); Serial.println("custo de uma placa que quebrou na semana 3 e o que a aula"); Serial.println("nao virou naquele dia. Por isso a reserva vem primeiro."); Serial.println(); } void imprimirInventario() { Serial.println("========================================"); Serial.println(" 2. o material: o que quebrou, o que faltou"); Serial.println("========================================"); for (int i = 0; i < totalDeMateriais; i++) { Serial.println(); Serial.println(" " + String(materiais[i].item) + " (x" + String(materiais[i].quantidade) + ")"); Serial.println(" situacao: " + String(materiais[i].situacao)); Serial.println(" comprar: " + String(materiais[i].precisaComprar ? "SIM" : "nao")); } Serial.println(); Serial.println("esta e a lista que o professor leva para a coordenacao."); Serial.println("ela nao vai para o portal do aluno: sao problemas internos"); Serial.println("da escola, e o aluno nao tem o que fazer com isso."); Serial.println(); } void imprimirSugestoes() { Serial.println("========================================"); Serial.println(" as sugestoes para o proximo ano"); Serial.println("========================================"); for (int i = 0; i < totalDeSugestoes; i++) { Serial.println(); Serial.println(" prioridade " + String(sugestoes[i].prioridade) + ": " + String(sugestoes[i].mudanca)); Serial.println(" porque: " + String(sugestoes[i].porque)); } Serial.println(); Serial.println("prioridade 1 e o que muda o ano; prioridade 2 e o que so"); Serial.println("tira trabalho. A ordem importa: comprar jumper antes de"); Serial.println("mudar o conteudo e o que o aluno sente na aula."); Serial.println(); } void imprimirEncerramento() { Serial.println("========================================"); Serial.println(" 3. encerramento"); Serial.println("========================================"); Serial.println("o ciclo fecha aqui, e a placa fica na bancada com a ultima"); Serial.println("gravacao. A proxima turma recebe o mesmo kit e o mesmo"); Serial.println("material, so que com as correcoes desta lista aplicadas."); Serial.println(); Serial.println("obrigado: a placa imprime uma vez por boot, e o professor"); Serial.println("nao precisa ler a palavra para dizer a de verdade."); Serial.println(); Serial.println("a proxima etapa e continuar estudando, com projeto proprio"); Serial.println("e com a sequencia de ports: firmware, depois servidor, depois"); Serial.println("os dois juntos. O ano que vem comeca onde este terminou."); Serial.println(); } // ---------------------------------------------------------------- setup void setup() { Serial.begin(115200); delay(400); pinMode(PIN_LED_STATUS, OUTPUT); pinMode(PIN_BOTAO_FECHAMENTO, INPUT_PULLUP); digitalWrite(PIN_LED_STATUS, HIGH); Serial.println(); Serial.println("========================================"); Serial.println("========================================"); Serial.println(" FIM DO ANO LETIVO — v" + String(VERSAO_FIRMWARE)); Serial.println("========================================"); Serial.println("========================================"); Serial.println("dispositivo: " + String(ID_DISPOSITIVO) + " | ultima gravacao do ano"); Serial.println(); montarFechamento(); montarMateriais(); montarSugestoes(); imprimirContagem(); imprimirOQueFechou(); imprimirCusto(); imprimirInventario(); imprimirSugestoes(); imprimirEncerramento(); Serial.println("========================================"); Serial.println(" placa de encerramento ligada e respondendo"); Serial.println("========================================"); } void loop() { // A placa fica viva ate o fim do periodo letivo. Nao e preciso manter // isso ligado, e o que importa e o registro: a ultima versao gravada // e a que fica no historico do laboratorio. digitalWrite(PIN_LED_STATUS, !digitalRead(PIN_LED_STATUS)); if (digitalRead(PIN_BOTAO_FECHAMENTO) == LOW) { static unsigned long ultimoToque = 0; if (millis() - ultimoToque > 2000) { ultimoToque = millis(); Serial.println(); Serial.println("========================================"); Serial.println(" ate a proxima"); Serial.println("========================================"); Serial.println("dispositivo: " + String(ID_DISPOSITIVO) + " v" + String(VERSAO_FIRMWARE)); Serial.println("firmware gravado em: " + String(__DATE__) + " as " + String(__TIME__)); Serial.println("heap: " + String(ESP.getFreeHeap()) + " bytes | cpu: " + String(getCpuFrequencyMhz()) + " MHz"); Serial.println("========================================"); Serial.println(); } } Serial.println("[fim do ano] viva | v" + String(VERSAO_FIRMWARE) + " | heap " + String(ESP.getFreeHeap()) + " B | LED " + String(digitalRead(PIN_LED_STATUS) ? "aceso" : "apago")); delay(9000); }
Por que assim e não de outro jeito. A última aula do ano não tem código para aprender, e o esqueleto óbvio seria um sketch vazio com um "obrigado". A placa faz o fechamento contábil do ano, e a escolha é deliberada: as três listas que o professor precisa ler em voz alta saem da placa, e não da memória dele. Memória de professor erra número; a lista impressa não.
O primeiro bloco é a contagem, e ele vem antes de tudo porque é o que dá escala ao resto: três trimestres, quarenta e quatro dias, oitenta e oito aulas. O __DATE__ e o __TIME__ no fim do loop são a prova de que o ano tem data, e não só número.
E aqui está a armadilha do número, que o professor aponta em voz alta antes de qualquer coisa: a conta de 15 × 2 × 3 = 90 não fecha. Trimestre não tem quinze dias cada — o primeiro tem treze, o segundo tem dezesseis e o terceiro tem quinze. Quem escreve 90 no slide está contando dias que não existem, e o aluno que conferir o eixo descobre. Número inventado é erro de regra, e a última aula do curso é o único lugar do ano em que o aluno audita a conta do professor.
A segunda lista é o que este ciclo entregou, e o campo entregue é um bool por item. Ele não está ali por decoração: o professor marca o que não fechou, se alguma camada não fechou, e o contador soma. Sete de sete é o número de hoje; se fosse seis de sete, o Serial diria seis de sete sem que ninguém precisasse contar, e é essa automatização boba que evita a constante "entregues?" da conversa.
O terceiro bloco é a lista que vai para a coordenação, e ele é o inverso do anterior: as sete camadas são para a turma e o inventário é para a escola. A placa separa os dois porque eles têm leitores diferentes, e o aluno não tem o que fazer com a informação de que a fonte queimou em março. A linha do Serial que diz isso na tela é a que o professor lê antes de guardá-la.
O CUSTO_DO_KIT_POR_ALUNO é um float, e a conta da turma é a multiplicação dele por doze. O professor explica por que float e não int em reais: os centavos existem, e um inteiro de reais arredonda o custo por aluno sem que ninguém perceba. A saída usa String com duas casas para o valor, que é a diferença entre "R$ 145" e "R$ 145,00" no orçamento que vai para a coordenação.
O contador de itens a comprar é feito com uma passada no vetor, e não com um número escrito à mão. Isso é a mesma disciplina do dia 5: quem escreve o total à mão erra quando alguém corrige a lista no meio do trimestre, e o erro fica na placa até o fim do ano.
O loop imprime a placa viva e, no botão, imprime a data e a hora da gravação com __DATE__ e __TIME__. Esses dois macros são resolvidos quando o firmware é compilado, e o professor explica que por isso eles dizem quando o professor gravou, e não quando a placa acordou — a diferença importa quando alguém quiser saber de quando é a imagem que está rodando naquele poste.
A resolução fecha lembrando que a placa não precisa ficar ligada: o que importa é o registro, e a última versão gravada é a que fica no arquivo do laboratório. Manter doze placas ligadas durante o recesso é custo sem retorno.
Criterios de correcao
| Critério | Pontos |
|---|---|
| Três números da contagem anotados e comparados com o calendário da escola | 2 pontos |
| Camadas entregues contadas, e a camada que falta escrita com o que falta para ela fechar | 2 pontos |
| Inventário conferido contra a lista da placa, com a diferença nomeada | 2 pontos |
| Custo da vaga escrito nas duas partes, com o maior número identificado | 2 pontos |
| Quatro sugestões ordenadas com as suas palavras, com a prioridade justificada | 2 pontos |
| Próxima etapa com data, uma coisa e horas | 1 ponto |
| Última frase escrita sobre o que a próxima turma recebe | 1 ponto |
Erros comuns
| Erro | Como aparece | Correcao |
|---|---|---|
| "Faltou material" como desculpa para a baixa presença | a turma não assistiu e o nome da peça some da conversa | "Falta de material é um dado, e a placa tem a lista. Mas ausência de aluno não sai de peça quebrada — e transformar tudo em falha de material tira do aluno a parte que é dele." |
| Comprar peça porque uma com defeito apareceu | o professor volta com dois displays novos e um cabo velho ainda na bancada | "Peça com defeito não é peça para comprar se o defeito é no cabo. Resolva o cabo antes. Comprar antes de diagnosticar é o erro do dia 11 aplicado ao armário." |
| Contar material como custo da vaga | o orçamento da coordenação usa só o número do kit | "O custo do material é a parte fácil. A cara é a placa que quebrou na semana 3 e a aula que não virou. Esse número não aparece em nota fiscal e é o que a coordenação precisa ouvir." |
| Lista de sugestões sem prioridade | dez itens em ordem aleatória | "Sem prioridade, a lista é reclamação. Duas marcadas mudam o ano; o resto só tira trabalho. Quatro itens com duas marcadas valem mais que dez sem nenhuma." |
| Mudança de conteúdo antes de mudança de material | a lista começa por "aumentar a aula de migration" e o jumper some | "Ordem importa. O jumper que faltou tirou três kits de aula: o aluno sente isso no dia. A aula de migração é prioridade um, mas a segunda lista é o que a turma sente primeiro." |
| Escrever "obrigado" e encerrar sem pergunta | o aluno não sabe se pode perguntar nada depois | "Encerramento não é dispensa. Deixe a pergunta aberta e aceite a dúvida que aparecer na próxima turma, mesmo que seja sobre coisa já dada." |
| Prometer material para a turma sem comprar antes | o professor anuncia um kit que não existe no armário | "Promessa de material é dívida. Se não está comprado, não anuncia. Aluno que chega e não tem o que foi prometido aprende que anúncio não vale nada." |
| Plano do aluno sem data | "vou publicar quando eu conseguir" | "Sem data, não é plano. Escreva uma data e um número de horas. 'Quando conseguir' é o mesmo que não fazer, escrito com otimismo." |
| Plano com prazo mas sem horas | "semana que vem, umas horas" | "Horas é o que protege o prazo. Vinte e cinco horas cabem em duas semanas; 'umas horas' não cabe em prazo nenhum." |
| Dizer que não falta nada | o aluno monta a lista e nenhuma sugestão tem prioridade 1 | "Quem não encontra nada para mudar no próprio ano não olhou. Alguém da turma sempre tem uma sugestão que você não tinha pensado — peça, não assuma." |
| Levar o inventário para a aula do aluno | o aluno passa o ano inteiro lendo sobre a fonte queimada | "A lista de material é problema da escola, e fica com a escola. O aluno precisa de um inventário de habilidade, que é a aula de ontem." |
| Tratar o encerramento como repetição | o professor repete a última aula do dia 13 e chama de despedida | "Encerrar é somar, não repetir. Se a última aula é conteúdo novo, o curso não fechou — faltou a semana que fecha." |
| Deixar a placa gravada sem ler nada | a placa fica no armário e ninguém confere a versão | "Grave e leia uma vez na frente da turma. É o registro do ano, e registro que ninguém lê é o mesmo que registro que não existe." |
Desafio extra
Faça o inventário do seu próprio kit de bancada, com seis itens e a situação real de cada um: funciona, funciona com reserva, ou não funciona. Some o que está de reserva e escreva o que você precisaria comprar para ter uma placa que não falha. Depois escreva as melhorias para o próximo ano do seu ponto de vista, com prioridade e motivo — a mesma lista que o professor leva para a coordenação, mas com a sua assinatura. Meça quanto tempo as duas listas levaram, e escreva uma frase sobre o que impede uma pessoa de fazer esse inventário com honestidade: pressa, apego à ferramenta que funciona, ou medo de descobrir que o que ela usa é o que quebrou.
A resolucao, compilada
// Aula 2 do dia 15: encerramento do ano e o passo depois. // // Ultima aula do ano. Nao ha codigo novo para aprender e nao ha prova: ha // um ciclo fechando e duas perguntas que so o titular pode responder. // // A placa faz o fechamento contábil do ano. Ela conta o que o ciclo entregou // (as 30 aulas, os 15 dias, as 3 trilhas), e ela recolhe o que faltou — o // inventário de material, que e a parte que o professor leva para a // coordinate e que costuma ser ignorada. // // Os dois blocos que o professor precisa ler em voz alta: // // 1. O QUE FECHOU: o ciclo que fecha, o que a turma entregou, e o numero // que responde "valeu a pena". // 2. O QUE FALTOU: o material que quebrou, o que faltou comprar, e as // tres sugestoes de mudanca que mudam o ano que vem. // // A segunda lista e a que o professor vai agradecer. E a unica aula do ano // em que o aluno escreve no codigo, e a escrita e sobre a escola, nao sobre // o firmware. #include <Arduino.h> // Versao do firmware. Ultima gravacao do ano: e o que fica na placa quando // a turma toda apagada e o laboratorio fecha. #define VERSAO_FIRMWARE "2.0.0" #define ID_DISPOSITIVO "esp32-bancada-01" // ------------------------------------------------------------------ pinos const int PIN_LED_STATUS = 2; const int PIN_BOTAO_FECHAMENTO = 0; // -------------------------------------------------------------- configuracao // Numero de aulas do ano. Soma dos tres trimestres do eixo: 13 + 16 + 15 // dias, com 2 aulas por dia. O numero e medido no eixo, nao escolhido. const int DIAS_DO_ANO = 44; const int TOTAL_DE_AULAS_DO_ANO = 88; const int TRIMESTRES = 3; // Custo do material, em reais. Valor de referencia do kit da bancada, e o // que o professor usa para calcular quanto custa matricular um aluno novo. const float CUSTO_DO_KIT_POR_ALUNO = 145.00; // ------------------------------------------------------------------ tipos struct OQueFechou { const char* item; const char* como; bool entregue; }; struct Material { const char* item; const char* situacao; int quantidade; bool precisaComprar; }; struct Sugestao { const char* mudanca; const char* porque; int prioridade; }; // --------------------------------------------------------------- montagem OQueFechou fechamento[7]; int totalDoFechamento = 0; Material materiais[6]; int totalDeMateriais = 0; Sugestao sugestoes[4]; int totalDeSugestoes = 0; void montarFechamento() { fechamento[0].item = "a camada de hardware"; fechamento[0].como = "sensor, display e saida digital, com fiaçao certa"; fechamento[0].entregue = true; fechamento[1].item = "a camada de firmware"; fechamento[1].como = "C++ que compila, com tempo limite e log"; fechamento[1].entregue = true; fechamento[2].item = "a camada de rede"; fechamento[2].como = "WiFi que reconecta, HTTP com codigo de status"; fechamento[2].entregue = true; fechamento[3].item = "a camada de servidor"; fechamento[3].como = "Node com login, sessao, permissao e log com id"; fechamento[3].entregue = true; fechamento[4].item = "a camada de banco"; fechamento[4].como = "MySQL com repository, migracao e paginacao"; fechamento[4].entregue = true; fechamento[5].item = "a camada de entrega"; fechamento[5].como = "teste, seguranca, deploy e README que roda"; fechamento[5].entregue = true; fechamento[6].item = "o projeto final"; fechamento[6].como = "sistema completo, apresentado e revisado"; fechamento[6].entregue = true; totalDoFechamento = 7; } void montarMateriais() { materiais[0].item = "ESP32 DevKit V1"; materiais[0].situacao = "funcionando, 2 com o cabo frouxo"; materiais[0].quantidade = 12; materiais[0].precisaComprar = true; materiais[1].item = "cabo USB"; materiais[1].situacao = "funcionando, 1 na troca"; materiais[1].quantidade = 12; materiais[1].precisaComprar = true; materiais[2].item = "DHT11"; materiais[2].situacao = "2 falhando, leitura travada em 0"; materiais[2].quantidade = 12; materiais[2].precisaComprar = true; materiais[3].item = "display OLED I2C"; materiais[3].situacao = "funcionando, 1 com cabo solto no VCC"; materiais[3].quantidade = 12; materiais[3].precisaComprar = false; materiais[4].item = "jumpers"; materiais[4].situacao = "faltaram 3 kits, repuser do armario"; materiais[4].quantidade = 12; materiais[4].precisaComprar = true; materiais[5].item = "fonte de bancada"; materiais[5].situacao = "1 queimou em marco, falta reposicao"; materiais[5].quantidade = 1; materiais[5].precisaComprar = true; totalDeMateriais = 6; } void montarSugestoes() { sugestoes[0].mudanca = "aumentar a aula de migracao para duas"; sugestoes[0].porque = "a turma mais travou em migration, nao em sintaxe"; sugestoes[0].prioridade = 1; sugestoes[1].mudanca = "comprar um kit de reserva antes de comprar sensor"; sugestoes[1].porque = "placa que quebra para a aula inteira, sensor e 20 reais"; sugestoes[1].prioridade = 1; sugestoes[2].mudanca = "guardar os 3 kits de jumper no armario com etiqueta"; sugestoes[2].porque = "faltou material 3 vezes no mesmo trimestre"; sugestoes[2].prioridade = 2; sugestoes[3].mudanca = "comecar o segundo trimestre com revisao de 1 aula"; sugestoes[3].porque = "quem entrou depois da semana 2 nao acompanhou a camada de rede"; sugestoes[3].prioridade = 2; totalDeSugestoes = 4; } // ------------------------------------------------------------------ saida void imprimirContagem() { Serial.println("========================================"); Serial.println(" o ano em numeros"); Serial.println("========================================"); Serial.println("trimestres: " + String(TRIMESTRES) + " (13 + 16 + 15 dias)"); Serial.println("aulas: " + String(TOTAL_DE_AULAS_DO_ANO) + " (" + String(DIAS_DO_ANO) + " dias de 2)"); Serial.println("firmware: versao " + String(VERSAO_FIRMWARE)); Serial.println("cpu: " + String(getCpuFrequencyMhz()) + " MHz"); Serial.println("heap: " + String(ESP.getFreeHeap()) + " bytes"); Serial.println(); } void imprimirOQueFechou() { Serial.println("========================================"); Serial.println(" 1. o que este ciclo entregou"); Serial.println("========================================"); int entregues = 0; for (int i = 0; i < totalDoFechamento; i++) { if (fechamento[i].entregue) entregues++; Serial.println(" [" + String(fechamento[i].entregue ? "x" : " ") + "] " + String(fechamento[i].item) + " — " + String(fechamento[i].como)); } Serial.println(); Serial.println("entregues: " + String(entregues) + " de " + String(totalDoFechamento)); Serial.println(); Serial.println("a camada que oano juntou e a que responde a pergunta 'onde"); Serial.println("o dado comeca e onde ele termina'. Um aluno que sabe dizer"); Serial.println("isso sem olhar para o diagrama fez o ano."); Serial.println(); } void imprimirCusto() { Serial.println("========================================"); Serial.println(" quanto custa uma vaga aberta"); Serial.println("========================================"); Serial.println("kit por aluno: R$ " + String(CUSTO_DO_KIT_POR_ALUNO, 2)); Serial.println("turma de 12: R$ " + String(CUSTO_DO_KIT_POR_ALUNO * 12, 2)); Serial.println("a comprar de novo:"); int paraComprar = 0; for (int i = 0; i < totalDeMateriais; i++) { if (materiais[i].precisaComprar) paraComprar++; } Serial.println(" itens: " + String(paraComprar) + " de " + String(totalDeMateriais)); Serial.println(); Serial.println("a conta que o titular faz nao e o custo do material: e o"); Serial.println("custo de uma placa que quebrou na semana 3 e o que a aula"); Serial.println("nao virou naquele dia. Por isso a reserva vem primeiro."); Serial.println(); } void imprimirInventario() { Serial.println("========================================"); Serial.println(" 2. o material: o que quebrou, o que faltou"); Serial.println("========================================"); for (int i = 0; i < totalDeMateriais; i++) { Serial.println(); Serial.println(" " + String(materiais[i].item) + " (x" + String(materiais[i].quantidade) + ")"); Serial.println(" situacao: " + String(materiais[i].situacao)); Serial.println(" comprar: " + String(materiais[i].precisaComprar ? "SIM" : "nao")); } Serial.println(); Serial.println("esta e a lista que o professor leva para a coordenacao."); Serial.println("ela nao vai para o portal do aluno: sao problemas internos"); Serial.println("da escola, e o aluno nao tem o que fazer com isso."); Serial.println(); } void imprimirSugestoes() { Serial.println("========================================"); Serial.println(" as sugestoes para o proximo ano"); Serial.println("========================================"); for (int i = 0; i < totalDeSugestoes; i++) { Serial.println(); Serial.println(" prioridade " + String(sugestoes[i].prioridade) + ": " + String(sugestoes[i].mudanca)); Serial.println(" porque: " + String(sugestoes[i].porque)); } Serial.println(); Serial.println("prioridade 1 e o que muda o ano; prioridade 2 e o que so"); Serial.println("tira trabalho. A ordem importa: comprar jumper antes de"); Serial.println("mudar o conteudo e o que o aluno sente na aula."); Serial.println(); } void imprimirEncerramento() { Serial.println("========================================"); Serial.println(" 3. encerramento"); Serial.println("========================================"); Serial.println("o ciclo fecha aqui, e a placa fica na bancada com a ultima"); Serial.println("gravacao. A proxima turma recebe o mesmo kit e o mesmo"); Serial.println("material, so que com as correcoes desta lista aplicadas."); Serial.println(); Serial.println("obrigado: a placa imprime uma vez por boot, e o professor"); Serial.println("nao precisa ler a palavra para dizer a de verdade."); Serial.println(); Serial.println("a proxima etapa e continuar estudando, com projeto proprio"); Serial.println("e com a sequencia de ports: firmware, depois servidor, depois"); Serial.println("os dois juntos. O ano que vem comeca onde este terminou."); Serial.println(); } // ---------------------------------------------------------------- setup void setup() { Serial.begin(115200); delay(400); pinMode(PIN_LED_STATUS, OUTPUT); pinMode(PIN_BOTAO_FECHAMENTO, INPUT_PULLUP); digitalWrite(PIN_LED_STATUS, HIGH); Serial.println(); Serial.println("========================================"); Serial.println("========================================"); Serial.println(" FIM DO ANO LETIVO — v" + String(VERSAO_FIRMWARE)); Serial.println("========================================"); Serial.println("========================================"); Serial.println("dispositivo: " + String(ID_DISPOSITIVO) + " | ultima gravacao do ano"); Serial.println(); montarFechamento(); montarMateriais(); montarSugestoes(); imprimirContagem(); imprimirOQueFechou(); imprimirCusto(); imprimirInventario(); imprimirSugestoes(); imprimirEncerramento(); Serial.println("========================================"); Serial.println(" placa de encerramento ligada e respondendo"); Serial.println("========================================"); } void loop() { // A placa fica viva ate o fim do periodo letivo. Nao e preciso manter // isso ligado, e o que importa e o registro: a ultima versao gravada // e a que fica no historico do laboratorio. digitalWrite(PIN_LED_STATUS, !digitalRead(PIN_LED_STATUS)); if (digitalRead(PIN_BOTAO_FECHAMENTO) == LOW) { static unsigned long ultimoToque = 0; if (millis() - ultimoToque > 2000) { ultimoToque = millis(); Serial.println(); Serial.println("========================================"); Serial.println(" ate a proxima"); Serial.println("========================================"); Serial.println("dispositivo: " + String(ID_DISPOSITIVO) + " v" + String(VERSAO_FIRMWARE)); Serial.println("firmware gravado em: " + String(__DATE__) + " as " + String(__TIME__)); Serial.println("heap: " + String(ESP.getFreeHeap()) + " bytes | cpu: " + String(getCpuFrequencyMhz()) + " MHz"); Serial.println("========================================"); Serial.println(); } } Serial.println("[fim do ano] viva | v" + String(VERSAO_FIRMWARE) + " | heap " + String(ESP.getFreeHeap()) + " B | LED " + String(digitalRead(PIN_LED_STATUS) ? "aceso" : "apago")); delay(9000); }
Sem saída de compilação gravada. Rode python3 validar.py -t 3 dia15 aula2.
