Raspberry Pi 3 e Python – Iniciação!!

Introdução

Sempre tive curiosidade em lidar com automação. Seja para fazer experimentos que venham a render algo, mas na sua grande maioria é por hobby mesmo!

Recentemente adquiri uma plaquinha do Raspberry Pi 3. Execelente para esses propósitos e com uma vantagem, em relação ao Arduino, que é poder programá-lo em Python, já que o Arduino a programação é em C++ com pequenas modificações. Foi então que parte de minha curiosidade e vontade fazer algo em automação começou.

Claro que para um início, o projeto que escolhi foi muito, mas muito tranquilo de se fazer. Um pequeno circuito com o Sensor DHT11 para leituras da temperatura ambiente e umidade relativa do ar. Mas, o que já me proporcionou momentos de grande aprendizado em relação ao Raspberry, ao Python e na integração entre ambos.

O Raspberry – RPi

Uma plaquinha poderosa e de baixo custo, varia de R$180 a R$290 no Mercado Livre, isso sem contar nos diversos kits que são vendidos, um pouco mais caros, mas que acompanham acessórios e outras coisinhas!!!

O que utilizo é um Raspberry Pi 3 Model B, a qual passarei a chamar de RPi para simplificar, que possui as seguintes especificações ténicas:

  • chipset Broadcom BCM2387
  • 1.2GHz quad-core ARM córtex-A53
  • 802.11 bgn wireless LAN e Bluetooth 4.1 (Bluetooth Classic e LE)
  • 1 GB de RAM
  • CPU de 64 bits
  • 4 portas USB
  • Saída estéreo de 4 portas e porta de vídeo composto
  • Conexão HDMI
  • Entrada de rede Ethernet 10/100 BaseT
  • Porta de câmera CSI para conexão da câmera Raspberry Pi
  • Porta de exibição DSI para conectar a tela de toque Touch Raspberry Pi
  • Porta Micro SD para carregar seu sistema operacional e armazenar dados
  • Entrada para Fonte de alimentação Micro USB
  • GPIO de 40 pinos

Eis uma imagem dele:

Preparando o ambiente

Utilizando um cartão microSD com 32Gb de capacidade instalamos a mais recente versão do Raspbian Stretch a distribuição Debian oficial para o RPi. O cartão é mais que suficiente para o sistema e para os dados, já que o RPi não possuiu uma unidade de armazenamento.

Após a instalação do Raspbina Stretch, passamos à configuração do sistema para o que nos propomos fazer! Não há mistérios nessa configuração, vejamos como foi o processo.

Instalando o Docker e Docker-Compose

Instalamos o Docker, pois vamos utilizá-lo para subir um container do PostgreSQL, para isso fizemos:

curl -sSL https://get.docker.com | sh — Isso instalará o Docker no RPi

sudo usermod -aG docker pi — Isso coloca o usuário pi no gruo docker, para não precisar executar as instruções do docker usando o sudo

sudo systemctl enable docker — Isso configura o sistema para que sempre que for iniciado o docker também o seja.

sudo reboot -h now — Bom, com essa linha reiniciamos o sistema.

Agora vamos à instalação do Docker-compose, que utilizamos para subir nosso container do PostgreSQL utilizando do arquivo de configuração docker-compose.yml, para isso executamos:

sudo apt intall docker-compose

Preparando o docker-compose.yml

Nosso arquivo de configuração ficou assim:

version: "2"

services:
  meteriologia:
    image: postgres:10.5
    container_name: "meteorologia"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - "./data/postgres:/var/lib/postgresql/data"
    ports:
      - 5432:5432

Explicando os passos tomados:

  • version expõem a versão do docker-compose que estamos usando
  • services lista os serviços, no nosso caso somente um.
  • image indica a imagem docker que vamos utilizar, no nosso caso para Postgres versão 10.5
  • container_name o nome que estamos dando ao nosso container
  • environment seta as variáveis de ambiente que precisamos para que tudo fucione, nesse caso específico, para fins didáticos, mantivemos usuário, senha e banco padrões do PostgreSQL, mas é aqui que deve ser definido as variáveis com seus reais valores.
  • volumes aqui definimos os diretórios no host e no container que ficarão os arquivos do Postgres, lembrando que o container pode apresentar falhas e fechar, se não tivermos essas definições os dados não serão mantidos, e perderemos tudo que tiver sido gravado no banco.
  • ports aqui bindamos a porta do host com a do container para que a comunicação aconteça!

