/*Residência Tecnológica em Software Embarcado - EMBARCATECH
Tarefa 13 - Aplicação Eletrônica Básica
Aluno: Antonio José Portela de Jesus Santos
Matrícula: 20251RSE.MTC0006
VERSÃO SDK UTILIZADA - 2.1.1
Questão 1 - Você deverá criar um sistema embarcado utilizando o Raspberry de
forma simulada com Wokwi, capaz de:
Detectar aumento de temperatura ambiente com o sensor DHT-22;
Verificar queda de luminosidade com o sensor LDR;
Identificar presença de gás/fumaça com sensor MQ-2;
Responder com atuadores específicos a cada evento monitorado,
de forma individual ou combinada.
*/
//Declaração de bibliotecas
#include "pico/stdlib.h"
#include <stdio.h>
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "hardware/timer.h"
//Definição das GPIO utilizadas baseado no PinOut da BitDogLab
#define DHT_PIN 22
#define VIBRACALL_PIN 21
#define IR_PIN 20
#define LDR_PIN 28
#define MQ2_PIN 27
#define RELE_PIN 18
//Definição de constantes e variáveis globais
const float conversion_factor = 3.3f / (1 << 12);
volatile bool temp_flag = true;
volatile bool ldr_flag = true;
volatile bool mq2_flag = true;
//Definicao do protótipo das funções
bool read_dht22(float *temperature, float *humidity);
void ldr_read(float *voltage_ldr);
void mq2_read(float *voltage_mq2);
void control_vibracall(float *temperature);
void control_led_ir(float *voltage_ldr);
void control_rele(float *voltage_mq2);
bool alarme_callback_1(repeating_timer_t *t);
bool alarme_callback_2(repeating_timer_t *t);
bool alarme_callback_3(repeating_timer_t *t);
//Função MAIN
void main() {
stdio_init_all();
adc_init();
adc_gpio_init(LDR_PIN);
adc_gpio_init(MQ2_PIN);
gpio_init(VIBRACALL_PIN);
gpio_set_dir(VIBRACALL_PIN, GPIO_OUT);
gpio_put(VIBRACALL_PIN, 0);
gpio_init(IR_PIN);
gpio_set_dir(IR_PIN, GPIO_OUT);
gpio_put(IR_PIN, 0);
gpio_init(RELE_PIN);
gpio_set_dir(RELE_PIN, GPIO_OUT);
gpio_put(RELE_PIN, 0);
static repeating_timer_t timer1, timer2, timer3;
add_repeating_timer_ms(2000, alarme_callback_1, NULL, &timer1);
add_repeating_timer_ms(500, alarme_callback_2, NULL, &timer2);
add_repeating_timer_ms(500, alarme_callback_3, NULL, &timer3);
printf("Aplicação dos sensores DHT22, LDR e MQ2:\n");
float temperature, humidity, voltage_ldr, voltage_mq2;
while (true) {
if(temp_flag==true){
temp_flag=false;
read_dht22(&temperature, &humidity);
control_vibracall(&temperature);
}
if(ldr_flag==true){
ldr_flag=false;
ldr_read(&voltage_ldr);
control_led_ir(&voltage_ldr);
}
if(mq2_flag==true){
mq2_flag=false;
mq2_read(&voltage_mq2);
control_rele(&voltage_mq2);
}
sleep_ms(1);
}
}
//Funções implementadas
bool read_dht22(float *temperature, float *humidity) {
uint8_t bits[5] = {0};
uint8_t cnt = 7, idx = 0;
// Start signal
gpio_init(DHT_PIN);
gpio_set_dir(DHT_PIN, GPIO_OUT);
gpio_put(DHT_PIN, 0);
sleep_ms(10); // pelo menos 1 ms
gpio_put(DHT_PIN, 1);
sleep_us(30);
gpio_set_dir(DHT_PIN, GPIO_IN);
// Espera pela resposta do sensor
sleep_us(40);
if (gpio_get(DHT_PIN) == 1) return false;
sleep_us(80);
if (gpio_get(DHT_PIN) == 0) return false;
sleep_us(80);
// Leitura de 40 bits (5 bytes)
for (int i = 0; i < 40; i++) {
while (gpio_get(DHT_PIN) == 0); // espera pelo início do bit
sleep_us(30);
if (gpio_get(DHT_PIN)) {
bits[idx] |= (1 << cnt);
}
while (gpio_get(DHT_PIN) == 1); // espera o fim do bit
if (cnt == 0) {
cnt = 7;
idx++;
} else {
cnt--;
}
}
// Verifica checksum
if (bits[4] != ((bits[0] + bits[1] + bits[2] + bits[3]) & 0xFF)) return false;
// Conversão dos dados
*humidity = ((bits[0] << 8) + bits[1]) * 0.1;
*temperature = (((bits[2] & 0x7F) << 8) + bits[3]) * 0.1;
if (bits[2] & 0x80) *temperature *= -1;
return true;
}
void ldr_read(float *voltage_ldr) {
adc_select_input(2);
uint16_t result = adc_read();
*voltage_ldr = conversion_factor * result;
}
void mq2_read(float *voltage_mq2) {
adc_select_input(1);
uint16_t result = adc_read();
*voltage_mq2 = conversion_factor * result;
}
void control_vibracall(float *temperature) {
if (*temperature > 30.0) {
gpio_put(VIBRACALL_PIN, 1);
printf("Temperatura MAIOR que 30.0 ºC. Vibracall ativado.\n");
}
else {
gpio_put(VIBRACALL_PIN, 0);
printf("Temperatura MENOR OU IGUAL a 30.0 ºC. Vibracall desativado.\n");
}
}
void control_led_ir(float *voltage_ldr) {
if (*voltage_ldr > 2.73) {
gpio_put(IR_PIN, 1);
printf("Luminosidade MENOR OU IGUAL a 10 lux. LED infravermelho ativado.\n");
}
else {
gpio_put(IR_PIN, 0);
printf("Luminosidade MAIOR que 10 lux. LED infravermelho desativado.\n");
}
}
void control_rele(float *voltage_mq2) {
if (*voltage_mq2 > 3.03091) {
gpio_put(RELE_PIN, 1);
printf("Quantidade de CO2 no ambiente MAIOR que 1000 ppm. Alarme ativado.\n\n");
}
else {
gpio_put(RELE_PIN, 0);
printf("Quantidade de CO2 no ambiente MENOR OU IGUAL a 1000 ppm. Alarme desativado.\n\n");
}
}
bool alarme_callback_1(repeating_timer_t *t) {
temp_flag = true;
return true;
}
bool alarme_callback_2(repeating_timer_t *t) {
ldr_flag = true;
return true;
}
bool alarme_callback_3(repeating_timer_t *t) {
mq2_flag = true;
return true;
}