Arduino Meteorolog

Protótipo v0.2 da tool chain Meteorolog, inspirado na antiga v0.1. Trata-se de um refactoring objetivando:

Repositório:
https://git.cta.if.ufrgs.br/meteorolog/arduino-meteorolog/tree/master

Tag v0.1 (código antigo):
https://git.cta.if.ufrgs.br/meteorolog/arduino-meteorolog/tree/v0.1

Overview

O conceito do Meteorolog abrange as duas seguintes ferramentas complementares:

  • Firmware que roda na placa Arduino, responsável por:
    • Escutar por uma solicitação de leitura de sensores através de caracteres enviados para a porta serial (USB);
    • Envio de uma resposta para a porta serial, através de uma string de caracteres contendo os valores medidos conforme a solicitação;
  • Logger que roda na máquina em que a Arduino está conectada via USB. É responsável por:
    • Comunicação serial com Arduino: envio de uma solicitação de leitura e subsequente leitura da resposta contendo os valores medidos;
      • OBS: Caso a porta esteja inacessível, espera um pouco e tenta de novo; isto é, o programa não pára.
    • Escrita das leituras em um arquivo local (para fins de backup);
    • Envio das leituras para o servidor da web app;
      • OBS: Caso o servidor esteja inacessível, as leituras "a enviar" ficam gravadas em um arquivo temporário local "outgoing.json". Quando o servidor estiver novamente acessível em tentativas posteriores, as leituras armazenadas em "outgoing.json" serão enviadas uma por uma e apagadas desse arquivo temporário.
    • Registro de todas as operações acima (e eventuais falhas) em um arquivo de log operacional.

Segue abaixo uma breve descrição da pasta meteorolog contendo toda tool chain:

meteorolog/
├── Makefile                      # oferece comandos curtos para facilitar uso no terminal
├── meteorolog                    # contém projeto compilável pela IDE do Arduino
│   ├── Adafruit_BMP085.cpp       # implementação da biblioteca Adafruit_BMP085.h
│   ├── Adafruit_BMP085.h         # biblioteca para leitura do sensor BMP085 (BSD License, mantida pela Adafruit)
│   ├── DHT.cpp                   # implementação da biblioteca DHT.h
│   ├── DHT.h                     # biblioteca para leitura do sensor DHT (MIT License, mantida pela Adafruit)
│   ├── meteorolog.ino            # arquivo principal contendo setup() e loop() do Arduino
│   ├── mysensors.cpp             # (*) implementação das funções read_SENSOR_NICKNAME()
│   ├── mysensors.h               # (*) configuração da placa do usuário, todos os sensores e funções read_SENSOR_NICKNAME()
│   ├── utils.cpp                 # implementação da biblioteca utils.h
│   └── utils.h                   # biblioteca de funções úteis ao projeto
├── meteorolog.py                 # software Logger, programado em Python
└── settings.yaml                 # arquivo de configurações do Logger (usuário deve editar)

(*) mysensors.h/mysensors.cpp: Esses arquivos contém código gerado automaticamente pela web app. O usuário pode reimplementar as funções read_SENSOR_NICKNAME() desde que mantenha a estrutura gerada de acordo com o cadastro na web app.

Logo, em termos técnicos, os softwares da tool chain são:
  • meteorolog.ino: firmware a ser gravado e executado na Arduino;
    • IDE do Arduino é usada para compilar o programa e enviá-lo para a placa;
  • meteorolog.py: software logger, executado na máquina onde a placa Arduino está conectada via USB.
    • Executado pelo interpretador Python (detalhes na seção sobre uso):
      $ python3 meteorolog.py
      

Instalação e uso

Seguem abaixo instruções para uso do kit Meteorolog juntamente com uma placa Arduino (assume-se Uno ou Duemilanove) onde os sensores serão conectados de modo a montar uma estação meteorológica modular.

A ordem das seções indicam os passos a serem seguidos.

1. Hardware

