Projectos maker para o estágio de Verão Ciência Viva 2018 / LIP

Fernando Barão, Catarina Espírito-Santo, Ana Sofia Nunes
LIP - Lab de Instrumentação e Partículas
Julho 2018

Índice

  1. Introdução a Python
  2. Quanto vale pi? Simular e calcular com números aleatórios...
  3. Realização de um semáforo de três cores
  4. Estação meteorológica: temperatura e humidade...
  5. Saber mais sobre o Raspberry Pi, breadboard, ...
  6. Outros Projectos

1. Introdução a Python

material
raspberry pi + teclado + rato
linguagem de programação Python3

Definir variáveis em python e utilizar o módulo matemático (math)

No início da primeira lição aprendemos a usar o interpretador de python e concluímos que o mais confortável é criarmos um ficheiro com o auxílio do editor de texto, nano, e introduzirmos lá o código que pretendemos correr. É isso que vamos fazer agora criando o ficheiro t1.py, onde vamos calcular o coseno de um dado valor em radianos. O valor é fornecido ao programa a partir do teclado.

Para editarmos o ficheiro t1.py escrevemos na linha de comando linux,

 $ nano t1.py

e de seguida introduzimos as seguintes linhas de programação python no ficheiro:

  # importamos o modulo matematico onde esta a funcao cos()
  import math
  # associamos a variável x ao valor de entrada / nota: conversão para real feita pela função float()
  x = float(input("angulo: "))
  # calculamos o coseno
  cx = math.cos(x)
  # imprimimos uma mensagem que seja clara
  print("O coseno do angulo ", x, " em radianos é = ", cx )

E finalmente para corrermos o ficheiro e vermos o resultado,

 $ python3 t1.py
 angulo: 2.3
 O coseno do angulo  2.3  em radianos é =  -0.6662760212798241

Definir ciclos e testar condições

Vamos agora criar um programa python que seja capaz de somar os números inteiros de 1 a 100. No final, queremos testar se o resultado é superior ao número 1000 ou não.

  # inicilaizar a variavel que contem a soma
  soma = 0
  for x in range(1,101):
     soma += x
  if soma>1000:
     print(soma)

Definir funções e módulos do utilizador

Em python as funções que podem retornar algo ou não, criam-se com def. Vamos criar um ficheiro com o nome pyfun.py, com o auxílio do editor nano, que contenha todas as funções que vamos desenvolver neste estágio. Poderemos assim criar o nosso próprio módulo pyfun que podemos importar (import) em programas python.

Vamos então editar o pyfun.py integrando lá as seguintes funções:

 import math

 def cos(x):
   x = float(input("angulo: "))
   cx = math.cos(x)
   print("O coseno do angulo ", x, " em radianos é = ", cx )
   return cx

 def soma(x,y):
   c = x + y
   print("a soma de ", x, " e de ", y, " dá a soma ", c)
   return c

Para utilizarmos as funções definidas no módulo pyfun basta fazermos o seguinte programa teste, t2.py:

 import math
 import pyfun

 x = float(input("angulo: "))
 pyfun.cos(x)
 x,y = float(input("soma de a,b :"))
 pyfun.soma(x,y)

2. Quanto vale pi? Simular e calcular com números aleatórios...

Ir para o Índice

material

Como gerar números aleatórios?

Ir para o Índice

O que é que a palavra aleatório te sugere?...
Por exemplo nesta semana que vais estar connosco irás muito provavelmente sentar-se sempre na mesma mesa, possivelmente no mesmo banco,...**isto é o oposto de aleatório**. O teu lugar é completamente previsível...
Portanto gerar um número aleatório, significa algo competamente imprevisível!!!
Mas o que é muito interessante é que esta imprevisibilidade pode-nos ajudar a fazer cálculos. Como por exemplo a calcular o valor de pi!!!! O número mágico que está em tantas eequações da física. Que está por exemplo na definição da área de um círculo, \begin{equation} Área = \pi \, Raio^2 \end{equation}

Para gerarmos um número completamente imprevisível (o completamente é eventualmente excessivo...) entre 1 e 10, teremos que usar o módulo random de python e fazemos,

  python
  >>> import random
  >>> i = random.randint(1,10)

