#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "hardware/gpio.h"
#include <string.h> // Inclui a biblioteca padrão de manipulação de strings para funções como snprintf.
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#define LED_G_PIN 11
#define LED_B_PIN 12
#define LED_R_PIN 13
#define BTN_A_PIN 5
#define BTN_B_PIN 6
#define TCP_SERVER "tcpbin.com"
#define TCP_PORT 4242
// Definindo pinos e configurações de hardware
const uint8_t pir_pin = 15; // Define o pino GPIO 15 como o pino de entrada para o sensor PIR.
// Estado do Sensor
int estado_sensor = 0;
int estado_botaoa = 0;
int estado_botaob = 0;
char *message;
// Variável para armazenar o último estado do sensor PIR
bool last_motion_state = false; // Armazena o último estado do sensor PIR (movimento detectado ou não).
void set_leds(bool green, bool blue, bool red) {
gpio_put(LED_G_PIN, green);
gpio_put(LED_B_PIN, blue);
gpio_put(LED_R_PIN, red);
}
void inicia_leds() {
// Inicializa os pinos dos LEDs e configura como saída
gpio_init(LED_G_PIN);
gpio_set_dir(LED_G_PIN, GPIO_OUT);
gpio_init(LED_B_PIN);
gpio_set_dir(LED_B_PIN, GPIO_OUT);
gpio_init(LED_R_PIN);
gpio_set_dir(LED_R_PIN, GPIO_OUT);
}
void inicia_botoes() {
// Inicializa os pinos dos botões e configura como entrada com pull-up
gpio_init(BTN_A_PIN);
gpio_set_dir(BTN_A_PIN, GPIO_IN);
gpio_pull_down(BTN_A_PIN);
gpio_init(BTN_B_PIN);
gpio_set_dir(BTN_B_PIN, GPIO_IN);
gpio_pull_down(BTN_B_PIN);
}
static struct tcp_pcb *tcp_client_pcb;
// Callback for when data is received
err_t tcp_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
if (p == NULL) {
printf("Connection closed by server.\n");
tcp_close(tpcb);
return ERR_OK;
}
// char buffer[128];
char buffer[2048];
pbuf_copy_partial(p, buffer, p->len, 0);
buffer[p->len] = '\0';
printf("Received: %s\n", buffer);
pbuf_free(p);
return ERR_OK;
}
// Callback for when the connection is established
err_t tcp_connect_callback(void *arg, struct tcp_pcb *tpcb, err_t err) {
if (err != ERR_OK) {
printf("Failed to connect to server.\n");
return err;
}
printf("Connected to server.\n");
if (estado_sensor >= 1) {
message = "Movimento detectado! Alerta ativado.\n";
tcp_write(tpcb, message, strlen(message), TCP_WRITE_FLAG_COPY);
tcp_recv(tpcb, tcp_recv_callback);
} else {
if (estado_sensor <= 0) {
message = "Sem movimento. Alerta desativado.\n";
tcp_write(tpcb, message, strlen(message), TCP_WRITE_FLAG_COPY);
tcp_recv(tpcb, tcp_recv_callback);
}
}
if (estado_botaoa >= 1) {
message = "O status do Botao A foi ativado (1).\n";
} else {
message = "O status do Botao A foi desativado (0).\n";
}
tcp_write(tpcb, message, strlen(message), TCP_WRITE_FLAG_COPY);
tcp_recv(tpcb, tcp_recv_callback);
estado_botaoa = 0;
if (estado_botaob >= 1) {
message = "O status do Botao B foi ativado (1).\n";
} else {
message = "O status do Botao B foi desativado (0).\n";
}
tcp_write(tpcb, message, strlen(message), TCP_WRITE_FLAG_COPY);
tcp_recv(tpcb, tcp_recv_callback);
estado_botaob = 0;
return ERR_OK;
}
// DNS callback function
static void dns_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) {
if (ipaddr == NULL) {
printf("Failed to resolve DNS for %s\n", name);
return;
}
printf("Resolved %s to %s\n", name, ipaddr_ntoa(ipaddr));
tcp_connect(tcp_client_pcb, ipaddr, TCP_PORT, tcp_connect_callback);
}
void print_network_info() {
struct netif *netif = netif_list;
printf("Network interface: %c%c\n", netif->name[0], netif->name[1]);
printf("IP Address: %s\n", ip4addr_ntoa(netif_ip4_addr(netif)));
printf("Netmask: %s\n", ip4addr_ntoa(netif_ip4_netmask(netif)));
printf("Gateway: %s\n", ip4addr_ntoa(netif_ip4_gw(netif)));
}
void connect_to_server() {
tcp_client_pcb = tcp_new();
if (!tcp_client_pcb) {
printf("Failed to create TCP PCB.\n");
return;
}
printf("Resolving %s...\n", TCP_SERVER);
ip_addr_t server_ip;
err_t err = dns_gethostbyname(TCP_SERVER, &server_ip, dns_callback, NULL);
if (err == ERR_OK) {
printf("DNS resolved immediately: %s\n", ipaddr_ntoa(&server_ip));
tcp_connect(tcp_client_pcb, &server_ip, TCP_PORT, tcp_connect_callback);
} else if (err != ERR_INPROGRESS) {
printf("DNS resolution failed: %d\n", err);
tcp_close(tcp_client_pcb);
}
}
void conectar_wifi() {
if (cyw43_arch_init()) { // Inicializa o hardware Wi-Fi.
printf("Erro ao inicializar o Wi-Fi.\n"); // Se falhar, imprime uma mensagem de erro.
conectar_wifi(); // Retorna 1 para indicar erro.
}
cyw43_arch_enable_sta_mode(); // Habilita o modo estação (STA) para conectar-se a uma rede Wi-Fi.
// Conecta ao Wi-Fi
const char *ssid = "Wokwi-GUEST"; // Define o nome da rede Wi-Fi.
const char *password = ""; // Define a senha da rede Wi-Fi.
printf("Conectando ao Wi-Fi...\n"); // Imprime uma mensagem indicando que está tentando conectar ao Wi-Fi.
if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 10000)) { // Tenta conectar ao Wi-Fi.
printf("Erro ao conectar ao Wi-Fi.\n"); // Se falhar, imprime uma mensagem de erro.
conectar_wifi(); // Retorna 1 para indicar erro.
}
printf("Conectado ao Wi-Fi.\n"); // Imprime uma mensagem indicando que a conexão foi bem-sucedida.
}
void botoes(void) {
while (true) {
if (gpio_get(BTN_A_PIN) && gpio_get(BTN_B_PIN)) {
set_leds(1, 1, 1); // Acende todos os LEDs
estado_botaoa = 1;
estado_botaob = 1;
break;
} else if (gpio_get(BTN_A_PIN)) {
set_leds(1, 0, 0); // Acende apenas o LED verde
estado_botaoa = 1;
break;
} else if (gpio_get(BTN_B_PIN)) {
set_leds(0, 1, 0); // Acende apenas o LED azul
estado_botaob = 1;
break;
} else {
set_leds(0, 0, 1); // Acende apenas o LED vermelho
// estado_botaoa = 0;
// estado_botaob = 0;
break;
}
sleep_ms(100);
//return;
}
}
int main() {
//printf("Vou inicializar o Wi-Fi.\n");
// Inicializa a comunicação serial
stdio_init_all(); // Inicializa a comunicação serial para permitir a saída de texto via USB.
/*
// Inicializa o Wi-Fi (para o Raspberry Pi Pico W)
if (cyw43_arch_init()) { // Inicializa o hardware Wi-Fi.
printf("Erro ao inicializar o Wi-Fi.\n"); // Se falhar, imprime uma mensagem de erro.
return 1; // Retorna 1 para indicar erro.
}
cyw43_arch_enable_sta_mode(); // Habilita o modo estação (STA) para conectar-se a uma rede Wi-Fi.
// Conecta ao Wi-Fi
const char *ssid = "SUA_REDE_WIFI"; // Define o nome da rede Wi-Fi.
const char *password = "SUA_SENHA_WIFI"; // Define a senha da rede Wi-Fi.
printf("Conectando ao Wi-Fi...\n"); // Imprime uma mensagem indicando que está tentando conectar ao Wi-Fi.
if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 10000)) { // Tenta conectar ao Wi-Fi.
printf("Erro ao conectar ao Wi-Fi.\n"); // Se falhar, imprime uma mensagem de erro.
return 1; // Retorna 1 para indicar erro.
}
printf("Conectado ao Wi-Fi.\n"); // Imprime uma mensagem indicando que a conexão foi bem-sucedida.
*/
inicia_leds();
inicia_botoes();
conectar_wifi();
print_network_info();
// Configura os pinos
gpio_init(pir_pin); // Inicializa o pino do sensor PIR.
gpio_set_dir(pir_pin, GPIO_IN); // Configura o pino do sensor PIR como entrada.
printf("Sistema iniciado.\n"); // Imprime uma mensagem indicando que o sistema foi iniciado.
//botoes();
while (true) { // Loop infinito para monitorar continuamente o sensor PIR.
bool current_motion_state = gpio_get(pir_pin); // Lê o estado atual do sensor PIR.
if (current_motion_state != last_motion_state) { // Verifica se o estado do sensor mudou.
if (current_motion_state) { // Se o movimento for detectado.
// printf("Movimento detectado! Alerta ativado.\n"); // Imprime uma mensagem.
estado_sensor = 1;
// printf("O estado do sensor eh = %d\n", estado_sensor);
connect_to_server();
} else { // Se o movimento cessar.
// printf("Sem movimento. Alerta desativado.\n"); // Imprime uma mensagem.
// estado_sensor = 0;
// printf("O estado do sensor eh = %d\n", estado_sensor);
// connect_to_server();
}
// printf("O estado do botao A eh = %d\n", estado_botaoa);
// printf("O estado do botao B eh = %d\n", estado_botaob);
// estado_botaoa = 0;
// estado_botaob = 0;
last_motion_state = current_motion_state; // Atualiza o último estado do sensor.
}
// Se o movimento persistir, mantenha o LED ligado e toque o buzzer em intervalos
if (current_motion_state) { // Se o movimento for detectado.
//sleep_ms(600); // Aguarda 600ms antes de tocar novamente.
}
botoes();
sleep_ms(1000); // Aguarda 100ms antes de verificar novamente o estado do sensor.
}
return 0; // Retorna 0 (nunca será alcançado devido ao loop infinito).
}