#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "dht22-pico.h" // Biblioteca do sensor DHT22
#include "hardware/i2c.h"
#define STEMPERATURA_PIN 28 // Define o pino GP28 para Canal ADC2 (sensor de umidade do solo)
const uint LED_PIN = 6;
const uint DHT_PIN = 2;
const uint BOMBA_PIN = 3; // Pino para controle da bomba/solenoide de irrigação
// Estrutura para definir um conjunto fuzzy trapezoidal
typedef struct {
float a, b, c, d; // Parâmetros para funções trapezoidais
} FuzzySet;
// Função de pertinência trapezoidal
float trapezoidalMembership(float x, FuzzySet set) {
if (x <= set.a || x >= set.d)
return 0.0;
else if (x > set.a && x < set.b)
return (x - set.a) / (set.b - set.a);
else if (x >= set.b && x <= set.c)
return 1.0;
else // x > set.c && x < set.d
return (set.d - x) / (set.d - set.c);
}
void blink() {
sleep_ms(50);
gpio_put(LED_PIN, 1);
sleep_ms(50);
gpio_put(LED_PIN, 0);
}
// Funções de pertinência para lógica fuzzy usando a função trapezoidal
float fuzzy_solo(float umidade_solo) {
FuzzySet solo_seco = {0, 0, 30, 50}; // Solo seco
FuzzySet solo_moderado = {30, 50, 70, 90}; // Solo moderado
FuzzySet solo_umido = {70, 90, 100, 100}; // Solo úmido
if (umidade_solo < 30) return trapezoidalMembership(umidade_solo, solo_seco);
else if (umidade_solo >= 30 && umidade_solo <= 70) return trapezoidalMembership(umidade_solo, solo_moderado);
else return trapezoidalMembership(umidade_solo, solo_umido);
}
float fuzzy_umidade_ar(float umidade_ar) {
FuzzySet ar_seco = {0, 0, 40, 60}; // Ar seco
FuzzySet ar_moderado = {40, 60, 80, 90}; // Ar moderado
FuzzySet ar_umido = {80, 90, 100, 100}; // Ar úmido
if (umidade_ar < 40) return trapezoidalMembership(umidade_ar, ar_seco);
else if (umidade_ar >= 40 && umidade_ar <= 80) return trapezoidalMembership(umidade_ar, ar_moderado);
else return trapezoidalMembership(umidade_ar, ar_umido);
}
float fuzzy_temperatura(float temperatura) {
FuzzySet temperatura_frio = {0, 0, 15, 20}; // Temperatura fria
FuzzySet temperatura_agradavel = {15, 20, 30, 35}; // Temperatura agradável
FuzzySet temperatura_quente = {30, 35, 50, 50}; // Temperatura quente
if (temperatura < 15) return trapezoidalMembership(temperatura, temperatura_frio);
else if (temperatura >= 15 && temperatura <= 30) return trapezoidalMembership(temperatura, temperatura_agradavel);
else return trapezoidalMembership(temperatura, temperatura_quente);
}
// Regras de inferência fuzzy
float inferencia(float solo, float ar, float temp) {
float regra1 = solo * ar * temp; // Solo seco E ar seco E temp quente
float regra2 = (1 - solo) * (1 - temp); // Solo úmido OU temp agradável
float regra3 = solo * (1 - ar) * (1 - temp); // Solo seco E ar úmido E temp quente
float regra4 = (1 - solo) * ar * temp; // Solo úmido E ar seco E temp quente
float regra5 = solo * ar * (1 - temp); // Solo seco E ar seco E temp fria
float regra6 = (1 - solo) * (1 - ar); // Solo úmido E ar úmido
// Média ponderada das regras
return (regra1 + regra2 + regra3 + regra4 + regra5 + regra6) / 6.0;
}
// Defuzzificação
float defuzzificar(float resultado_fuzzy) {
return resultado_fuzzy * 100; // Converte para uma escala de 0 a 100%
}
float adc_para_umidade_solo(uint16_t adc_value) {
const uint16_t ADC_SECO = 600; // Ajuste conforme sua calibração
const uint16_t ADC_MOLHADO = 100;
if (adc_value > ADC_SECO) {
adc_value = ADC_SECO;
} else if (adc_value < ADC_MOLHADO) {
adc_value = ADC_MOLHADO;
}
// Certifique-se de que a umidade seja maior quanto menor o valor do ADC (invertido)
float umidade_solo = ((float)(adc_value - ADC_MOLHADO) / (ADC_SECO - ADC_MOLHADO)) * 100.0f;
return umidade_solo; // Agora o valor é inversamente proporcional
}
int main() {
stdio_init_all();
adc_init();
adc_gpio_init(STEMPERATURA_PIN);
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_init(BOMBA_PIN);
gpio_set_dir(BOMBA_PIN, GPIO_OUT);
gpio_put(BOMBA_PIN, 0); // Garante que a bomba está desligada inicialmente
dht_reading dht = dht_init(DHT_PIN);
while (1) {
sleep_ms(2000);
// Leitura do sensor de umidade do solo
adc_select_input(2);
uint16_t adc_value = adc_read();
//float umidade_solo = adc_para_umidade_solo(adc_value);
float umidade_solo = adc_value;
// Leitura do sensor DHT22
uint8_t status = dht_read(&dht);
if (status == DHT_OK) {
float umidade_ar = dht.humidity;
float temperatura = dht.temp_celsius;
// Aplicação da lógica fuzzy
float solo_fuzzy = fuzzy_solo(umidade_solo);
float ar_fuzzy = fuzzy_umidade_ar(umidade_ar);
float temp_fuzzy = fuzzy_temperatura(temperatura);
float resultado_fuzzy = inferencia(solo_fuzzy, ar_fuzzy, temp_fuzzy);
float resultado = defuzzificar(resultado_fuzzy);
// Dentro do loop principal, logo após o cálculo fuzzy
printf("Solo fuzzy: %.2f\n", solo_fuzzy);
printf("Ar fuzzy: %.2f\n", ar_fuzzy);
printf("Temp fuzzy: %.2f\n", temp_fuzzy);
printf("Inferência fuzzy: %.2f\n", resultado_fuzzy);
printf("Defuzzificação: %.2f%%\n", resultado);
// Imprime os resultados na comunicação serial
printf("Umidade do solo: %.2f%%\n", umidade_solo);
printf("Umidade do ar: %.2f%%\n", umidade_ar);
printf("Temperatura: %.2fC\n", temperatura);
printf("Resultado fuzzy: %.2f%%\n", resultado);
// Controle do sistema de irrigação
if (resultado > 50.0) { // Se o resultado fuzzy for maior que 50%, ativa a irrigação
gpio_put(BOMBA_PIN, 1); // Liga a bomba/solenoide
printf("Irrigação ATIVADA\n");
} else {
gpio_put(BOMBA_PIN, 0); // Desliga a bomba/solenoide
printf("Irrigação DESATIVADA\n");
}
// Acende o LED como indicação (opcional)
blink();
} else if (status == DHT_ERR_CHECKSUM) {
printf("Bad data (checksum)\n");
blink();
blink();
} else {
printf("Bad data (NaN)\n");
blink();
blink();
}
}
return 0;
}
Loading
pi-pico-w
pi-pico-w