Finalizada a criação do docker-compose.yml está na hora de subirmos nosso container, para tanto utilizamos o seguinte comando:

docker-compose -d up meteorologia

Importante observar:

  1. O -d indica que o container vai rodar em daemon, ou seja, em segundo plano

  2. O meteorologia é o nome do serviço que demos em nosso arquivo docker-compose.yml

Instalando o pyenv e o Python 3.7.0

Vamos instalar, agora, o pyenv, o utilizamos para manter nossa versão do python distinta das que já vem instaladas no sistema, e porque vamos usar o python 3.7.0, que não é a versão do sistema, bom vamos ao que interessa!!

Atualizamos o sistema:

sudo apt update && sudo apt upgrade -y

Instalamos as dependências do pyenv:

sudo apt-get update && sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libffi-dev liblzma-dev libncursesw5-dev openssl bzip2

Agora a instalação do pyenv

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

Não esquecer de inserir as seguintes linhas no final do arquivo ~/.bashrc

export PATH="~/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Atualizamos o pyenv:

pyenv update

Finalmente instalamos o Python 3.7.0:

pyevn install 3.7.0

Obs.: A instalação aqui é bem demorada, no meu RPi levou pelo menos uns 10 minutos para finalizar a instalação do Python 3.7.0.

Após a instalação do Python 3.7.0, temos, pelo pyenv, duas versões do Python, isso é possível de verificar executando o seguinte comando:

pyenv versions

Cuja saída é:

* system
  3.7.0 (set by /home/pi/.pyenv/version)

Note que há um asterísco na versão do sistema, indicando que é a versão ativa no momento. E temos, também, a versão que acabamos de instalar. Ok, mas o que fazer para que a versão que ativa seja a que acabamos de instalar?

Não vamos entrar nos pormenores, para isso você pode assistir à Tech Talk do Python Pro na qual discutimos sobre o pyenv. Mass, basicamente, o que precisaos é executar um comando do pyenv para torna a versão que acabamos de instalar a versão global do sistema. Eis o comando:

pyenv global 3.7.0

Feito isso, se executarmos de novo o comando pyenv versions teremos uma saída bem semelhante, mas cuja diferença estará na posição do asterísco, veja:

  system
* 3.7.0 (set by /home/pi/.pyenv/version)

Indicando que agora a versão que temos como global para uso é a versão 3.7.0 do Python.

Após a instalação do Python, precisamos agora preparar nosso projeto. Bora lá então:

Configurando o Projeto Python

Primeiramete, criamos um diretório para o projeto e iniciamos um virtualenv nele.

~/Documents/# mkdr meteoroloiga
~/Documents/# cd meteorologia
~/Documents/meteorologia/#

Pronto, com isso temos o diretório de nosso projeto, vamos agora ao ambiente virtual:

~/Documents/meteorologia/# python -m venv .meteorologia

Criado nosso ambiente virtual, vamos ativá-lo:

~/Documents/meteorologia/# source .meteorologia/bin/activate
(meteorologia) ~/Documents/meteorologia/#

Feito, com isso agora podemos instalar as bibliotecas que nosso projeto necessita sem, contudo, enchar o python global com elas, mantendo um ambiente bem isolado.

Instalando as dependências do projeto

Bom, vamos entender o que nosso proejto vai fazer, num fluxo em alto nível bem simples:

  1. Acessar a GPIO do Raspberry para ler as informações do sensor DHT11, para isso vamos necessitar da biblioteca RPi.GPIO

  2. Lerá os dados de temperatura e umidade do sensor DHT11, para isso vamos necessitar da biblioteca chamada Adafruit_DHT.

  3. Gravará esses dados numa base de dados em PostgreSQL, para isso vamos precisar da biblioteca Psycopg2.

  4. Enviará, também, essas informações para o site ThingSpecks, para isso vamos precisar da biblioteca requests.

Bom, tendo isso em mente e nosso ambiente virtual ativado, bora instalar as dependências, seguindo os ordem descrita no fluxo acima temos:

(meteorologia) ~/Documents/meteorologia/# pip install RPi.GPIO
(meteorologia) ~/Documents/meteorologia/# pip install Adafruit_DHT
(meteorologia) ~/Documents/meteorologia/# pip install psycopg2
(meteorologia) ~/Documents/meteorologia/# pip install request

