#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "dht22.h"
#include "hardware/gpio.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "hardware/i2c.h"
#include "ssd1306.h"
#define DHT_PIN 26
#define BUZZER_PIN 21
#define I2C_PORT i2c1
#define SDA_PIN 14 // Pino SDA
#define SCL_PIN 15 // Pino SCL
void set_pwm_duty_cycle(uint pin, uint duty_cycle_percent, uint top) {
uint level = (duty_cycle_percent * top) / 100;
pwm_set_gpio_level(pin, level);
}
void pwm_init_buzzer(uint pin) {
gpio_set_function(pin, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(pin);
pwm_config config = pwm_get_default_config();
pwm_config_set_clkdiv(&config, 2.0f);
pwm_init(slice_num, &config, true);
pwm_set_gpio_level(pin, 0);
}
void beep(uint pin, uint frequency, uint duration_ms) {
uint slice_num = pwm_gpio_to_slice_num(pin);
uint32_t clock_freq = clock_get_hz(clk_sys);
uint32_t top = clock_freq / (frequency * 4) - 1;
pwm_set_wrap(slice_num, top);
set_pwm_duty_cycle(pin, 50, top); // Ciclo de trabalho de 50%
sleep_ms(duration_ms);
set_pwm_duty_cycle(pin, 0, top); // Desliga o som
sleep_ms(50); // Breve pausa entre os sons
}
void setup_all(void) {
pwm_init_buzzer(BUZZER_PIN); // Inicializa o buzzer
gpio_init(DHT_PIN); // Inicializa o GPIO para o sensor
gpio_set_dir(DHT_PIN, GPIO_IN); // Define o GPIO como entrada
i2c_init(I2C_PORT, 400 * 1000); // Configura I2C para 400 kHz
gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(SDA_PIN);
gpio_pull_up(SCL_PIN);
ssd1306_init(I2C_PORT); // Inicializa o display OLED
ssd1306_clear();
}
void display_data(float temperature, float humidity, const char* status_message) {
char buffer[64]; // Um buffer para armazenar as strings formatadas
// Exibir "Embarcatech" no topo da tela
snprintf(buffer, sizeof(buffer), "Embarcatech");
ssd1306_clear(); // Limpa a tela
ssd1306_draw_string(0, 0, buffer, true); // Exibe "Embarcatech" no topo
// Exibir a temperatura
snprintf(buffer, sizeof(buffer), "Temperatura: %.2f°C", temperature);
ssd1306_draw_string(0, 16, buffer, true); // Exibe a temperatura
// Exibir a umidade
snprintf(buffer, sizeof(buffer), "Umidade: %.2f%%", humidity);
ssd1306_draw_string(0, 32, buffer, true); // Exibe a umidade
// Exibir a mensagem de status passada como parâmetro
snprintf(buffer, sizeof(buffer), "%s", status_message);
ssd1306_draw_string(0, 48, buffer, true); // Exibe a mensagem de status
ssd1306_update(I2C_PORT); // Atualiza o display
}
const char* get_status_message(float temperature, float humidity) {
if (temperature > 30.0f && humidity < 40.0f) {
beep(BUZZER_PIN, 500, 1000); // Som mais longo e grave
return "Temp alta e Umid baixa!";
} else if (temperature > 30.0f) {
beep(BUZZER_PIN, 1000, 500); // Som moderado
return "Temperatura alta!";
} else if (humidity < 40.0f) {
beep(BUZZER_PIN, 1500, 300); // Som mais agudo e breve
return "Umidade baixa!";
}
return "Normal"; // Retorna "Normal" caso não haja alerta
}
int main() {
stdio_init_all(); // Inicializa o sistema padrão de entrada/saída
setup_all();
float temperature = 0.0f;
float humidity = 0.0f;
while (1) {
// Tenta ler os valores do DHT22
int result = dht22_read(DHT_PIN, &temperature, &humidity);
if (result == DHT22_OK) {
// Mostra os valores no console
printf("Temperatura: %.2f°C, Umidade: %.2f%%\n", temperature, humidity);
const char* status_message = get_status_message(temperature, humidity);
// Exibe os dados no LCD
display_data(temperature, humidity, status_message);
} else {
// Mostra uma mensagem de erro no console
printf("Falha ao ler o sensor DHT22. Código de erro: %d\n", result);
}
sleep_ms(2000); // Aguarda 2 segundos antes da próxima leitura
}
return 0;
}