Arduinos suportadas: Uno, Duemilanove

O protótipo básico inclue suporte aos seguintes sensores:

  • LDR : Luminosidade.
    • Hardware: resistor foto-sensível, onde a incidência de luz altera a tensão (voltagem) -- a qual é lida por um pino analógico da Arduino;
    • Operação: Leitura via software com analogRead() ;
  • DHT22 : Temperatura e umidade relativa do ar.
    • Hardware: encapsulamento contendo um sensor capacitivo de umidade, um termistor e uma controladora.
      • Operação: Biblioteca DHT.h, mantida pela Adafruit, MIT License;
    • A leitura é feita no hardware, pela controladora, ao receber uma sequência de bits por uma porta digital exclusiva. Após um intervalo de tempo, uma nova sequência de bits -- contendo a leitura -- é devolvida pela mesma porta digital.
  • BMP085 : Pressão barométrica e temperatura (*);
    • Hardware: PCB contendo sensor piezo-resistivo, componentes I2C e controladora.
    • Operação: A leitura é feita no hardware, pela controladora, utilizando valores calibrados (de fábrica) como referência. A resposta é enviada para o pino analógico 4 da Arduino utilizando o protocolo I2C, que permite a conexão de múltiplos componentes num único pino. A identificação do componente a ser lido/escrito é feita através de um endereço.
    • OBS: Requer uso complementar do pino analógico 5 para clock do I2C;
    • ATENÇÃO: Requer uso específico da voltagem 3.3 V (presente na Arduino);

(*) Nesse projeto a temperatura será lida pelo DHT22.

1.1 Montagem: Protoboard

1.1 Montagem: Shield

(em desenvolvimento pelo CTA)

2. Software: Firmware

2.1 IDE Arduino

Uma vez que a placa está montada, é preciso programá-la. Isto pode ser feito com a IDE (Integrated Development Enviroment) do Arduino, um programa que permite tanto a escrita do código como a compilação e upload para a placa. Segue abaixo instruções de como obter:

  • A versão mais recente pode ser baixada em:
    http://www.arduino.cc/en/Main/Software (contém instruções de instalação dos pacotes Linux);
  • Opcionalmente, usuários de Linux podem instalar uma versão não tão atualizada diretamente pela linha de comando:
    $ sudo apt-get install arduino
    
    • OBS: O comando acima é para distribuições Debian. Caso não funcione, procure utilizar o gerenciador de pacotes da sua distribuição.
  • Usuários do TropOS não precisam se preocupar, pois essa IDE já vem instalada no sistema!

2.2 Obtendo o código

Tendo a IDE, é preciso obter o código do nosso firmware. Para isso utilize a ferramenta git:

  • Instale-a caso não possua:
    $ sudo apt-get install git
    
  • Clone o repositório:
    $ git clone https://git.cta.if.ufrgs.br/meteorolog/arduino-meteorolog.git
    
  • Entre na pasta do meteorolog:
    $ cd arduino-meteorolog/meteorolog/meteorolog
    
  • Verifique a existência do arquivo meteorolog.ino:
    $ ls
    Adafruit_BMP085.cpp  DHT.cpp  meteorolog.ino  mysensors.h  utils.h
    Adafruit_BMP085.h    DHT.h    mysensors.cpp   utils.cpp
    

