#include <stdio.h> // Funções padrão de entrada/saída (printf).
#include <string.h> // Funções para manipulação de strings.
#include "pico/stdlib.h" // Funções padrão do Raspberry Pi Pico.
#include "ili9341.h" // Biblioteca para controle do display ILI9341.
#include "hardware/i2c.h" // Biblioteca para comunicação I2C.
// Configuração do sensor AHT10 (I2C)
#define I2C_PORT i2c0 // Define a porta I2C (i2c0).
#define AHT10_ADDR 0x38 // Endereço I2C do sensor AHT10.
#define SDA_AHT10 4 // Pino GPIO para SDA do AHT10.
#define SCL_AHT10 5 // Pino GPIO para SCL do AHT10.
// Definindo os pinos do display para comunicação SPI
ILI9341_t display = { // Estrutura de configuração do display.
.sck = 18, // Pino SCK (clock serial).
.mosi = 19, // Pino MOSI (Master Out Slave In).
.cs = 17, // Pino CS (Chip Select).
.rst = 20, // Pino RST (Reset).
.dc = 21, // Pino DC (Data/Command).
.bl = 22, // Pino BL (Backlight).
.orientation = 0x60 // Orientação do display.
};
float temperatura, umidade; // Variáveis globais para temperatura e umidade.
void aht10_init() // Inicializa o sensor AHT10.
{
uint8_t cmd[] = {0xBE, 0x08, 0x00}; // Comando de calibração/inicialização AHT10.
i2c_write_blocking(I2C_PORT, AHT10_ADDR, cmd, 3, false); // Envia comando ao sensor.
}
void aht10_trigger_monitoring() // Inicia uma nova medição no AHT10.
{
uint8_t cmd[] = {0xAC, 0x33, 0x00}; // Comando para iniciar medição.
i2c_write_blocking(I2C_PORT, AHT10_ADDR, cmd, 3, false); // Envia comando de trigger.
sleep_ms(50); // Aguarda o tempo necessário para a medição.
}
void aht10_read() // Lê dados de temperatura e umidade do AHT10.
{
uint8_t data[6]; // Buffer para armazenar os 6 bytes de dados.
int input_read = i2c_read_blocking(I2C_PORT, AHT10_ADDR, data, 6, false); // Lê 6 bytes.
if (input_read != 6) printf("Erro. Leitura incorreta do sensor.\n"); // Verifica erros na leitura.
// Decodifica os bytes brutos para umidade e temperatura.
uint32_t umidade_raw = ((uint32_t)data[1] << 12) | ((uint32_t)data[2] << 4) | ((data[3] >> 4) & 0x0F);
uint32_t temperatura_raw = (((uint32_t)data[3] & 0x0F) << 16) | ((uint32_t)data[4] << 8) | data[5];
// Converte os valores brutos para umidade (%) e temperatura (°C).
umidade = ((float)umidade_raw / 1048576) * 100.0;
temperatura = ((float)temperatura_raw / 1048576) * 125.0 - 40.0;
}
void init_pins() // Inicializa pinos I2C e o display.
{
i2c_init(I2C_PORT, 100 * 1000); // Inicializa I2C com 100 kHz.
gpio_set_function(SDA_AHT10, GPIO_FUNC_I2C); // Configura SDA para I2C.
gpio_set_function(SCL_AHT10, GPIO_FUNC_I2C); // Configura SCL para I2C.
gpio_pull_up(SDA_AHT10); // Habilita pull-up no pino SDA.
gpio_pull_up(SCL_AHT10); // Habilita pull-up no pino SCL.
aht10_init(); // Inicializa o sensor AHT10.
ILI9341_init(&display); // Inicializa o display ILI9341.
}
int main() { // Função principal do programa.
stdio_init_all(); // Inicializa console serial.
init_pins(); // Inicializa pinos e periféricos.
uint16_t color = RGB_to_RGB565(255, 255, 255); // Define cor branca para texto.
ILI9341_clear(&display); // Limpa o display uma vez na inicialização.
char texto_monitoramento[50]; // Buffer para o texto de monitoramento.
while (true) { // Loop infinito para leituras e atualizações.
aht10_trigger_monitoring(); // Aciona nova medição no sensor.
aht10_read(); // Lê os valores de temperatura e umidade.
// Verifica condições de perigo e exibe mensagens no display.
if (temperatura < 20 || umidade > 70) {
ILI9341_drawText(&display, 0, 176, " Perigo.", color, 1, 1);
ILI9341_drawText(&display, 0, 164, " Temp ou Umidade RUINS", color, 1, 1);
}
// Formata string com temperatura e umidade.
sprintf(texto_monitoramento, " Temperatura %.1f Umidade %.1f%%", temperatura, umidade);
// Desenha texto de monitoramento no display.
ILI9341_drawText(&display, 0, 208, texto_monitoramento, color, 1, 1);
ILI9341_clear(&display); // ATENÇÃO: Limpa o display completamente a cada loop.
// Isso fará o display piscar e o texto sumir rapidamente.
// Idealmente, limpar apenas a área do texto dinâmico.
sleep_ms(1000); // Pausa por 1 segundo antes da próxima iteração.
}
}