Pular para conteúdo

Funções

O firmware é dividido em tarefas do FreeRTOS — pequenos programas que rodam "ao mesmo tempo", cada um cuidando de uma única responsabilidade. Essa divisão deixa o código simples: em vez de um laço gigante fazendo tudo, cada tarefa tem um objetivo claro e um ritmo próprio.

As tarefas não conversam diretamente entre si. Existem tarefas que produzem dados (leem os sensores, decidem o aquecedor) e tarefas que consomem esses dados (acendem o LED, apitam, desenham no display, respondem à web). A ponte entre elas é sempre o estado compartilhado (ver Arquitetura).

Tarefas do sistema

Tarefa (função) O que faz Período Arquivo
task_sensor Lê temperatura e pressão do BMP280 2 s task_sensor.c
task_dht11 Lê a umidade do DHT11 2 s task_dht11.c
task_control Liga/desliga o aquecedor por histerese 1 s task_control.c
task_led_status Define a cor do LED conforme a temperatura 0,3 s task_led_status.c
task_buzzer Apita quando a temperatura sai da faixa 0,25 s task_buzzer.c
task_display Desenha a leitura e o estado no OLED 1 s task_display.c
Wi-Fi + HTTP Sobe o SoftAP e o servidor web serviço task_wifi_ap.c · task_http_server.c
Detalhe técnico — tarefas, prioridades e leitura dos sensores

Cada tarefa é criada no app_main() com xTaskCreate, recebendo uma prioridade e um tamanho de pilha. As tarefas de aquisição e controle (task_sensor, task_dht11, task_control) têm prioridade um pouco maior que as de saída (display, LED, buzzer), porque medir e agir sobre o aquecedor é mais importante que atualizar a tela.

Os períodos vêm de vTaskDelay: o sensor e a umidade a cada 2 s, o controle a cada 1 s (para reagir rápido), o LED a cada 0,3 s e o buzzer a cada 0,25 s (para o apito intermitente). A task_sensor lê só temperatura e pressão (BMP280) e a task_dht11 lê só umidade (DHT11) — cada uma publica a sua parte no estado compartilhado.

Controle do aquecedor (histerese)

A task_control é o coração do sistema: ela mantém a temperatura numa faixa estreita ligando e desligando o relé do aquecedor. Não é um liga/desliga simples — usa histerese (uma "banda morta") para o aquecedor não ficar chaveando toda hora, o que desgastaria o relé e faria a temperatura oscilar demais.

  • Liga o aquecedor quando a temperatura cai a 28 °C;
  • Desliga quando a temperatura atinge 29 °C;
  • entre 28 e 29 °C, mantém o estado atual.
if (heating) {
    if (temperatura >= HEATER_OFF_ABOVE_C)   // 29 °C -> desliga
        heating = false;
} else {
    if (temperatura <= HEATER_ON_BELOW_C)    // 28 °C -> liga
        heating = true;
}

Segurança

Se a leitura de temperatura falhar (sensor com problema), a task_control desliga o aquecedor por segurança, em vez de continuar aquecendo às cegas.

Detalhe técnico — por que histerese

Sem banda morta, um único limite (ex.: "ligar/desligar em 28,5 °C") faria o relé chavear dezenas de vezes por minuto perto do ponto de corte, pois a temperatura sempre flutua alguns centésimos. A histerese cria dois limites diferentes (28 para ligar, 29 para desligar): o aquecedor só volta a ligar depois que a temperatura realmente caiu, resultando em ciclos longos e estáveis. Os dois valores são #define em app_config.h (HEATER_ON_BELOW_C e HEATER_OFF_ABOVE_C), fáceis de ajustar.

Alarme e sinalização

O LED RGB e o buzzer avisam se a temperatura saiu da faixa segura (27 a 32 °C). Repare que essa faixa é mais larga que a de controle (28–29): o controle mantém a temperatura no ponto ideal, e o alarme só dispara se algo der muito errado.

Situação Temperatura LED Buzzer Aquecedor
Muito frio < 27 °C 🔴 vermelho apitando ligado
Faixa segura 27 – 32 °C 🟢 verde silêncio histerese 28 ↔ 29 °C
Muito quente > 32 °C 🔴 vermelho apitando desligado
Inicializando / falha de sensor — 🔵 azul silêncio desligado
Detalhe técnico — como o estado é calculado

Uma função central, compute_status(), traduz a temperatura em um estado (ST_OK, ST_WARNING, ST_ALARM, ST_ERROR, ST_INIT) comparando a leitura com a faixa ideal (TEMP_IDEAL_MIN/TEMP_IDEAL_MAX) mais uma margem (TEMP_ALERTA_BANDA). Com os valores atuais (28, 31 e 1 °C), o alarme (ST_ALARM) ocorre abaixo de 27 ou acima de 32 °C. O LED fica verde em toda a faixa segura e vermelho no alarme; o buzzer apita apenas em ST_ALARM. As faixas de alarme e de controle são independentes — mexer em uma não afeta a outra.

Página web e API

A task_wifi_ap cria uma rede Wi-Fi própria (SoftAP IncubadoraAP, sem precisar de roteador) e a task_http_server sobe um servidor em http://192.168.4.1. Ao conectar o celular nessa rede, a página mostra as leituras atualizando sozinhas.

Rota Método Função
/ GET Página HTML com temperatura, umidade, pressão e estado do aquecedor
/api/status GET JSON com as leituras atuais e o status
/api/config GET / POST Consulta e ajusta as faixas de alarme
Detalhe técnico — servidor e API

O servidor usa o esp_http_server do ESP-IDF, que roda na sua própria tarefa interna. A página em / é servida como uma string HTML única (com o JavaScript embutido) que, a cada 2 s, busca /api/status e atualiza os campos. O /api/status responde um JSON como {"temperature":28.5,"humidity":41,"pressure":898,"heater":true,"status":"ok"}. O POST /api/config recebe novas faixas de alarme (formato form-encoded), valida e aplica na hora, sem reiniciar.