Pocketbeagle board – Como fazê-la falar as informações do clima

A Pocketbeagle Board é, no momento da escrita deste artigo, a placa mais nova da linha das placas Beaglebone. Dentre seus atrativos, destacam-se o diminuto tamanho físico e o uso de um SiP da Octavo muito similar ao das famosas BeagleBone Black. Partindo do princípio que esta é uma placa compacta e com considerável poder computacional, este artigo mostrará um projeto muito interessante com ela: uma central de informações de clima, que não somente exibe as informações, mas sim as fala!

Material necessário

Para reproduzir este projeto, será necessário:

  • Uma placa Pocketbeagle Board operacional (com sistema operacional instalado no cartão SD), com barras de pinos soldadas;
  • Um display OLED 0.96″ I²C (da cor que desejar);
  • Uma placa de som USB;
  • Um cabo adaptador micro-USB;
  • Uma placa breakout USB;
  • Jumpers macho-fêmea.

Circuito esquemático

O circuito esquemático do projeto pode ser visto na figura 1.

Circuito esquemático.
Figura 1 – Circuito esquemático.

Observações:

  • A placa de som USB deve ser ligada no cabo adaptador micro-USB e este, por sua vez, ligado à placa breakout USB;
  • Pode-se ligar ou caixas de som de computadores convencionais ou fones de ouvido à saída de som da placa de som USB. Fica à sua escolha.

Pocketbeagle board – Preparação

Antes de prosseguir com o projeto em si, deve-se realizar uma preparação na Pocketbeagle board (ou seja, bibliotecas devem ser instalas e configurações devem ser feitas).

Conectividade à Internet

Para garantir conectividade à Internet com a Pocketbeagle board, siga as instruções deste artigo. 

Seleção da placa de som USB

Na distribuição Debian da Pocketbeagle board, por default, a placa de som USB não é automaticamente selecionada como placa de som principal. Desta forma, é necessário que a configuração para que esta seja a placa principal de som seja feita. Para isso, o primeiro passo é verificar se a placa de som foi ao menos reconhecida como dispositivo USB. Para isso, utilize o comando abaixo:

lsusb

Ele irá produzir uma saída conforme mostrado na figura 2. Nesta figura, nota-se que a placa de som foi reconhecida (C-Media Electronics, Inc. CM108 Audio Controller), logo ela pode ser utilizada pelo sistema operacional.

Detecção da placa de som USB como dispositivo USB válido.
Figura 2 – Detecção da placa de som USB como dispositivo USB válido.

Uma vez com a certeza de que a placa de som foi reconhecida, pode-se avançar para a configuração desta como placa principal. Para isso, deve-se criar o arquivo .asoundrc no diretório /home/debian. Trata-se do arquivo de configuração a ser lido pelo ALSA. Para fazer isso, execute os comandos abaixo:

cd /home/debian
nano .asoundrc

No editor de texto nano, cole o código abaixo (verifique o id de sua placa de som com o comando aplay -l):

pcm.!default
{
  type plug
  slave
  {
    pcm "hw:1,0" # hw:1:0 
  }
}
ctl.!default
{
  type hw
  card 1 # change card number if necessary
}

Salve e saia do editor nano (aperte Ctrl+X e depois Ctrl+Y). Pronto, agora sua placa de som USB está configurada como placa de som principal do sistema. 

Instalação de bibliotecas

Para o projeto, serão necessárias as bibliotecas para utilizar o display OLED, text-to-speech (gTTS), player de áudio mpg123 e a biblioteca para fazer requisições HTTP. Todas estas são bibliotecas Python. Execute os comandos abaixo para realizar as instalações:

  • Biblioteca para display OLED:
    sudo apt-get update
    sudo apt-get install build-essential python-dev python-pip
    sudo pip install Adafruit_BBIO
    sudo apt-get install python-imaging python-smbus
    sudo apt-get install git
    git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
    cd Adafruit_Python_SSD1306
    sudo python setup.py install
  • Biblioteca text-to-speech e player de áudio mpg123:
    sudo pip install gTTS
    sudo apt-get install mpg321
  • Biblioteca para requisições HTTP:
sudo pip install requests