2.3 Instalando o firmware

  • 2.3.1) Conecte a placa Arduino na porta USB;
  • 2.3.2) Abra o arquivo meteorolog.ino com a IDE do Arduino. Várias tabs deverão aparecer na IDE, contendo todos os arquivos do projeto (mysensors.cpp, utils.cpp, etc..).
  • 2.3.3) Clique no botão compilar:
    • Caso tenha dado algum erro de compilação, não adianta prosseguir o tutorial. Refaça os passos anteriores ou entre em contato conosco para relatar o problema.
  • 2.3.4) Certifique-se de que o modelo correto (Uno ou Duemilanove) da placa está selecionado em "Tools" > "Board";
  • 2.3.5) Selecione a porta USB correta no menu "Tools" > "Serial Port";
    • Arduino Uno em geral deverá aparecer em:
      /dev/ttyACM*
      

      onde * pode ser 0, 1, 2, etc.
  • 2.3.6) Clique no botão upload:
    • Caso tenha dado algum erro de upload, verifique as seguintes possíveis causas:
      • A porta selecionada em "Tools" > "Serial Port" está incorreta. Para saber realmente qual porta é a correta, experimente os seguintes passos:
        • (i) Desconecte a placa da porta USB e execute os comandos:
          $ cd ~
          $ ls /dev/tty* > old.txt
          
        • (ii) Reconecte a placa na porta USB e execute os comandos
          $ ls /dev/tty* > new.txt
          $ diff old.txt new.txt
          

          O resultado do último comando deverá ser algo como:
          65a66
          > /dev/ttyACM0
          

          onde /dev/ttyACM0 (ou aquele valor que aparecer para você) é a porta correta.
      • Verifique se há algum mal contato no cabo USB ou considere também a troca do mesmo;
  • 2.3.7) Abra o monitor serial na IDE do Arduino. Esse dispositivo permite enviar caracteres para a porta serial e visualizar possíveis respostas que a placa pode enviar.
    • Experimente ler alguns sensores enviando uma lista de apelidos separados por vírgula, como:
      t,l
      

      E recebendo de volta algo como
      24,521
      

      onde o primeiro consiste na leitura de temperatura do DHT e o segundo em luminosidade do LDR.
      A lista completa de apelidos é:
      't' ou 'DHT22_TEMP'      : temperatura
      'ah' ou 'DHT22_AH'       : umidade relativa do ar
      'p' ou 'BMP085_PRESSURE' : pressão barométrica
      'l' ou 'LDR'             : luminosidade
      

      OBS: Não incluir aspas ao digitar! Exemplo de comando para ler todos os sensores:
      t,ah,p,l
      
As seguintes respostas de leituras indicam algum tipo de erro:
  • <invalid_nickname:XX>: apelido inválido para o sensor (você pode enviar uma lista de apelidos separados por vírgula)
  • <NaN>: Abreviação de "Not a Number", provavelmente vem de um DHT mal conectado (no caso do LDR, mesmo se ele estiver desconectado um numero válido será lido do pino analógico);
  • <BMP085_not_found>: Graças à arquitetura I2C, é possível detectar de antemão se o BMP085 está presente no circuito ou não.

