Integração Arduino - Python Leitura de sensor de umidade e

Propaganda
Integração Arduino - Python
Leitura de sensor de umidade e temperatura
Filipi Nascimento Silva, Luciano da Fontoura Costa
Disciplina: Modelagem Matemático - Computacional
Nesta prática, usaremos um programa python para se comunicar
com um dispositivo Arduino através da conexão serial usando um
cabo USB. Serão lidos valores provenientes de um sensor de
umidade e temperatura conectado ao Arduino.
Hardware necessário
- Arduino
- PC com windows ou linux, ou Mac.
- Sensor de umidade e temperatura DHT22
Softwares necessários
-
Arduino IDE
Python 2.x ou 3.x
Biblioteca pySerial
Biblioteca MatplotLib
Biblioteca NumPy
Sensor DHT22
Preparo do ambiente de desenvolvimento
Inicialmente deve-se realizar o download da IDE do Arduino,
disponível em:
https://www.arduino.cc/en/Main/Software
Após a instalação deve-se configurar a IDE
com as informações do Arduino (que deverá
estar conectado através da porta USB).
A configuração é feita selecionando o tipo
de dispositivo no menu Tools > Board.
Também deve-se selecionar a porta de comunicação com o
Arduino no menu
Tools > Port.
Recomenda-se testar o ambiente carregando o exemplo Blink
através do menu File > Examples > 01.Basics > Blink.
A interface de edição da IDE é
simples. O botão com a marca de
correto checa e compila o código,
enquanto o botão com a seta
envia o código para ser executado
no Arduino.
É importante alterar os valores de delay no código do exemplo
Blink para verificar se realmente o dispositivo está executando o
código fornecido. Dispositivos novos já vem com o exemplo blink
pré-instalado.
Preparo do ambiente Python
O python pode ser instalado através de arquivos que podem ser
obtidos no site:
https://www.python.org/downloads/
Para Linux, verifique a disponibilidade do python através do
gerenciador de pacotes disponível como apt-get ou port.
Por padrão, junto ao python também é instalado o gerenciador de
módulos pip. Este deverá ser usado para instalar o módulos
necessários para a prática. Para instalar os módulos usados utilize
os comandos:
pip install matplotlib
pip install numpy
pip install pyserial
Dependendo da versão do python o comando pip pode estar
nomeado como pip3 ou pip2, neste caso utilize estes comandos
ao invés de simplesmente pip.
Preparo do sensor DHT22
O sensor DHT22 comunica-se através de um pino digital (serial) e
possui 3 pinos (+: 5 ou 3.3 Volts, out: saída serial, -: Terra).
A conexão com o Arduino é feita
conectando-se os pinos + e - do
sensor aos pinos Vcc (5V ou 3.3V)
e GRD do Arduino, respectivamente. O pino out deve ser
conectado a uma entrada/saída
digital do Arduino. Nesta prática
usamos a porta digital 2.
Códigos para as práticas
Os códigos usados para a prática encontram-se nesta pasta e
estão comentados.
O arquivo TemperatureHumidity.ino deve
ser carregado no Arduino através da
IDE. Ele é responsável por realizar a
leitura do sensor e enviar os valores de
umidade e temperatura, através da
porta serial, para o computador. É
possível testar este código observando
o monitor de porta serial embutido na
IDE do arduino, assim com através do
plotter embutido. Ambos são acessíveis
através do menu Tools.
O arquivo TemperatureHumiditySimple.py lê os dados enviados
pelo Arduino através da porta serial e os imprime no terminal. É
necessário configurar, através da variável selectedPortIndex, qual
porta serial deverá ser usada para a comunicação com o Arduino.
O arquivo TemperatureHumidityPlot.py lê progressivamente os
dados enviados pelo Arduino através da porta serial e construi um
gráfico do tipo scatterplot com a história de valores no espaço
Umidade x Temperatura. Também é necessário configurar, através
da variável selectedPortIndex, qual porta serial deverá ser usada
para a comunicação com o Arduino.
Arquivos
- TemperatureHumidity.ino
//Incluindo a biblioteca de comunicação com o sensor de humidade e
temperatura.
#include "DHT.h"
//Define o macro DHTPIN de acordo com o pino digital correspondente.
#define DHTPIN 2
//Selecionando o tipo de sensor (no nosso caso, o DHT22)
//#define DHTTYPE DHT11
// DHT 11
#define DHTTYPE DHT22
// DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21
// DHT 21 (AM2301)
//Cria e inicializa os dados do sensor.
DHT dht(DHTPIN, DHTTYPE);
double currentHumidity = 0.0;
double currentTemperature = 0.0;
// Função que executa uma vez para configurar
// variáveis e parametros
void setup() {
// Inicializa a porta serial a uma velocidade de 57600bps
Serial.begin(57600);
//Envia um header pela porta serial.
Serial.print("Humidity\tTemperature\n");
}
//Inicializa o sensor.
dht.begin();
// Esta função executa em loop indefinidamente após a execução da função
setup
// mas pode ser parado por certas funções e interrupções.
void loop() {
// Aguarda-se 250ms antes de realizar uma nova leitura do sensor.
delay(250);
currentHumidity = dht.readHumidity();
currentTemperature = dht.readTemperature();
// Checa se alguma das leituras falhou.
if (isnan(currentHumidity) || isnan(currentTemperature)) {
Serial.println("ERROR: Failed to read from DHT sensor!");
return;
}
}
// Envia através da porta serial os valores de umidade e temperatura.
Serial.print(currentHumidity);
Serial.print("\t");
Serial.print(currentTemperature);
Serial.print("\n");
- TemperatureHumiditySimple.py
#!/usr/bin/python
# -*- coding: utf-8 -*import serial
from serial.tools import list_ports
#Primeiramente precisamos determinar as portas seriais disponiveis na maquina
# para isso, obtemos a lista de portas seriais e escolhemos manualmente
# aquela com index 1.
selectedPortIndex = 1;
selectedDevice = "";
ports = list_ports.comports();
print("Avaiable ports:\n%s"%"\n".join(["\t%d: %s"%
(portIndex,str(ports[portIndex])) for portIndex in range(len(ports))]));
selectedDevice = ports[selectedPortIndex].device;
print("Selected device: %s"%selectedDevice);
ser = serial.Serial(selectedDevice, 57600);
# Cada execução lê uma linha da porta serial
# e separada os dois valores (umidade e temperatura)
# imprimindo no prompt
try:
for line in ser:
try:
entry = line.decode("utf-8").split("\t");
humidity = float(entry[0]);
temperature = float(entry[1]);
print(u"T: %gºC H:%g%%"%(temperature,humidity));
except ValueError as e:
print("E: %s"%line);
except IndexError as e:
print("E: %s"%line);
except KeyboardInterrupt:
# Ao abortar a execução do programa esta exception é chamada
# deve-se então fechar a porta serial para novas comunicações
ser.close();
except:
#Caso seja um erro não especificado é importante fechar a porta
# serial para permitir comunicação futura
ser.close();
- TemperatureHumidityPlot.py
#!/usr/bin/python
# -*- coding: utf-8 -*import numpy as np;
import serial;
import matplotlib.pyplot as plt;
import matplotlib.animation as animation;
import time;
from serial.tools import list_ports;
#Primeiramente precisamos determinar as portas seriais disponiveis na maquina
# para isso, obtemos a lista de portas seriais e escolhemos manualmente
# aquela com index 1.
selectedPortIndex = 1;
selectedDevice = "";
ports = list_ports.comports();
print("Avaiable ports:\n%s"%"\n".join(["\t%d: %s"%
(portIndex,str(ports[portIndex])) for portIndex in range(len(ports))]));
selectedDevice = ports[selectedPortIndex].device;
print("Selected device: %s"%selectedDevice);
#Iniciando a porta serial à velocidade de 57600 bps
ser = serial.Serial(selectedDevice, 57600);
temperatureHistory = [];
humidityHistory = [];
fig = plt.figure();
l, = plt.plot([], [], '.-');
plt.xlabel('Temperatude (°C)');
plt.ylabel('Humidity (%)');
plt.title('Temperature vs Humidity');
# Criando uma funcao de animacao para o matplotlib
def update_line(num, ser, temperatureHistory, humidityHistory, plt, line):
try:
#cada execução lê uma linha da porta serial
# e separada os dois valores (umidade e temperatura)
entryLine = ser.readline().decode("utf-8");
entry = entryLine.split("\t");
humidity = float(entry[0]);
temperature = float(entry[1]);
if( (len(temperatureHistory)==0 or
len(humidityHistory)==0 or
temperature!=temperatureHistory[-1] or
humidity!=humidityHistory[-1] ) and
temperature>0 and humidity>0):
print(u"T: %g°C H:%g%%"%(temperature,humidity));
temperatureHistory.append(temperature);
humidityHistory.append(humidity);
minx = min(temperatureHistory)
maxx = max(temperatureHistory)
lenx = maxx-minx;
miny = min(humidityHistory)
maxy = max(humidityHistory)
leny = maxy-miny;
plt.xlim([minx-0.05*lenx,maxx+0.05*lenx]);
plt.ylim([miny-0.05*leny,maxy+0.05*leny]);
line.set_data(temperatureHistory, humidityHistory);
except ValueError as e:
#Em caso de erro apenas imprime o texto com erros no terminal.
print("E: %s"%entryLine);
except IndexError as e:
print("E: %s"%entryLine);
except:
#Caso seja um erro não especificado é importante fechar a porta
# serial para permitir comunicação futura
ser.close();
raise;
return line,
#Ativa o modo animação do matplotlib com a função update_line
line_ani = animation.FuncAnimation(fig, update_line, 1,
fargs=(ser,temperatureHistory,humidityHistory,plt, l), interval=1,
blit=False)
plt.show()
ser.close();
Download