Obtenção de acesso à API OpenWeather e download de fontes TTF para o Display

Para obter acesso à API OpenWeather e ter orientações do download de fontes TTF para o display, faça a leitura deste artigo.

Código-fonte do projeto

Finalmente, é chegada a hora do código-fonte do projeto. Primeiramente, é preciso criar um script para fazer o text-to-speech somente (servirá como um “módulo” do projeto). Para isso, crie um script Python com o nome text_to_speech.py (com o comando nano text_to_speech.py) e cole o código abaixo. 

from gtts import gTTS
import os

def TextToSpeech_ptbr(texto):
   AudioDoTexto = gTTS(text=texto, lang='pt')
   AudioDoTexto.save("/tmp/audio.mp3")
   os.system("mpg321 /tmp/audio.mp3")
   return

Feito isso, salva e saia do nano (aperte Ctrl + X e Ctrl + Y).

Agora, crie um script Python com o nome clima_oled_audio.py (com o comando nano clima_oled_audio.py) e cole o código abaixo.

IMPORTANTE: NÂO SE ESQUEÇA de substituir sua API key do OpenWeather API no código! Se isto for esquecido, nada irá funcionar.

import Adafruit_SSD1306
import requests
import json
import time
from text_to_speech import TextToSpeech_ptbr

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

#Configuracao do pino de reset do display (utilizado apenas para comunicacao via SPI, porem de 
#uso obrigatorio nas funcoes da biblioteca
RST = 'P9_12'

#configuracao do pino de leitura do sensor de temperatura
pin = 'P8_11'

#display 128x64 (no barramento 2 da I2C, no endereco 0x3c)
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3c, i2c_bus=2)

#demais variaveis globais
api_key_openweather = "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" #Coloque aqui a sua api key!!
cidade = "Campinas"  #para nomes com espaco, substitua o espaco por %20
pais = "br"

def le_infos_clima():
    global api_key_openweather
    global cidade
    global pais

    url_http_req = "https://api.openweathermap.org/data/2.5/weather?q="+cidade+","+pais+"&appid="+api_key_openweather
    dados_clima = requests.get(url_http_req).json()

    #parser das informacoes desejadas do JSON
    temp_atual_kelvin = dados_clima["main"]["temp"]
    umidade = dados_clima["main"]["humidity"]
    nebulosidade = dados_clima["clouds"]["all"]
    vel_vento = dados_clima["wind"]["speed"]
    angulo_vento = dados_clima["wind"]["deg"]

    temp_atual_celsius = int(float(temp_atual_kelvin) - 273.15)
    umidade_atual = int(umidade)
    nebulosidade = int(nebulosidade)
    vel_vento_atual = float(vel_vento)
    angulo_vento_atual = int(float(angulo_vento))
    return temp_atual_celsius,umidade,nebulosidade,vel_vento_atual,angulo_vento_atual


############################
### PROGRAMA PRINCIPAL  ####
############################

#Inicializacoes de display
disp.begin()
disp.clear()
disp.display()

#Cria area de imagem para escrita / desenho no display
width = disp.width
height = disp.height
image = Image.new('1', (width, height)) #imagem binaria (somente 1's e 0's)

#Determina a area a ser desenhada / escrita
draw = ImageDraw.Draw(image)

#definicoes uteis do display (para localizacao no mesmo)
padding = 2
shape_width = 20
top = padding
bottom = height-padding
x = padding

#Carrega fonte padrao do display
font = ImageFont.load_default()

#variavel de controle de leituras
leitura = 0

#Fonte da temperatura: fonte ttf que simula display 7 segmentos, com tamanho 30
font_temp = ImageFont.truetype('ManualDisplay.ttf', 45)

#Fonte da umidade: fonte ttf que simula display 7 segmentos, com tamanho 16
font_umid = ImageFont.truetype('ManualDisplay.ttf', 16)

#Fonte da nebulosidade: fonte ttf que simula display 7 segmentos, com tamanho 16
font_neb = ImageFont.truetype('ManualDisplay.ttf', 16)

#Fonte da velocidade do vento: fonte ttf que simula display 7 segmentos, com tamanho 16
font_vel_vento = ImageFont.truetype('ManualDisplay.ttf', 16)