Pronto, nosso sistema está configurado e pronto para ser trabalhado.

Preprando o Hardware

Bom, vamos fazer um pequeno experimento e vamos utilizar alguns materiais que comporão nosso circuito, esses materiais são descrito e mostrada em imagem abaixo:

Um sensor de temperatura e umidade DHT11

Um resistor de 1k5, que indica ser o resistor de 1 Kilo OHMs com tolerância de +/- 5%

Uma protobord e Jumpers para as ligações

A montagem é super simples, abaixo um esquema de como pode ser feito:

Essa montagem ao final fica bonita assim:

Fazendo a programação Python

Bom, até agora o que fizemos foi:

  • Instalar o Raspibian e configurá-lo com o que precisamos
  • Juntar as peças do nosso quebra-cabeças inteligente e montá-lo conforme nossa necessidade.

Mas, ainda falta o cérebro de tudo isso, falta fazermos a programação do bichinho para que ele possa fazer a leitura da temperatura e umidade e enviar essas informações tanto para nosso Banco de Dados como para o site Thingspeak. Bora por a mão no código?

Primeiramente, vamos lembrar que é quase Just Python aqui, ou seja, se não fosse o fato de precisarmos das comuniações com o mundo exterior, tudo estaria só com as bibliotecas padrão do Python.

Bem, comecemos com nossa tabela do Banco de Dados, ela é bem simples, não possui qualquer relacionamente ou JOIN complicado, nada! É uma tabela com quantro campos, nosso SQL ficou assim:

    create table if not exists dados_temp_umid
    (
        id serial not null
            constraint dados_temp_umid_pkey
                primary key,
        temperatura double precision not null,
        umidade double precision not null,
        lido_em timestamp with time zone default CURRENT_TIMESTAMP not null
    );

    create unique index if not exists dados_temp_umid_id_uindex
        on dados_temp_umid (id);

Vamos às explicações, que esse script deve ser executado uma única vez, somente para cria nossa tabela. O mais importante é entendermos os tipos de dados que usamos.

O primeiro create é o coração do script, pois é ele quem cria a tabela, define os campos assim:

  • id é serial ou seja, será de auto-incremento; tem como restrição (constraint) não poder ser nulo, será a chave primária do registro;
  • temperatura é número decimal, isso é definido pelo double precision e também não pode ser núlo;
  • umidade, assim como a temperatura, não pode ser nulo e é decimal;
  • lido_em é um campo do tipo timestap com time zone e tem por conteúdo default o CURRENT_TIMESTAMP, também não pode ser nulo. É interessante, pois esse campo será prenchido, sempre, pelo valor default. Pois a função do PostgreSQL CURRENT_TIMESTAMP vai preenhcer o campo com data e hora do exato momento da criação do registro que coincidira, por fração de milisegundos com o tempo de leitura do sensor.

Bom, tabela do banco criado, vamos inicia no Python propriamente dito. Nosso código ficou assim:


    import Adafruit_DHT as dht
    import RPi.GPIO as gpio
    import psycopg2
    import requests

    sensor = dht.DHT11
    gpio.setmode(gpio.BOARD)
    pino_sensor = 4
    url = 'https://api.thingspeak.com/update'
    api_key = 'AQUI_VEM_SUA_CHAVE_DO_SITE'

    connect = psycopg2.connect(
        host='192.168.0.106',
        database='postgres',
        user='postgres',
        password='postgres'
    )
    cursor = connect.cursor()

    umid, temp = dht.read_retry(sensor, pino_sensor)

    sql = f"""
        INSERT INTO dados_temp_umid (temperatura, umidade)
        VALUES ({temp:.2f}, {umid:.2f})"""
    cursor.execute(sql)
    connect.commit()
    connect.close()

    response = requests.get(f"""
                  {url}?api_key={api_key}&field1={temp}&field2={umid}
              """)

Bom, as primeiras quatro linhas fazem os imports necessários:

  • a Adafruit_DHT é responsável pela comunicação com o Sensor DHT11
  • a RPi.GPIO é responsável por permitir que o Python se comunique com os pinos da GPIO do RPi
  • a Psycopg2 é responsável por permitir que o Python se comunique com o Banco de Dados PostgreSQL
  • a requests é responsável por permitir que o Python se comunique com uma API externa pelo protocolo HTTP