Agora imagina um quadrado dividido em 100 células (10x10). Para localizarmos cada célula usaremos uma notação do tipo (i,j). Por isso a primeira célula do canto inferior esquerdo será definida por (1,1). Pensa nas outras...
O exercício é agora escolhermos aleatoriamente uma célula. Mas como?
Fácil, gerando dois número aleatórios entre 1 e 10...
Tenta fazer o seguinte programa!!!!

Biblioteca gráfica turtle

Ir para o Índice

E agora chega mais uma coisa interessante que é aprendermos a desenhar graficamente com python. Vamos querer desenhar um quadrado, e cada vez que uma célula for escolhida colocamos uma côr na célula, o que nos permitirá facilmente identificar a célula que foi escolhida de forma imprevisível!!!

Vamos começar por lançar o python e importar a biblioteca turtle para a podermos utilizar de seguida,

  python
  >>> import turtle
  >>> turtle.color("blue")
  >>> turtle.pensize(10)
  >>> turtle.hideturtle()

E agora vamos desenhar um quadrado,

  >>> turtle.forward(100)
  >>> turtle.left(90)
  >>> turtle.forward(100)
  >>> turtle.left(90)
  >>> turtle.forward(100)
  >>> turtle.left(90)
  >>> turtle.forward(100)
  >>> turtle.left(90)

Para obter ajuda sobre como utilizar uma função,

  >>> help("turtle.forward")

Para apagarmos o desenho,

  >>> turtle.reset()

Para levantarmos a caneta e a podermos deslocar sem desenhar, colocá-la numa dada posição e descê-la de novo para começar a desenhar,

  >>> turtle.penup()
  >>> turtle.setpos(-200,-180)
  >>> turtle.pendown()

Mais avançado ainda, podemos agrupar um conjunto de instruções que tem um dado objectivo e definir uma função. Por exemplo neste caso, para definirmos uma função quadrado que desenhe um quadrado e que tem como argumento o número de células do quadrado,

def quadrado(lado):
    for a in range(4):
        turtle.fd(lado)
        turtle.left(90)

quadrado(100)

E finalmente para desenharmos uma grelha de quadrados,

for col in range(10):
    for row in range(10):
        # draw a square here

Programa python

Este programa foi desenvolvido com os participantes no Estágio/2018 e teve as seguintes ideias chave para o seu desenvolvimento:

import random
import pyfun
import turtle
import os
import time

lado = 10 # numero de celulas
Nt=1000000 # numero de lancamentos
Nc = 0 # numero de pontos no interior do circulo
ampli = 50

# offset para desenho do quadrado no ecran
xoffset = +0.5*lado*ampli
yoffset = +0.5*lado*ampli

# desenhar o quadrado
turtle.color("red","blue")
turtle.penup()
turtle.setup(width=900,height=900)
turtle.pensize(4)
turtle.setpos(-xoffset, +yoffset)
turtle.pendown()
turtle.fd(ampli*lado)
turtle.right(90)
turtle.fd(ampli*lado)
turtle.right(90)
turtle.fd(ampli*lado)
turtle.right(90)
turtle.fd(ampli*lado)

# desenhar linhas
for i in range(1,int(lado/2)+1):
    turtle.penup()
    turtle.right(90)
    turtle.fd(ampli*lado/lado)
    turtle.pendown()
    turtle.right(90)
    turtle.fd(ampli*lado)
    turtle.penup()
    turtle.left(90)
    turtle.fd(ampli*lado/lado)
    turtle.pendown()
    turtle.left(90)
    turtle.fd(ampli*lado)

# retomar posicao de origem
turtle.penup()
turtle.setpos(-xoffset, +yoffset)
turtle.right(180)

for i in range(1,int(lado/2)+1):
    turtle.fd(ampli*lado/lado)
    turtle.pendown()
    turtle.left(90)
    turtle.fd(ampli*lado)
    turtle.penup()
    turtle.right(90)
    turtle.fd(ampli*lado/lado)
    turtle.pendown()
    turtle.right(90)
    turtle.fd(ampli*lado)
    turtle.left(90)