#Fonte do angulo do vento: fonte ttf que simula display 7 segmentos, com tamanho 16
font_ang_vento = ImageFont.truetype('ManualDisplay.ttf', 16)

#Fonte dos titulos das informacoes
font_titulos = ImageFont.truetype('Minecraftia-Regular.ttf', 8)

#Fonte do titulo da tela (display)
font_titulo_tela = ImageFont.truetype('Minecraftia-Regular.ttf', 8)

while (True):
      try:
        #requisita informacoes da API e faz parser do json, filtrando as informacoes desejadas (temperatura, umidade e nebulosidade
        (temp,umidade,nebulosidade,vel_vento,ang_vento) = le_infos_clima()
        leitura = leitura + 1

        temperatura_str = str(temp)+"C"
        umidade_str = str(umidade)+"%"
        nebulosidade_str = str(nebulosidade)+"%"
        vel_vento_str = str(vel_vento)
        ang_vento_str = str(ang_vento)
        cidade_str_replace = cidade.replace("%20"," ")

        #escreve as informacoes lidas e a cidade referida
        print ""
        print "Leitura: "+str(leitura)
        print ""
        print "Cidade: "+cidade_str_replace+","+pais
        print "Temperatura atual: "+temperatura_str
        print "Umidade relativa do ar: "+umidade_str
        print "Nebulosidade: "+nebulosidade_str
        print "Velocidade do vento: "+vel_vento_str
        print "Angulo do vento: "+ang_vento_str

        #Escreve informacoes no display OLED
        draw.rectangle((0,0,width-1,height-1), outline=255, fill=0)
        draw.rectangle((0,0,width-1,15), outline=255, fill=0)
        draw.rectangle((0,15,65,height-1), outline=255, fill=0)
        disp.image(image)
        disp.display()

        draw.text((x, top),    "Clima:    "+cidade_str_replace,  font=font_titulo_tela, fill=255)
        draw.text((x, top+15), "Temp.",font=font_titulos,fill=255)
        draw.text((x+5, top+25), temperatura_str, font=font_temp, fill=255)

        draw.text((x+65, top+15), "Umid.",font=font_titulos,fill=255)
        draw.text((x+65, top+25), umidade_str, font=font_umid, fill=255)
        draw.text((x+65, top+40), "Neb.",font=font_titulos,fill=255)
        draw.text((x+65, top+48), nebulosidade_str, font=font_neb, fill=255)

        draw.text((x+95, top+15), "Vento",font=font_titulos,fill=255)
        draw.text((x+95, top+25), vel_vento_str, font=font_vel_vento, fill=255)
        draw.text((x+95, top+40), "Ang",font=font_titulos,fill=255)
        draw.text((x+95, top+48), ang_vento_str, font=font_ang_vento, fill=255)

        disp.image(image)
        disp.display()


        #fala as informacoes climaticas
        string_para_falar = "Agora em "+cidade_str_replace+" a temperatura eh "+str(temp)+" graus Celsius. A umidade relativa do ar eh "+umidade_str+". A nebulosidade eh "+nebulosidade_str+". O vento tem velocidade de "+vel_vento_str+" metros por segundo a "+ang_vento_str+" graus"
        TextToSpeech_ptbr(string_para_falar)

        time.sleep(90)

        #Limpa display: desenha um retangulo preto em todo o display (para apagar "restos" de dados na area de imagem)
        draw.rectangle((0,0,width,height), outline=0, fill=0)
      except KeyboardInterrupt:
        print "Aplicacao encerrada."
        exit(1)

Para rodar o projeto, utilize o comando abaixo:

python clima_oled_audio.py

Projeto em ação!

Veja o vídeo abaixo do projeto em ação:

Saiba mais

PocketBeagle – Nova placa da Beagleboard

Conectando a Photon ao Twitter por IFTTT

CHIP – Um computador de $9

Referências

https://www.hackster.io/beaglefriends-octavosystems/adding-text-to-speech-to-pocketbeagle-projects-3ab078
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Inscrever-se
Notificar de
0 Comentários
mais recentes
mais antigos Mais votado
Home » Linux Embarcado » Pocketbeagle board – Como fazê-la falar as informações do clima

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: