#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/pwm.h"
#include "hardware/i2c.h"
#include <math.h>
// Definições de pinos e parâmetros
#define POT_PIN 26 // Pino do sensor de umidade do solo
#define TEMP_SENSOR_PIN 27 // Pino do sensor de temperatura NTC
#define LDR_PIN 28 // Pino do sensor de luminosidade (LDR)
#define MOTOR_PIN 15 // Pino do PWM para o motor
#define IRRIGATION_PIN 14 // Pino de controle da irrigação
#define ADC_MAX 4095 // Resolução do ADC (12 bits)
#define VCC 3.3 // Tensão de referência
#define R_SERIES 10000.0 // Resistor em série (10kΩ)
#define BETA 3950.0 // Coeficiente beta do termistor
#define T0 298.15 // Temperatura de referência (25°C em Kelvin)
#define R0 10000.0 // Resistência a 25°C (10kΩ)
#define DS1307_ADDR 0x68 // Endereço I²C do DS1307
#define I2C_PORT i2c0 // Porta I²C
#define PIN_SDA 4 // Pino SDA
#define PIN_SCL 5 // Pino SCL
// Parâmetros de controle
const float UMIDADE_MIN = 70.0; // Umidade mínima para irrigação (%)
const float TEMP_REF = 25.0; // Temperatura de referência (°C)
const float TEMP_FATOR = 0.04; // 4% de aumento por grau acima de 25°C
// Função para configurar o horário no DS1307
uint8_t dec_to_bcd(uint8_t val) {
return ((val / 10) << 4) | (val % 10);
}
uint8_t bcd_to_dec(uint8_t val) {
return ((val >> 4) * 10) + (val & 0x0F);
}
void ds1307_set_time(uint8_t hour, uint8_t min, uint8_t sec) {
uint8_t data[4];
data[0] = 0x00;
data[1] = dec_to_bcd(sec);
data[2] = dec_to_bcd(min);
data[3] = dec_to_bcd(hour);
i2c_write_blocking(I2C_PORT, DS1307_ADDR, data, 4, false);
printf("Hora configurada: %02d:%02d:%02d\n", hour, min, sec);
}
void ds1307_read_time(uint8_t *hour, uint8_t *min, uint8_t *sec) {
uint8_t data[1] = {0x00};
uint8_t buffer[3];
i2c_write_blocking(I2C_PORT, DS1307_ADDR, data, 1, true);
i2c_read_blocking(I2C_PORT, DS1307_ADDR, buffer, 3, false);
*sec = bcd_to_dec(buffer[0] & 0x7F);
*min = bcd_to_dec(buffer[1]);
*hour = bcd_to_dec(buffer[2] & 0x3F);
}
void setup_i2c() {
i2c_init(I2C_PORT, 100 * 1000);
gpio_set_function(PIN_SDA, GPIO_FUNC_I2C);
gpio_set_function(PIN_SCL, GPIO_FUNC_I2C);
gpio_pull_up(PIN_SDA);
gpio_pull_up(PIN_SCL);
sleep_ms(1000);
}
void setup_pwm(uint pin) {
gpio_set_function(pin, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(pin);
pwm_config config = pwm_get_default_config();
pwm_config_set_clkdiv(&config, 488.0f);
pwm_config_set_wrap(&config, 255);
pwm_init(slice_num, &config, true);
pwm_set_gpio_level(pin, 0);
}
// Função para ler a umidade do solo
float read_soil_moisture() {
adc_select_input(0);
uint16_t raw = adc_read();
return (raw * 100.0f) / ADC_MAX;
}
// Função para ler a temperatura
float read_temperature() {
adc_select_input(1);
float voltage = (adc_read() * VCC) / ADC_MAX;
float resistance = (R_SERIES * voltage) / (VCC - voltage);
float temp_k = 1.0 / (log(resistance / R0) / BETA + 1.0 / T0);
return temp_k - 273.15;
}
// Função para ler a luminosidade
float read_luminosity() {
adc_select_input(2);
uint16_t raw = adc_read();
return (raw * VCC) / ADC_MAX; // Retorna a tensão lida
}
int main() {
stdio_init_all();
adc_init();
adc_gpio_init(POT_PIN);
adc_gpio_init(TEMP_SENSOR_PIN);
adc_gpio_init(LDR_PIN);
gpio_init(IRRIGATION_PIN);
gpio_set_dir(IRRIGATION_PIN, GPIO_OUT);
setup_pwm(MOTOR_PIN);
setup_i2c();
ds1307_set_time(6, 30, 45);
while (true) {
float umidade = read_soil_moisture();
float temp = read_temperature();
float luminosity = read_luminosity();
uint8_t duty = 0;
uint8_t hour, min, sec;
ds1307_read_time(&hour, &min, &sec);
if (hour >= 6 && hour < 8) {
gpio_put(IRRIGATION_PIN, 1);
printf("Irrigação: LIGADA\n");
} else {
gpio_put(IRRIGATION_PIN, 0);
printf("Irrigação: DESLIGADA\n");
}
if (umidade < UMIDADE_MIN && hour >= 6 && hour < 8) {
float deficit = UMIDADE_MIN - umidade;
float base_duty = (deficit / UMIDADE_MIN) * 255.0f;
if (temp > TEMP_REF) {
float temp_ajuste = 1.0 + (temp - TEMP_REF) * TEMP_FATOR;
base_duty *= temp_ajuste;
}
duty = (uint8_t)fminf(base_duty, 255.0f);
}
if(luminosity <= 0.04){
printf("\nAtenção! Luminosidade Excessiva 🚨\n");
}
pwm_set_gpio_level(MOTOR_PIN, duty);
printf("Hora: %02d:%02d:%02d | Umidade: %.1f%% | Temp: %.1f°C | PWM: %d\n",
hour, min, sec, umidade, temp, duty);
sleep_ms(5000);
}
}