# geracao dos aleatorios
for i in range(1,Nt+1):
    x,y,xc,yc = pyfun.GetParRandom(1,lado)
    c = pyfun.Circle(lado/2,lado/2.,lado/2.,xc,yc)
    print(c)
    # desenhar celula e colorir
    turtle.color("red","blue")
    turtle.penup()
    turtle.setpos(-xoffset+ampli*x,-yoffset+y*ampli)
    turtle.begin_fill()
    turtle.fd(ampli*lado/lado)
    turtle.right(90)
    turtle.fd(ampli*lado/lado)
    turtle.right(90)
    turtle.fd(ampli*lado/lado)
    turtle.right(90)
    turtle.fd(ampli*lado/lado)
    turtle.right(90)
    turtle.end_fill()
    if c:
        Nc += 1
        # desenhar celula e colorir
        turtle.color("red","green")
        turtle.penup()
        turtle.setpos(-xoffset+ampli*x,-yoffset+y*ampli)
        turtle.begin_fill()
        turtle.fd(ampli*lado/lado)
        turtle.right(90)
        turtle.fd(ampli*lado/lado)
        turtle.right(90)
        turtle.fd(ampli*lado/lado)
        turtle.right(90)
        turtle.fd(ampli*lado/lado)
        turtle.right(90)
        turtle.end_fill()

print("Nt,Nc=",Nt,Nc)
pi = 4.*Nc/Nt
print("pi=",pi)

GPIO: General purpose input/output

Ir para o Índice O conjunto de pins existentes no Raspberry Pi (40 pins) constituem uma interface utilizável entre o computador e o utilizador. Poderemos desta forma, usar o computador para controlar circuitos eléctricos, motores, sensores, etc. que queiramos ligar ao Raspberry Pi. Há pins que providenciam:

Como iluminar um LED com o raspberry pi

Ir para o Índice

Já deves ter ouvido falar de LED's a propósito de TV's ou da iluminação lá de casa. Quando usados na iluminação de casa, os LED's revelam-se muito económicos. E com uma grande vantatgem em relação às lâmpadas de filamento (incandescência) que se calhar nem conheces (porque antigas): duram muito mais...

Nós aqui pretendemos utilizar os LED's para aprender a utilizar os Raspberry Pi e os seus pins GPIO como controladores. Estes dispositivos são muito usados em electrónica para assinalar que um aparelho electrónico se encontra ligado! Os LED's têm a particularidade de ser feitos de material dito semi-condutor em que a passagem de electrões provoca a emissão de luz.

Mas os LED's são sensíveis! Não podem ter um número excessivo de electrões a atravessá-los. Por isso na montagem básica que envolve um LED, existe sempre uma resistência eléctrica para limitar o número de electrões que passam.

Conheces a lei de Ohm? \begin{equation} V = R I \end{equation} A corrente eléctrica corresponde ao número de electrões por segundo que passam no LED.
A unidade de corrente eléctrica utilizada é o Ampère = A. Por isso a corrente eléctrica é a quantidade que queremos limitar. \begin{equation} I = \frac{V}{R} < 20 \, mA \end{equation}

Precisamos de ter em conta a tensão do LED (Vled), que depende da sua côr:

Atenção, podes medir este valor com o multímetro digital que existe no laboratório. Tenta!!!!
Procura o símbolo do díodo (-|>|-) no multímetro e desloca o botão selector para aí.
A ponta de prova vermelha do mutímetro liga-se ao ânodo e a preta ao cátodo (perna curta do díodo).

  1. Portanto se o nosso circuito LED for alimentado por 3.3V (a tensão existente no pin GPIOn), começa por calcular qual a resistência eléctrica que teremos que colocar para limitar a corrente.
  2. Liga de seguida o pin GPIO 2 ao LED (atenção que o LED tem uma perna mais comprida que a outra). A perna mais comprida (ânodo) deve-se ligar ao pin GPIO e depois à resistência eléctrica.
  3. Para fecharmos o circuito (os electrões passam no LED e na resistência e voltam a entrar no Raspberry Pi), teremos que ligar ao pin GND.
  4. Agora temos que fazer um pequeno programa na linguagem Python que permita ligar o LED. Vamos para isso utilizar a biblioteca gpiozero que já está instalada no Raspberry Pi.

Vamos então calcular a resistência a colocar em série: \begin{equation} R = \frac{V-V_{LED}}{0.02} \end{equation}

Completa a tabela no teu caderno:

LED Resistência
vermelho 50 ohms
amarelo
azul

Programação da activação do LED em python