Na sequencia o comando sensor = dht.DHT11 vai definir pra gente qual é o sensor com o qual estamos trabalhando, a biblioteca Adafruit_DHT permite ainda trabalhar com os sensores DHT22 e AM2302.

Setamos o modo de leitura da GPIO com o comando gpio.semod(gpio.BOARD) em seguid informamos qual pino utilizamos para ligar nosso sensor, setando a variável pino_sensor com essa informação.

Na sequência definimos as variáveis que permitirão o envio das informações para o site ThingSpeak, que são a url e a api_key.

Feita as definições da url e da api_key, iniciamos a conexão com o banco de dados, abrindo a conexão e setando o objeto connect para referencia-la quando necessário. Aqui passamos o host, database, usuário e senha para que a conexão seja realizada. Note que estamos usando o IP de nossa rede interna na qual nosso RPi esá conectado. Em seguida criamos um cursor para acesso.

Com a seguinte linha de código: umid, temp = dht.read_retry(sensor, pino_sensor) é que efetivamente fazemos a leitura de nosso sensor e armazenamos nas variáveis umid e temp seus respectivos valores de umidade e temperatura.

Na variável sql colocamos a string com os comandos SQL que gravarão as informações em nosso Banco de dados. Executamos essa gravação com o comando cursor.execute(sql), damos um commit para que os dados sejam persistidos no banco, com o comando connect.commit() e fechamos a conexão com o banco usando connect.close().

Finalmente, montamos a requisição para o envio das informaçãos para o site ThingSpeak com o comando: response = requests.get(f"""{url}?api_key={api_key}&field1={temp}&field2={umid}"""), com isso nosso programa é encerrado.

Bom, mas aí você pode estar se perguntando: Uai, mas isso vai executar uma única vez, gravar as informações no banco, enviá-las ao site e depois terei que executar tudo na unha novamente?

Bom, a resposta mais simples para essa pergunta é: SIM!!! Contudo, nós fizemos um pequeno script bash e agendamos no Cron, via crontab, para que o mesmo seja executado a cada 15min o dia todo, o script ficou assim:

#!/bin/bash

cd /home/pi/Documents/pythonprojects/meteorologia/
source .meteorologia/bin/activate
cd app
python temp_umid.py
deactivate

O script é bem simples ele vai até o diretório do projeto, ativa o virtualenv, segue para o diretório da aplicação a executa e, ao término da execução, desativa o virtualenv.

E, no crontab, ficou assim:

*/15 * * * * root /home/pi/.bin/./le_temp_umid.sh

No qual a indicação */15 diz que é para repetir a cada 15min os asteríscos posteriores informam que é de qualquer hora, qualquer dia do mês, qualquer mês e qualquer dia da semana, o root executa o script que está em /home/pi/.bin/./le_temp_umid.sh

Bom, essa foi minha primeira aventura com o Raspberry Pi 3 Model B com Python. E você tem algum projetinho bacana para compartilhar conosco? Deixa nos comentários ou mesmos suas perguntas! Será muito legal poder interagir com quem mais brinca com o RPi!!

About Prof. Vicente E. R. Marçal

Professor Adjunto do Departamento de Filosofia da Universidade Federal de Rondônia. Doutorando em Psicologia Social pelo Instituto de Psicologia da USP. Mestre em Filosofia pela Universidade Estadual Paulista/Campus Marília. Especialista em Filosofia Moderna e Contemporânea: Aspectos Éticos e Jurídicos pela Universidade Estadual de Londrina. Licenciado em Filosofia pela Universidade Estadual de Londrina. Coordenador do GEPEGRA - Grupo de Estudos e Pesquisa em Epistemologia Genética da Região Amazônica. Com experiência em Filosofia, com ênfase em Epistemologia e Teoria do Conhecimento.

4 thoughts on “Raspberry Pi 3 e Python – Iniciação!!

  1. Matiusco

    Parabéns por compartilhar. No futuro gostaria de me aventurar nessa área também. Hoje faço ciências da computação mas sempre quis mexer com máquinas. Estou aprendendo muito de programação e espero no futuro poder compartilhar também como vc pediu.

    Reply

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

This site uses Akismet to reduce spam. Learn how your comment data is processed.