#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stdlib.h"
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/adc.h"
#include "hardware/gpio.h"
#include "ssd1306.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
// Definições dos pinos
#define I2C_SDA_PIN 14
#define I2C_SCL_PIN 15
#define LED_G_PIN 11
#define BTN_A_PIN 5
#define BTN_B_PIN 6
#define JOY_X_PIN 27
#define JOY_Y_PIN 26
#define JOY_BTN_PIN 22
#define ADC_CHANNEL_0 0 // Canal ADC para o eixo X do joystick
#define ADC_CHANNEL_1 1 // Canal ADC para o eixo Y do joystick
// Config para a conexão do wifi
#define WIFI_SSID "SUA_REDE_WIFI" // Nome da rede Wi-Fi
#define WIFI_PASSWORD "SUA_SENHA" // Senha da rede Wi-Fi
// Config para o Thingspeak
#define THINGSPEAK_HOST "api.thingspeak.com"
#define THINGSPEAK_PORT 80
#define API_KEY "Q69864I9JVW7LER1" // API Key do ThingSpeak
// Global
static struct tcp_pcb *tcp_client_pcb;
char request[256]; // Buffer para o HTTP GET
// Configurações do display OLED
const uint I2C_SDA = I2C_SDA_PIN;
const uint I2C_SCL = I2C_SCL_PIN;
// Buffer do display OLED
uint8_t ssd_buffer[ssd1306_buffer_length];
struct render_area frame_area;
// Estado da luz
int luz_ligada = 0;
int contador_luzes = 0; // Contador de quantas vezes a luz foi acesa
// Função para exibir mensagens no OLED
void display_messages(const char *messages[], int count) {
memset(ssd_buffer, 0, ssd1306_buffer_length); // Limpa o buffer
int y = 0; // Posição vertical inicial
for (int i = 0; i < count; i++) {
ssd1306_draw_string(ssd_buffer, 5, y, (char*)messages[i]); // Desenha cada linha
y += 8; // Move para a próxima linha
}
// Renderiza o conteúdo no display
render_on_display(ssd_buffer, &frame_area);
}
void exibir_instrucoes() {
const char *instrucao[] = {
"Bem vindo",
"A liga desliga",
"B sensor de luz",
"Joystick",
"Sensor de mov.",
"e enviar dados"};
display_messages(instrucao, 6);
}
// 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");
const char *mensagem[] = {"dados enviados", "com sucesso"};
display_messages(mensagem, 2);
sleep_ms(2000);
exibir_instrucoes();
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=%d HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n\r\n",
API_KEY, contador_luzes, 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() {
const char *mensagem[] = {"Conectando", "ao wi fi"};
display_messages(mensagem, 2);
if (cyw43_arch_init()) {
printf("Falha ao inicializar o módulo Wi-Fi.\n");
const char *mensagem2[] = {"Falha", "ao conectar"};
display_messages(mensagem2, 2);
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");
const char *mensagem3[] = {"Rede", "nao encontrada"};
display_messages(mensagem3, 2);
cyw43_arch_poll();
cyw43_arch_deinit();
sleep_ms(1000);
wifi_setup();
}
printf("Wi-Fi conectado com sucesso.\n");
const char *mensagem4[] = {"wi fi", "conectado", "com sucesso"};
display_messages(mensagem4, 3);
sleep_ms(2000);
}
// Função para enviar dados ao ThingSpeak
void enviar_para_thingspeak(int contador) {
const char *mensagem1[] = {"enviando dados", "para o", "Thingspeak"};
display_messages(mensagem1, 3);
sleep_ms(2000);
tcp_client_pcb = tcp_new();
if (!tcp_client_pcb) {
const char *mensagem2[] = {"falha ao", "criar TCP", "PCB"};
display_messages(mensagem2, 3);
printf("Falha ao criar o TCP PCB.\n");
return;
}
// Atualiza o valor a ser enviado
contador_luzes = contador;
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);
}
}
// Função para incrementar o contador quando a luz for acesa
void incrementar_contador() {
contador_luzes++;
printf("A luz foi acesa %d vezes\n", contador_luzes);
}
// Inicializa o display OLED
void init_oled() {
i2c_init(i2c1, 100 * 1000); // Configura a comunicação I2C
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
gpio_pull_up(I2C_SDA);
gpio_pull_up(I2C_SCL);
ssd1306_init(); // Inicializa o display OLED
// Configura a área de renderização
frame_area.start_column = 0;
frame_area.end_column = ssd1306_width - 1;
frame_area.start_page = 0;
frame_area.end_page = ssd1306_n_pages - 1;
calculate_render_area_buffer_length(&frame_area);
// Limpa o display
memset(ssd_buffer, 0, ssd1306_buffer_length);
render_on_display(ssd_buffer, &frame_area);
}
// Função para debounce do botão
bool debounce_button(uint gpio) {
static uint32_t last_ms = 0;
const uint32_t debounce_delay = 50; // Tempo de debounce em milissegundos
if (gpio_get(gpio) == 0) { // Botão pressionado
if (time_us_32() - last_ms > debounce_delay * 1000) {
last_ms = time_us_32() / 1000;
return true; // Retorna verdadeiro apenas uma vez após o debounce
}
} else {
last_ms = 0; // Reseta o tempo se o botão for liberado
}
return false;
}
// Controle da iluminação
void alternar_luz() {
luz_ligada = !luz_ligada;
gpio_put(LED_G_PIN, luz_ligada);
if (luz_ligada) {
incrementar_contador(); // Incrementa o contador quando a luz for acesa
const char *messages[] = {"Luz Acesa", "Ambiente", "Iluminado"};
display_messages(messages, 3);
} else {
const char *messages[] = {"Luz Apagada"};
display_messages(messages, 1);
}
}
// Simula um sensor de luminosidade
void simular_sensor_luminosidade() {
const char *mensagem_avaliacao[] = {"Sensor", "de luminosidade", "Avaliando", "ambiente"};
display_messages(mensagem_avaliacao, 4);
sleep_ms(2000);
// Gera um valor aleatório entre 0 e 100 (simulando um sensor real)
int luminosidade = rand() % 101; // Valor entre 0 e 100
if (luminosidade < 40) { // Considera escuro se for menor que 40
if (!luz_ligada) {
luz_ligada = 1; // Liga a luz
gpio_put(LED_G_PIN, luz_ligada);
incrementar_contador(); // Incrementa o contador quando a luz for acesa
}
const char *mensagem_luz[] = {"Estava escuro", "Luz acesa"};
display_messages(mensagem_luz, 2);
} else { // Ambiente claro
if (luz_ligada) {
luz_ligada = 0; // Desliga a luz
gpio_put(LED_G_PIN, luz_ligada);
}
const char *mensagem_economia[] = {"Esta claro", "Luz apagada", "Economia", "de energia"};
display_messages(mensagem_economia, 4);
}
}
// Simula um sensor de movimento
void simular_sensor_movimento() {
const char *messages[] = {"Sensor", "de movimento", "detectado"};
display_messages(messages, 3);
sleep_ms(2000);
if (luz_ligada) {
const char *messagem_luz_acesa[] = {"Luz acesa", "Desligando em", "5 segundos"};
display_messages(messagem_luz_acesa, 3);
sleep_ms(5000);
gpio_put(LED_G_PIN, !luz_ligada);
luz_ligada = 0;
const char *messagem_luz_apagada[] = {"Sem movimentos", "no ambiente", "luz apagada"};
display_messages(messagem_luz_apagada, 3);
} else {
luz_ligada = 1; // Liga a luz
gpio_put(LED_G_PIN, luz_ligada);
incrementar_contador(); // Incrementa o contador quando a luz for acesa
const char *messagem_luz_acesa[] = {"Luz acesa", "Desligando em", "5 segundos"};
display_messages(messagem_luz_acesa, 3);
sleep_ms(5000);
gpio_put(LED_G_PIN, !luz_ligada);
luz_ligada = 0;
const char *messagem_luz_apagada[] = {"Sem movimentos", "no ambiente", "luz apagada"};
display_messages(messagem_luz_apagada, 3);
}
}
int main() {
printf("Iniciando o programa...\n");
stdio_init_all();
gpio_init(LED_G_PIN);
gpio_set_dir(LED_G_PIN, GPIO_OUT);
// Configuração do botão do joystick
gpio_init(JOY_BTN_PIN);
gpio_set_dir(JOY_BTN_PIN, GPIO_IN);
gpio_pull_up(JOY_BTN_PIN);
// Configuração dos botões A e B
gpio_init(BTN_A_PIN);
gpio_set_dir(BTN_A_PIN, GPIO_IN);
gpio_pull_up(BTN_A_PIN);
gpio_init(BTN_B_PIN);
gpio_set_dir(BTN_B_PIN, GPIO_IN);
gpio_pull_up(BTN_B_PIN);
adc_init();
adc_gpio_init(JOY_Y_PIN);
adc_gpio_init(JOY_X_PIN);
// Inicialização do OLED
init_oled();
wifi_setup(); // Inicializa o Wi-Fi
// Exibe instruções iniciais
exibir_instrucoes();
while (true) {
if (!gpio_get(BTN_A_PIN)) {
alternar_luz();
sleep_ms(500);
}
if (!gpio_get(BTN_B_PIN)) {
simular_sensor_luminosidade();
sleep_ms(500);
}
if (debounce_button(JOY_BTN_PIN)) {
enviar_para_thingspeak(contador_luzes);
}
adc_select_input(1);
uint adc_y_raw = adc_read();
adc_select_input(0);
uint adc_x_raw = adc_read();
if (adc_x_raw > 3500 || adc_x_raw < 500 || adc_y_raw > 3500 || adc_y_raw < 500) {
simular_sensor_movimento();
sleep_ms(500);
}
}
return 0;
}
Loading
pi-pico-w
pi-pico-w
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
bz1:1
bz1:2
bz2:1
bz2:2
mic1:1
mic1:2
joystick1:VCC
joystick1:VERT
joystick1:HORZ
joystick1:SEL
joystick1:GND
Loading
ssd1306
ssd1306
rgb1:VDD
rgb1:DOUT
rgb1:VSS
rgb1:DIN
rgb2:VDD
rgb2:DOUT
rgb2:VSS
rgb2:DIN
rgb3:VDD
rgb3:DOUT
rgb3:VSS
rgb3:DIN
rgb4:VDD
rgb4:DOUT
rgb4:VSS
rgb4:DIN
rgb5:VDD
rgb5:DOUT
rgb5:VSS
rgb5:DIN
rgb6:VDD
rgb6:DOUT
rgb6:VSS
rgb6:DIN
rgb7:VDD
rgb7:DOUT
rgb7:VSS
rgb7:DIN
rgb8:VDD
rgb8:DOUT
rgb8:VSS
rgb8:DIN
rgb9:VDD
rgb9:DOUT
rgb9:VSS
rgb9:DIN
rgb10:VDD
rgb10:DOUT
rgb10:VSS
rgb10:DIN
rgb11:VDD
rgb11:DOUT
rgb11:VSS
rgb11:DIN
rgb12:VDD
rgb12:DOUT
rgb12:VSS
rgb12:DIN
rgb13:VDD
rgb13:DOUT
rgb13:VSS
rgb13:DIN
rgb14:VDD
rgb14:DOUT
rgb14:VSS
rgb14:DIN
rgb15:VDD
rgb15:DOUT
rgb15:VSS
rgb15:DIN
rgb16:VDD
rgb16:DOUT
rgb16:VSS
rgb16:DIN
rgb17:VDD
rgb17:DOUT
rgb17:VSS
rgb17:DIN
rgb18:VDD
rgb18:DOUT
rgb18:VSS
rgb18:DIN
rgb19:VDD
rgb19:DOUT
rgb19:VSS
rgb19:DIN
rgb21:VDD
rgb21:DOUT
rgb21:VSS
rgb21:DIN
rgb22:VDD
rgb22:DOUT
rgb22:VSS
rgb22:DIN
rgb23:VDD
rgb23:DOUT
rgb23:VSS
rgb23:DIN
rgb24:VDD
rgb24:DOUT
rgb24:VSS
rgb24:DIN
rgb25:VDD
rgb25:DOUT
rgb25:VSS
rgb25:DIN
rgb20:VDD
rgb20:DOUT
rgb20:VSS
rgb20:DIN
rgb26:R
rgb26:COM
rgb26:G
rgb26:B
r1:1
r1:2