Ir para o Índice

Abre um Terminal para poderes escrever comandos. E escreve python

  python

Agora vamos importar a biblioteca LED que está no modulo gpiozero

  >>> from gpiozero import LED

Como ligámos o pin 2 GPIO, temos que informar o Rasberry Pi disso! A maneira de o fazer é definir uma variável nossa, neste caso chamamos led.

  >>> led = LED(2)

E agora só falta activar a saída 2, ou seja activar a pilha! A função on() fará isso.

  >>> led.on()

E finalmente desligar a pilha, ou seja, desactivar o pin 2. A função off() fará isso.

  >>> led.off()

Foi fácil???!!!! Senão revê os passos e faz de novo...

O teu segundo programa em Python...

Ir para o Índice

O conjunto de instruções que fomos fazendo anteriormente podem agora ser todas juntas e colocadas num ficheiro.
Como se trata de um programa em Python, vamos colocar no nome do ficheiro uma extensao .py

Vamos então editar o ficheiro LED_1.py
Vamos usar para isso o edito simples nano

  nano LED_1.py

Vamos colocar todas as instruções anteriores e ainda vamos adicionar mais uma ideia ao programa. Queremos que o LED acenda e apague cada segundo e para sempre....Por isso vais fazer um ciclo e utilizar uma nova biblioteca chamada time, que permite adormecer o programa 1 segundo,

  from gpiozero import LED
  import time # nota as duas maneiras diferentes de importar os modulos!

  led = LED(2)

  while True:
    led.on()
    time.sleep(1)
    led.off()
    time.sleep(1)

Salva o ficheiro e corre agora o programa,

   python LED_1.py

E agora estás a ver o LED a acender, a apagar, a acender, a apagar, ....!!!!!


3. Realização de um semáforo com três cores (verde/amarelo/vermelho)

Ir para o Índice

material

Construção de um sistema de controlo de tráfego com luz, som, e possibilidade de intervenção do utilizador

Vamos agora usar os conhecimentos adquiridos acima para criar um sistema de controlo de tráfego em que:

Esta é a proposta base, mas outras ideias e variantes são também bem vindas!

Utilizar um interruptor para controlar o LED

Ir para o Índice

Comecemos por testar o interruptor de controlo. O que pretendemos é utilizar o interruptor para controlar o acendimento do LED. Ou seja, neste caso, estamos a dar o poder final de acender o LED ao utilizador. Claro que, tivémos que activar a alimentação do circuito através do raspberry pi e do programa python.

Na breadboard, onde já tens o LED ligado ao pin GPIO 2, ligamos agora o interruptor (em série).

Faz um programa em python que active o circuito e onde o LED acenda cada vez que carregarmos no interruptor.

E agora podemos complicar um pouco mais o nosso circuito. Como? Porque usaremos o raspberry pi para controlar o interruptor, isto é, saber o estado do interruptor. Poderemos assim dentro do programa saber quando o interruptor está para baixo ou para cima! Vê o que faz a função Button.wait_for_press(),

help("Button.wait_for_press()")

O programa python que vamos desenvolver agora é mais complexo. Temos que controlar o LED (led) e o estado do interruptor (Button). Para isso ligaremos o LED a um pin GPIO (o número 2) e o interruptor a um outro pin (o número 17, por exemplo). Ou seja, teremos dois circuitos.

  1. o circuito do LED, que é constituído pelo LED e por uma resistência ligados a um pin GPIO e à massa (Terra, potencial zero).
  2. o circuito do interruptor, que é ligado directamente a um pin GPIO e à massa

Faremos ainda um ciclo infinito (perigoso em programação mas aqui podemos sempre abortá-lo com o ctrl-C), dentro do qual o LED acenderá sempre que carregarmos no interruptor.

import time
from gpiozero import LED, Button

led = LED(2)  # ligamos o LED ao pin GPIO 2
button = Button(17)  # ligamos o INTERRUPTOR ao pin GPIO 17

while True:
  button.wait_for_press() # esperamos pela ligação do interruptor
  led.on()  # ligar LED
  time.sleep(2)  # esperar 2 segundos com o LED ligado
  led.off() # desligar o LED
  time.sleep(2)  # esperar 2 segundos com o LED desligado

