// Os valores calculados são enviados para o ThingSpeak
// Link: https://thingspeak.mathworks.com/channels/2818611
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#include "hardware/gpio.h"
#include "dht.h"
#include "hardware/adc.h"
// Config para a conexão do wifi
#define WIFI_SSID "Wokwi-GUEST" // Nome da rede Wi-Fi
#define WIFI_PASSWORD "" // Senha da rede Wi-Fi
// Config para o Thingspeak
#define THINGSPEAK_HOST "api.thingspeak.com"
#define THINGSPEAK_PORT 80
#define API_KEY "0DERZILACAL3WRV2" // API Key do ThingSpeak
// Config para os sensores
#define DHT_PIN 20 // Pino do sensor DHT
#define POT1_PIN 26 // Pino do "Sensor de Tensão" ( Potenciometro / ADC0 )
#define POT2_PIN 27 // Pino do "Sensor de Corrente" ( Potenciometro / ADC1)
#define LIGAR_PIN 14 // Pino que mostra se esta ligado ou desligado
// Para os calculos da Potencia Media, Corrente RMS e Tensao RMS
#define N 10 // Número de amostras para o somatório
// Global
static struct tcp_pcb *tcp_client_pcb;
char request[256]; // Buffer para o HTTP GET
float valor_temp = 0;
float valor_umid = 0;
float valor_tensao = 0;
float valor_corrente = 0;
int valor_ligado = 0;
float valor_potencia = 0;
float tensao_rms = 0.0;
float corrente_rms = 0.0;
float potencia_media = 0.0;
// Callback quando dados são recebidos
err_t tcp_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
if (p == NULL) {
printf("Conexão encerrada pelo servidor.\n");
tcp_close(tpcb);
return ERR_OK;
}
char buffer[512]; // Buffer maior para evitar overflow
size_t copy_len = (p->len < sizeof(buffer) - 1) ? p->len : sizeof(buffer) - 1;
pbuf_copy_partial(p, buffer, copy_len, 0);
buffer[copy_len] = '\0';
//printf("Recebido: %s\n", buffer);
pbuf_free(p);
return ERR_OK;
}
// Callback quando a conexão é estabelecida
err_t tcp_connect_callback(void *arg, struct tcp_pcb *tpcb, err_t err) {
if (err != ERR_OK) {
printf("Falha ao conectar ao servidor.\n");
return err;
}
printf("Conectado ao servidor.\n");
// Enviar a requisição HTTP GET ao ThingSpeak com o valor recebido
snprintf(request, sizeof(request),
"GET /update?api_key=%s&field1=%.2f&field2=%.2f&field3=%.2f&field4=%.2f&field5=%d&field6=%.2f HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n\r\n",
API_KEY, valor_temp, valor_umid, valor_tensao, valor_corrente, valor_ligado, valor_potencia, THINGSPEAK_HOST);
tcp_write(tpcb, request, strlen(request), TCP_WRITE_FLAG_COPY);
tcp_output(tpcb);
tcp_recv(tpcb, tcp_recv_callback);
return ERR_OK;
}
// Callback de resolução DNS
static void dns_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) {
if (ipaddr == NULL) {
printf("Falha ao resolver DNS para %s\n", name);
return;
}
printf("Resolvido %s para %s\n", name, ipaddr_ntoa(ipaddr));
tcp_connect(tcp_client_pcb, ipaddr, THINGSPEAK_PORT, tcp_connect_callback);
}
// Configuração do Wi-Fi
void wifi_setup() {
if (cyw43_arch_init()) {
printf("Falha ao inicializar o módulo Wi-Fi.\n");
return;
}
cyw43_arch_enable_sta_mode();
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 10000)) {
printf("Não foi possível encontrar a rede Wi-Fi.\n");
cyw43_arch_poll();
cyw43_arch_deinit();
sleep_ms(1000);
wifi_setup();
}
printf("Wi-Fi conectado com sucesso.\n");
}
// Função para enviar dados ao ThingSpeak
void enviar_para_thingspeak(float temp, float umid, float tensao, float corrente, int ligado, float potencia) {
tcp_client_pcb = tcp_new();
if (!tcp_client_pcb) {
printf("Falha ao criar o TCP PCB.\n");
return;
}
// Atualiza o valor a ser enviado
valor_temp = temp;
valor_umid = umid;
valor_tensao = tensao;
valor_corrente = corrente;
valor_ligado = ligado;
valor_potencia = potencia;
printf("Resolvendo %s...\n", THINGSPEAK_HOST);
ip_addr_t server_ip;
err_t err = dns_gethostbyname(THINGSPEAK_HOST, &server_ip, dns_callback, NULL);
if (err == ERR_OK) {
printf("DNS resolvido imediatamente: %s\n", ipaddr_ntoa(&server_ip));
tcp_connect(tcp_client_pcb, &server_ip, THINGSPEAK_PORT, tcp_connect_callback);
} else if (err != ERR_INPROGRESS) {
printf("Falha na resolução DNS: %d\n", err);
tcp_close(tcp_client_pcb);
}
}
float leitura_do_potenciometro(int id){
adc_select_input(id);
return (adc_read() / 4095.0) * 3.3;
}
void calcular_tudo() {
float somatorio_tensao = 0.0;
float somatorio_corrente = 0.0;
float somatorio_potencia = 0.0;
float tensao = 0;
float corrente = 0;
// Realiza a leitura de N amostras de tensão e corrente
for (int i = 0; i < N; i++) {
// Lê a tensão e a corrente
tensao = leitura_do_potenciometro(0);
corrente = leitura_do_potenciometro(1);
// Multiplica a tensão por 100
tensao = tensao * 100;
// Calcula o quadrado da tensão, corrente e potência instantânea
somatorio_tensao += tensao * tensao;
somatorio_corrente += corrente * corrente;
somatorio_potencia += tensao * corrente;
sleep_ms(10);
}
// Calcula a média dos quadrados e tira a raiz quadrada para o RMS
tensao_rms = sqrt(somatorio_tensao / N);
corrente_rms = sqrt(somatorio_corrente / N);
// Calcula a potência média
potencia_media = somatorio_potencia / N;
}
int main(){
stdio_init_all();
gpio_init(LIGAR_PIN);
gpio_set_dir(LIGAR_PIN, GPIO_IN);
gpio_init(DHT_PIN);
// Inicializa o ADC
adc_init();
adc_gpio_init(POT1_PIN);
adc_gpio_init(POT2_PIN);
wifi_setup(); // Inicializa o Wi-Fi
while(1){
dht_reading reading;
read_from_dht(&reading, DHT_PIN);
calcular_tudo();
// Exibe os valores
printf("Humidity = %.1f%%, Temperature = %.1fC, Tensao RMS = %.2fV, Corrente RMS = %.2fA, Potencia Media = %.2fW, Estado da Maquina (Desligado = 0, Ligado = 1) = %d \n", reading.humidity, reading.temp_celsius, tensao_rms, corrente_rms, potencia_media, gpio_get(LIGAR_PIN));
// Envia a temperatura lida para o ThingSpeak
enviar_para_thingspeak(reading.temp_celsius, reading.humidity, tensao_rms, corrente_rms, gpio_get(LIGAR_PIN), potencia_media);
sleep_ms(30000); // Aguarda 30 segundos por conta do thingspeak
}
}
Sensor de Tensão
Sensor de Corrente
Liga/Desliga
Sensor de Temperatura e Umidade