Monitorar Temperatura e Humidade de sua Casa com DHT11
Neste artigo iremos desenvolver um servidor utilizando o Arduino, Flask, e Firebase capaz de monitorizar a temperatura e humidade de sua casa.
Lista de material
Imagem | Produto | Comprar |
---|---|---|
Arduino Uno |
||
DHT11 |
||
Cabos Jumper Macho-Femêa |
Requisitos
Para acompanhar este projeto necessita de:
- Conta Google – Pode criar aqui
- Python instalado na sua máquina – Pode transferir aqui
Atenção
Sendo que neste artigo iremos utilizar algumas tecnologias avançadas que já foram introduzidas em detalhe em artigos anteriores portanto aconselhamos o leitor a que consulte os seguintes artigos antes de iniciar este projeto:
- Como Hospedar um Servidor Local com Raspberry Pi e Flask
- Como Utilizar a Firebase para Visualizar Dados de um Arduino (ESP32)
Preparar Ambiente
Primeiramente necessita de criar 2 pastas, uma responsável por enviar os dados lidos pelo DHT11 para a nossa base de dados na FireBase e outra para armazenar os arquivos responsáveis pelo servidor e pela leitura dos dados da Firebase
Aconselhamos a que copie a seguinte estrutura de pastas e arquivos de forma a evitar incoerências na importação de ficheiros para o seu ambiente
Código para Arduino
De seguida o código que deve ser carregado no seu Arduino para efetuar a leitura da Temperatura (ºC) e Humidade (%) – Deve também instalar a libraria DHT sensor library da Adafruit.
#include "DHT.h" #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); } void loop() { delay(2000); float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); if (isnan(h) || isnan(t) || isnan(f)) { Serial.println(F("Não foi possivel efetuar a leitura do sensor!")); return; } Serial.print(t); }
Esquema de Montagem
Script Upload Firebase
De seguida iremos preparar a parte do projeto responsável por comunicar com o Firebase
run.py
Script principal responsável por gerenciar os restantes ficheiros do ambiente.
from models.ReadDht11 import SensorDHT11 from modules import UploadFirebase from time import sleep def lerValoresSensor(): sensor = SensorDHT11() valoresDht = sensor.LerValoresArduino() return valoresDht def main(): while True: valoresDht = lerValoresSensor() update_status = UploadFirebase.UploadTemperature(valoresDht) if update_status: print("Ocorreu um erro ao carregar firebase") sleep(20) if __name__ == '__main__': main()
config/config.py
Ficheiro responsável por armazenar as configurações do nosso projeto – Ter em atenção este ficheiro deve ser substituídos pelos dados do seu ambiente:
FIREBASE_CONFIG = { # Dados Firebase API } PORTA_COM = "PORTA_COM_ARDUINO"
models/ReadDht11.py
Ficheiro armazena a classe responsável por interpretar os valores que circulam no Serial da máquina e retomar o valor de Humidade e Temperatura.
from config import config import serial class SensorDHT11: def __init__(self): self.esp32 = serial.Serial(port= config.PORTA_COM, baudrate=9600, timeout=.1) self.read_valores = "" def LerValoresArduino(self): while self.read_valores == "": try: self.read_valores = self.esp32.readline().decode("utf-8") except: continue return self.read_valores
modules/UploadFirebase.py
Script responsável por formatar e carregar dados no Firebase
from datetime import datetime from config import config import pyrebase def UploadTemperature(valores): try: # Establecer conexao com firebase firebase = pyrebase.initialize_app(config.FIREBASE_CONFIG) database = firebase.database() # Timestamp no firebase data = str(datetime.now().date()) hora = str(datetime.now().time()).split('.')[0] temp = valores.split("|")[0] hum = valores.split("|")[1] upload_data = { 'Temperatura':temp, 'Humidade':hum, 'Data': data, 'Hora': hora } database.child().update({f'temperatura_data_{data}_{hora}':upload_data}) print(f"{upload_data.get('Data')} - {upload_data.get('Hora')}") print(f"Temperatura registada: {upload_data.get('Temperatura')} C\nHumidade registada: {upload_data.get('Temperatura')}\n---") error = False except: error = True return error
Servidor Flask
Servidor responsável por exibir uma tabela com as 10 medições mais recentes.
app.py
from servidor import app if __name__ == '__main__': app.run(debug = True, host="0.0.0.0", port=80)
routes.py
from flask import render_template from servidor import app from servidor import firebase_data @app.route("/") def homepage(): firebase_objs = firebase_data.firebase_data() return render_template("home.html", firebase_objs = firebase_objs)
firebase_data.py
import pandas as pd import pyrebase def firebase_data(): FIREBASE_CONFIG = { "apiKey" : "AIzaSyDCVM_cDiDLTpdqF0Ug2mg3o3N8WGqZMjg", "authDomain" : "shellyem-esp32.firebaseapp.com", "databaseURL" : "https://shellyem-esp32-default-rtdb.europe-west1.firebasedatabase.app", "projectId" : "shellyem-esp32", "storageBucket" : "shellyem-esp32.appspot.com", "messagingSenderId" : "130619280471", "appId" : "1:130619280471:web:092c408d78d750b7616712" } firebase = pyrebase.initialize_app(FIREBASE_CONFIG) db = firebase.database() data_res = db.child().get() firebase_obj = [] for line in data_res.each(): obj = { 'data':line.val().get("Data"), "hora":line.val().get("Hora"), "temp":line.val().get('Temperatura'), "hum":line.val().get('Humidade') } firebase_obj.append(obj) while len(firebase_obj) > 10: firebase_obj.pop(0) return firebase_obj
__init__.py
from flask import Flask app = Flask(__name__) from servidor import routes
templates/base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Poiret+One&display=swap" rel="stylesheet"> <title>Monitorar DHT11</title> </head> <body> {% include 'navbar.html' %} {% block content %} {% endblock %} </body> </html>
templates/navbar.html
<div class="navbar-custom"> <p class="text-center text-custom"> Monitorar Casa <p> </div> <style> .navbar-custom{ background: rgb(0,0,0); background: linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(62,62,62,1) 50%, rgba(0,0,0,1) 100%); border-bottom-width: 1px; border-bottom-style:solid; border-bottom-color:black; } .text-custom{ color:rgb(245, 245, 245); font-size: 2rem; font-family: 'Poiret One', cursive; padding-top:10px; } </style>
templates/home.html
{% extends 'base.html' %} {% block content %} <div class="container"> <div class="row mt-3"> <div class="col"> <div class="display-6">Valores DHT-11</div> <hr> <table class="table table-secondary table-hover text-center"> <thead> <tr> <th scope="col">Data</th> <th scope="col">Hora</th> <th scope="col">Temperatura</th> <th scope="col">Humidade</th> </tr> </thead> <tbody class=> {% for firebase_obj in firebase_objs %} <tr> <td>{{ firebase_obj.data }}</td> <td>{{ firebase_obj.hora }}</td> <td>{{ firebase_obj.temp }}ºC</td> <td>{{ firebase_obj.hum }}%</td> </tr> {% endfor %} </tbody> </table> </div> </div> <div class="row mt-2 text-center"> <div class="col-2"> <button class="btn btn-outline-dark form-control" id="btn-reload">Recarregar</button> </div> <div class="col-10"></div> </div> </div> <script> const btn_reload = document.getElementById('btn-reload'); btn_reload.addEventListener('click', function(e){ window.location.reload(true); }) </script> {% endblock %}
Para mais projetos, percorram o nosso blog, onde podem encontrar vários artigos interessantes relacionados com eletrónica, robótica e muito mais! Visitem também o nosso site, onde encontram tudo para eletrónica e robótica!