Observas o que esperarias? (Experimenta ainda substituir as linhas de código dentro do While por:

  led.toggle()
  time.sleep(0.5)

Utilização do avisador sonoro (besouro)

Ir para o Índice

Vamos agora juntar um sinal de aviso sonoro ao sistema. Para tal vamos utilizar um besouro que emite um sinal sonoro quando é atravessado por corrente eléctrica. Para controlarmos o besouro vamos fazer um circuito em que este é ligado à massa e a um pin GPIO (por exemplo, o número 4). Colocaremos ainda o interruptor tal como em cima com o LED, para controlarmos a emissão do aviso sonoro. Portanto o programa python tbesouro.py, deve fazer o seguinte:

Completa o programa:

from time import sleep
from gpiozero import Buzzer, Button, LED

buzzer = Buzzer(4)
button = Button(p4)
led= LED(2)

while True:
   button.wait_for_press()
   ...

4. Estação meteorológica simples: uso de sensores para medida da temperatura, humidade, detecçao de chuva,...

material

Elementos adicionais de programação Python

     // a instalação do software deve ser feita pelos monitores
     $ sudo su
     // instalar o git
     $ apt-get update
     $ apt-get install -y git-core
     $ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
     // install auxiliary tools, change directory and install library
     $ apt-get install build-essential python-dev
     $ cd Adafruit_Python_DHT
     $ python setup.py install
     $ sudo su
     $ apt-get install -y python-matplotlib

Teste a biblioteca,

  python
  >>> import matplotlib
  >>> print matplotlib.__version__

Introdução

Nas actividades realizadas anteriormente, vimos como usando um computador (neste caso o Raspberry Pi) e e a linguagem de programação (neste caso o Python) podemos controlar dispositivos eléctricos ou electro-mecânicos — nestes exemplos, LEDs e buzzers, mas existe uma infinidade de outras possibilidades! Vimos também como dar ao utilizador a possibilidade de, através dos RPi e do Python, controlar directamente esses dispositivos — utilizando um interruptor que lhe permite influenciar o seu estado segundo normas pré-definidas e programadas no código Python de controlo.

Muitas vezes, é também útil e necessário utilizar dispositivos que nos dão informação sobre o estado do nosso sistema ou do ambiente em seu redor, podendo depois o utilizador ou o próprio sistema reagir de acordo com a informação recebida. Estes dispositivos, genericamente designados sensores, podem medir as quantidades mais variadas. Por exemplo, temperatura, orientação no espaço, velocidade, existência de campos magnéticos, quantidade de radiação de um determinado tipo a que o sistema está sujeito, etc.

Os detectores de física de partículas usam sensores para recolher os sinais deixados pelas partículas que os atravessam — e que podem ser sinais luminosos, eléctricos. etc. É a recolha destes sinais que nos permite depois reconstruir as propriedades das partículas. Por outro lado, utilizamos sensores e outros dispositivos no sistema de monitorização e controlo do detector, que nos permite fazê-lo funcionar e garantir que permanece em boas condições.

O sistema de controlo permite-nos, por exemplo, ligar e desligar as altas tensões necessárias ao funcionamento do detector. Ou, por meio de um conjunto de sensores colocados no próprio detector, avaliar se as temperaturas permanecem em valores adequados — accionando um alarme ou um sistema de reacção se algo de anormal acontecer.

Neste projecto, vamos agora usar o Raspberry Pi, alguns sensores ambientais, e a linguagem de programação Python para criar uma versão simples de uma estação meteorológica. E assim podemos guardar os valores medidos num ficheiro e mostrarmos graficamente os resultados com o auxílio da biblioteca matplotlib, muito usada em Física!

Sensor de temperatura e humidade

Em particular, vamos utilizar o sensor digital de temperatura e humidade DHT11. Para utilizarmos este sensor, temos primeiro de ter em atenção o modo como deve ser conectado. O DHT11 tem três pins: alimentação (Vcc), ligação à massa (GND) e a leitura de saída. Coloca o sensor na placa breadboard e faz as ligações adequadas:

Vamos ver como ler o sensor,

 import Adafruit_DHT
 import time

 # ler temperatura e humidade com o GPIO 12 ligado à saída do sensor
 humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 12)

