#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
#include "lwip/dns.h"
#include "lwip/tcp.h"
#include "hardware/adc.h"
#include "hardware/clocks.h"
#include "hardware/pwm.h"
#include <string.h>
#include <stdio.h>
#define WIFI_SSID "Sofia_2G"
#define WIFI_PASS "......"
#define THINGSPEAK_HOST "api.thingspeak.com"
#define THINGSPEAK_API_KEY "....."
#define NUM_READINGS 10
#define LED_VERDE 11
#define LED_VERMELHO 13
#define BUZZER_PIN 21
#define FREQUENCIA_BAIXA 440
#define FREQUENCIA_ALTA 660
#define DURACAO_NOTA 850
float readings[NUM_READINGS] = {0};
int idx = 0;
int count = 0;
struct tcp_pcb *pcb_global;
// 🔹 Configurar o buzzer
void configurar_buzzer(int pin)
{
gpio_set_function(pin, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(pin);
pwm_config configuracao = pwm_get_default_config();
pwm_config_set_clkdiv(&configuracao, 1.0);
pwm_init(slice_num, &configuracao, true);
pwm_set_gpio_level(pin, 0);
}
// 🔹 Ajustar a frequência do buzzer
void ajustar_frequencia(int pin, int freq)
{
uint slice_num = pwm_gpio_to_slice_num(pin);
uint32_t clock_div = clock_get_hz(clk_sys) / (freq * 5000);
pwm_set_wrap(slice_num, 5000 - 1);
pwm_set_clkdiv(slice_num, clock_div);
}
// 🔹 Emitir som no buzzer
void emitir_som(int pin, int freq, int duracao_ms)
{
ajustar_frequencia(pin, freq);
pwm_set_gpio_level(pin, 2500);
sleep_ms(duracao_ms);
pwm_set_gpio_level(pin, 0);
}
// 🔹 Calcular a média das leituras de temperatura
float calcular_media()
{
float soma = 0;
for (int i = 0; i < NUM_READINGS; i++)
{
soma += readings[i];
}
return soma / NUM_READINGS;
}
// 🔹 Callback para receber a resposta do ThingSpeak
static err_t thingspeak_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
if (p == NULL)
{
printf("Conexão fechada pelo servidor\n");
tcp_close(tpcb);
return ERR_OK;
}
char *response = (char *)p->payload;
char *first_line = strtok(response, "\r\n");
printf("Resposta do ThingSpeak: %s\n\n", first_line);
pbuf_free(p);
tcp_close(tpcb);
return ERR_OK;
}
// 🔹 Callback ao conectar ao ThingSpeak
static err_t thingspeak_connected_callback(void *arg, struct tcp_pcb *tpcb, err_t err)
{
if (err != ERR_OK)
{
printf("Erro ao conectar ao ThingSpeak: %d\n", err);
return err;
}
float temperatura = *(float *)arg;
char post_data[150];
snprintf(post_data, sizeof(post_data), "api_key=%s&field1=%.2f&field2=%d&field3=%d",
THINGSPEAK_API_KEY, temperatura, gpio_get(LED_VERDE), gpio_get(LED_VERMELHO));
char request[512];
snprintf(request, sizeof(request),
"POST /update HTTP/1.1\r\n"
"Host: " THINGSPEAK_HOST "\r\n"
"User-Agent: PicoWClient/1.0\r\n"
"Connection: close\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n\r\n"
"%s",
(int)strlen(post_data), post_data);
printf("Enviando dados para ThingSpeak...\n");
tcp_write(tpcb, request, strlen(request), TCP_WRITE_FLAG_COPY);
tcp_output(tpcb);
tcp_recv(tpcb, thingspeak_recv_callback);
return ERR_OK;
}
// 🔹 Callback de resolução de DNS
static void dns_callback(const char *name, const ip_addr_t *ipaddr, void *arg)
{
if (ipaddr == NULL)
{
printf("Erro ao resolver o DNS do ThingSpeak.\n");
return;
}
struct tcp_pcb *pcb = tcp_new();
if (!pcb)
{
printf("Erro ao criar PCB para ThingSpeak\n");
return;
}
float *temp = (float *)arg;
pcb_global = pcb;
tcp_arg(pcb, temp);
tcp_connect(pcb, ipaddr, 80, thingspeak_connected_callback);
}
// 🔹 Enviar dados ao ThingSpeak
void send_to_thingspeak(float temperatura)
{
printf("Resolvendo DNS do ThingSpeak...\n");
ip_addr_t thingspeak_ip;
err_t err = dns_gethostbyname(THINGSPEAK_HOST, &thingspeak_ip, dns_callback, &temperatura);
if (err == ERR_OK)
{
dns_callback(THINGSPEAK_HOST, &thingspeak_ip, &temperatura);
}
}
// 🔹 Função principal
int main()
{
stdio_init_all();
sleep_ms(10000);
printf("Iniciando...\n");
if (cyw43_arch_init())
{
printf("Erro ao inicializar o Wi-Fi\n");
return 1;
}
cyw43_arch_enable_sta_mode();
printf("Conectando ao Wi-Fi...\n");
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASS, CYW43_AUTH_WPA2_AES_PSK, 10000))
{
printf("Falha ao conectar ao Wi-Fi\n");
return 1;
}
else
{
printf("Wi-Fi conectado!\n");
}
adc_init();
adc_set_temp_sensor_enabled(true);
adc_select_input(4);
gpio_init(LED_VERDE);
gpio_set_dir(LED_VERDE, GPIO_OUT);
gpio_init(LED_VERMELHO);
gpio_set_dir(LED_VERMELHO, GPIO_OUT);
configurar_buzzer(BUZZER_PIN);
while (true)
{
uint16_t raw = adc_read();
float conversion_factor = 3.3f / (1 << 12);
float result = raw * conversion_factor;
float temp = 27 - (result - 0.706) / 0.001721;
readings[idx] = temp;
idx = (idx + 1) % NUM_READINGS;
count++;
if (count == NUM_READINGS)
{
float media_temp = calcular_media();
printf("Média da temperatura: %.2f C\n", media_temp);
send_to_thingspeak(media_temp);
count = 0;
if (media_temp >= 29.0)
{
gpio_put(LED_VERDE, 0);
gpio_put(LED_VERMELHO, 1);
emitir_som(BUZZER_PIN, FREQUENCIA_BAIXA, DURACAO_NOTA);
emitir_som(BUZZER_PIN, FREQUENCIA_ALTA, DURACAO_NOTA);
}
else
{
gpio_put(LED_VERDE, 1);
gpio_put(LED_VERMELHO, 0);
}
}
sleep_ms(1000);
}
}