2.4 Executando o Logger

  • 2.4.1) Abra o terminal (linha de comando) e entre na pasta dentro do código baixado na seção 2.2:
    $ cd arduino-meteorolog/meteorolog
    

    Experimente listar o conteúdo dessa pasta para assegurar a presença do arquivo meteorolog.py (juntamente com um Makefile):
    $ ls
    Makefile  meteorolog  meteorolog.py  settings.yaml  test_serial.py requirements.pip
    
  • 2.4.2) Prepare o ambiente Python:
    $ make setup
    
    • No caso de um erro como make: *** No rule to make target `setup'. Stop., volte ao passo 2.4.1!
  • 2.4.3) Configurando o logger: usando um editor de texto, abra o arquivo settings.yaml que está na mesma pasta do meteorolog.py. Os seguintes campos devem ser alterados se necessário:
    • Endereço do servidor:
      BASE_URL: http://localhost:5000/
      
    • ID da placa cadastrada na web app:
      BOARD_ID: 2
      
    • Lista de sensores cujos dados você quer incluir no log:
      SENSORS:
          - nickname: DHT22_TEMP
            data_format: FLOAT
          ...
      
    • Porta serial (pode ser uma lista de possibilidades, separadas por vírgula):
      SERIAL_PORT: /dev/ttyACM0, /dev/ttyACM1
      
    • Intervalo entre leituras (em segundos):
      READING_INTERVAL_SECONDS: 2
      

      Esse é o tempo em que o logger dorme antes de fazer uma nova leitura, mas cada leitura em si pode tomar um tempo mínimo de 3 s ou mais conforme sobrecarga de atividade do logger.
  • 2.4.4) Execute o logger:
    $ make log
    

Exemplo de uma iteração do logger:

-----------------------------------------------------
Serial<id=0x2b3b6a480ef0, open=True>(port='/dev/ttyACM0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1.5, xonxoff=True, rtscts=False, dsrdtr=False)
sent 'DHT22_TEMP,DHT22_AH,BMP085_PRESSURE,LDR': 39
read:  b'20.700001,64.500000,101930,519\r\n'
csv_result:  20.700001,64.500000,101930,519 <class 'str'>

JSON raw sensor data:
{'datetime': '20150513045531',
 'sensors': {'BMP085_PRESSURE': 101930,
             'DHT22_AH': 64.5,
             'DHT22_TEMP': 20.700001,
             'LDR': 519}}

Writed data log onto
    /home/nelso/cta-emm-web/meteorolog/datalog.csv

Sending data to the server now.. done.
    <Response [200]>

Going to sleep now for 2 seconds..
Em suma, as seguintes coisas aconteceram:
  • (i) Foi enviada a seguinte linha para a serial:
    DHT22_TEMP,DHT22_AH,BMP085_PRESSURE,LDR
    
  • (ii) Foi obtida a seguinte resposta:
    20.700001,64.500000,101930,519
    
  • (iii) Essa resposta foi guardada em um arquivo local datalog.csv no seguinte formato:
    20150513045531    20.700001    64.5    101930    519
    

    onde a primeira coluna é o datetime (data + hora lidos da própria máquina), e as demais são as medidas respectivas de temperatura (ºC), umidade relativa do ar (), pressão (Pa) e luminosidade () obtidas da placa;
  • (iv) Um objeto JSON foi criado contendo as leituras:
    {'datetime': '20150513045531',
     'sensors': {'BMP085_PRESSURE': 101930,
                 'DHT22_AH': 64.5,
                 'DHT22_TEMP': 20.700001,
                 'LDR': 519}}
    

    Esse formato é adequado para o envio de dados para o servidor web (próxima etapa)
  • (v) O objeto JSON foi enviado para o servidor; a resposta obtida foi
    <Response [200]>
    

    Código 200 significa sucesso no envio.
  • (vi) O logger dorme por um certo tempo, conforme configurado em settings.py; passado esse tempo, o processo é reiniciado a partir de uma nova leitura da placa.

Contatos

(mantenedor atual)

Overview técnico (para desenvolvedores)

Teste simples

1. Instalar Python 3
sudo apt-get install python3

2. Instalar PIP (gerenciador de pacotes do Python)
sudo apt-get install python3-pip

3. Instalar virtualenv (cria ambientes virtuais de Python)
sudo pip3 install virtualenv

4. Criar um ambiente virtual usando Python 3
virtualenv --python=python3 venv

5. Ativar o ambiente virtual
source venv/bin/activate

6. Instalar requisitos do ambiente Python
pip install -r requirements.pip

7. Executar o Logger (dentro do ambiente virtual)
python meteorolog.py

arduino-meteorolog.tar.gz (12 MB) Nelso G. Jost, 16/05/2015 13:41

board-proto.svg (434.4 kB) Nelso G. Jost, 25/06/2015 06:11

arduino_upload_button_cut.png (4 kB) Nelso G. Jost, 25/06/2015 09:18

serial-monitor-button-cut.JPG (8.9 kB) Nelso G. Jost, 25/06/2015 09:20

CDS-Photoresistor-LDR.jpg (16 kB) Nelso G. Jost, 25/06/2015 09:32

dht22.jpg (9.4 kB) Nelso G. Jost, 25/06/2015 09:41

bmp085-2-500x500.jpg (132.6 kB) Nelso G. Jost, 25/06/2015 09:50