e associar à leitura dos sensores um tag temporal (ANO MES DIA HORA MINUTOS SEGUNDOS),

 import datetime
 data = datetime.datetime.now()
 print(data)

Se corrermos este último programa obtemos,

 2018-07-05 09:00:13.361201

Vamos agora escrever um pequeno programa para recolher os valores lidos pelo sensor a associar a cada medida uma data. Experimenta primeiro escrevê-los sequencialmente para o écran (por exemplo, de 30 em 30 segundos). Depois, escreve estes valores para um ficheiro (por exemplo, de 5 em 5 minutos).

from __future__ import print_function # for python2 (old fashion guys)
f = open('/home/pi/CV2018/meteo_data.txt','a')
pin = 12
date0 = datetime.datetime.now()
while True:
    time.sleep(10) # just read every 10 seconds
    date = datetime.datetime.now()
    humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, pin) # ler valores
    elapsedTime = date - date0
    time_minutes, time_seconds = divmod(elapsedTime.total_seconds(), 60)
    if time_minutes > 5 :
       print(date, humidity, temperature, file=f)
       date0 = = datetime.datetime.now()
    else if time_minutes == 0 and time_seconds > 30 :
       print(date, humidity, temperature)
       date0 = = datetime.datetime.now()
    else :
       print('.', end='')

f.close()

Antes de avançares para a representação gráfica dos resultados, podes fazer algumas experiências. Por exemplo:

Sensor de chuva

Vamos agora experimentar um sensor de chuva. O sensor funciona com uma resistência eléctrica que varia com a presença de água. Do ponto de vista do controlo no raspberry pi, o sinal GPIO estará no estado "HIGH" se não houver chuva e "LOW" se houver.

Este sensor vai indicar-nos que está a chover se for, por exemplo, borrifado com algumas (poucas!) gotas de água. Podemos por exemplo accionar um aviso (primeiro, um aviso para o écran, e depois um buzzer ou LED) caso chova.

O sensor de chuva possui uma pequena placa de electrńica que faz a interface com os raspberry pi. Essa placa tem três pinos:

O nosso programa python, à semelhança do que já fizémos atrás, irá testar em contínuo o estado da saída. Se for "HIGH", isto é "True" do ponto de vista do programa, então não temos chuva. Do ponto de vista lógico se nos sentirmos mais confortáveis com a lógica contrária que é termos "True" quando está a chover, podemos fazer isso no programa:

 import time
 from gpiozero import Buzzer, InputDevice

 pinRAIN = 17
 pinBUZZER = 13
 buzz    = Buzzer(pinBUZZER)
 rain = not bool(InputDevice(pinRAIN))

 # ler em contínuo o sensor
 while True:
    if rain.is_active:
        print("está a chover...")
        for i in range(1,10):
           buzz.on()
           sleep(0.1)
           buzz.off()
           sleep(0.1)

matplotlib: uma maneira gráfica de mostrar resultados...

Vamos agora ler o ficheiro que contem os dados registados e plotar (anglicismo: "make a plot*) os resultados numa forma gráfica atraente. Aqui podem dar livre curso à imaginação e não se esqueçam de consulta o google, DuckDuckGo, ou outro motor de busca qualquer (eu prefiro o pato).

 import matplotlib.pyplot as plt
 import signal

 with open("/home/pi/CV2018/meteo_data.txt") as f:
    lines = f.readlines()
    data = [line.split()[0] for line in lines]
    humidity = [line.split()[1] for line in lines]
    temperature = [line.split()[2] for line in lines]

 fig = plt.figure()

 ax1 = fig.add_subplot(111)

 ax1.set_title("estacao metereologica")
 ax1.set_xlabel('tempo')
 ax1.set_ylabel('temperature')

 ax1.plot(data,temperature, c='r', label='temperatura')

 leg = ax1.legend()
 # beautify the x-labels
 plt.gcf().autofmt_xdate()
 plt.show()

 signal.pause()

Raspberry Pi, breadborad, ...

Ir para o Índice

Esquema de pins GPIO


Breadboard



Outros projectos e documentação

Ir para o Índice

Sensor de temperatura analógico e ADC


material

Documentação


Documentação


Os endereços IP dos raspberry pi 3+ na sala de Ensino:


Fernando Barão
Catarina Espírito-Santo
LIP - Lab de Instrumentação e Partículas
Julho 2018