Meteorolog

Protótipo de sistema de aquisição de dados meteorológicos baseados em Arduino controlado por um miniPC Rikomagic MK802. Compilação de projetos e pesquisa desenvolvidos por Leonardo Alves, Lucas Leal e Renan Bohrer, orientação Rafael Pezzi.

Licença do Software, GPL V3 quando cabível. Diagramas, Imagens e explicações Creative Commons - BY-SA. Amostras de dados coletados dedicados ao domínio público.

Diagrama esboçado no KiCad

Esquema KiCAD Estação Meteorolog - Mini

Diagrama Arduino para KiCad por nicholasclewis CC-BY

Esquema esboçado no Fritzing

Esse esquema da estação é idêntico à este com a adição do módulo RTC.

Os links são para o esquemático e o programa de Arduino. Esse protótipo, assim como os anteriores, funciona junto do mini-pc e portanto o programa está adequado para esse tipo interface.

Esquemático: meteorolog-phi.fz

Programa para o arduino: meteorolog_2_0.ino

Protótipo Montado

Meteorolog - MiniPC MK802 + Arduino com Relay Shield

MiniProtoboard com Sensores Meteorolog

Software

O mini-pc MK802 está rodando uma versão do Ubuntu desenvolvida pela empresa Australiana Miniand. Está rodando um script de inicialização que mantem o serviço da registro da estação rodando em caso de falha de energia.

O software meteorolog está dividido em três componentes: 1) código de controle do Arduino, 2) logger dos dados meteorológico em python (para aquisição dos dados) e 3) programa para visualização e análise dos dados.

Código Arduino de controle da estação Meteorológica

Realiza medidas dos sensores de acordo com comandos de uma letra recebidos pela porta serial, retornando o valor numérico. Temperatura em Graus Celsius, Umidade Relativa do ar em %, Pressão em Pascal, Umidade do Solo e Luminosidade em unidades arbitrárias.

Utiliza biblioteca de controle do módulo DHT11 desenvolvida por Adafuit, disponível no Github. Código de controle do módulo BMP085 foi obtido deste link - este código também pode ser incluído em uma biblioteca para tornar o código mais legível e condensado.

meteorolog.ino

  1 
  2 // Interface de controle da estacao meteorologica meteorolog
  3 // Centro de Tecnologia Academica - UFRGS
  4 // http://cta.if.ufrgs.br - Março de 2013
  5 
  6 int soloPinVCC = 13; //Pino VCC do sensor de umidade do solo
  7 int soloPinleitura = 0; //Pino VCC do sensor de umidade do solo
  8 
  9 #define LDRpin 1
 10 #define PinoPiezo 9
 11 #define DHTPIN 4     // Pino de dados do DHT11
 12 
 13 // Para utilização do DHT11
 14 // Biblioteca desenvolvida por Adafuit
 15 // https://github.com/adafruit/DHT-sensor-library
 16 #include "DHT.h" 
 17 #define DHTTYPE DHT11   
 18 DHT dht(DHTPIN, DHTTYPE);
 19 
 20 // Configuracao do BMP085
 21 // Fonte: http://bildr.org/2011/06/bmp085-arduino/
 22 #include <Wire.h>
 23 #define BMP085_ADDRESS 0x77  // I2C address of BMP085
 24 const unsigned char OSS = 0;  // Oversampling Setting
 25 
 26 // Calibration values
 27 int ac1;
 28 int ac2;
 29 int ac3;
 30 unsigned int ac4;
 31 unsigned int ac5;
 32 unsigned int ac6;
 33 int b1;
 34 int b2;
 35 int mb;
 36 int mc;
 37 int md;
 38 
 39 // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
 40 // so ...Temperature(...) must be called before ...Pressure(...).
 41 long b5; 
 42 
 43 void setup()   { 
 44 
 45   //Inicialização do DHT11  
 46   dht.begin();
 47 
 48   // Configuração do BPM085
 49   Wire.begin();
 50   bmp085Calibration();
 51 
 52   Serial.begin(115200);  
 53 
 54   // Configura pino de alimentação do sensor de umidade do solo
 55   pinMode(soloPinVCC, OUTPUT);     
 56 }
 57 
 58 void loop()                     
 59 {
 60 
 61     if (Serial.available())
 62   {
 63     switch (Serial.read())
 64     {
 65     case 'p':
 66       pressao();
 67       break;
 68     case 'l':
 69       luminosidade();
 70       break;
 71     case 'u':
 72       umidade_ar();
 73       break;
 74     case 's':
 75       umidade_solo();      
 76       break;
 77     case 't':
 78       temperatura_BMP085();
 79       break;
 80     case 'T':
 81       leDHT11_temp();
 82       break;
 83     default:
 84       break;
 85     }
 86   }
 87 }
 88 
 89 void temperatura_BMP085()
 90 {
 91   float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
 92   Serial.println(temperature, 2); //display 2 decimal places
 93 }
 94 
 95 void pressao()
 96 {
 97   float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
 98   float pressure = bmp085GetPressure(bmp085ReadUP());
 99   Serial.println(pressure, 0); //whole number only.
100 
101 }
102 
103 void umidade_ar()
104 {
105   leDHT11_umid();  
106 }
107 
108 void luminosidade()
109 {
110  int lum=analogRead(LDRpin);
111  Serial.println(1023-lum);
112 }
113 
114 void umidade_solo()
115 {
116   digitalWrite(soloPinVCC,HIGH);
117   delay(300);
118   int us1 = analogRead(soloPinleitura);
119   delay(10);
120   int us2 = analogRead(soloPinleitura);
121   delay(10);
122   int us3 = analogRead(soloPinleitura);
123   delay(10);
124   int us4 = analogRead(soloPinleitura);
125   delay(10);
126   int us5 = analogRead(soloPinleitura);
127   int umidsolo = (us1+us2+us3+us4+us5)/5;  
128 //  Serial.print("Umidade do solo: ");
129   Serial.println(umidsolo);
130   digitalWrite(soloPinVCC,LOW);
131 }
132 
133 void leDHT11_temp()
134 {
135   // Reading temperature or humidity takes about 250 milliseconds!
136   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
137   float t = dht.readTemperature();
138 
139   // check if returns are valid, if they are NaN (not a number) then something went wrong!
140   if (isnan(t) ) {
141     Serial.println("Failed to read from DHT");
142   } else {
143 //    Serial.print("Temperatura: "); 
144     Serial.println(t);
145 //    Serial.println(" *C");
146   }
147 
148 }
149 
150 void leDHT11_umid()
151 {
152   // Reading temperature or humidity takes about 250 milliseconds!
153   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
154   float h = dht.readHumidity();
155 
156   // check if returns are valid, if they are NaN (not a number) then something went wrong!
157   if (isnan(h)) {
158     Serial.println("Failed to read from DHT");
159   } else {
160   //  Serial.print("Umidade relativa do ar: "); 
161     Serial.println(h);
162 //    Serial.println(" %\t");
163   }
164 
165 }
166 
167 // Stores all of the bmp085's calibration values into global variables
168 // Calibration values are required to calculate temp and pressure
169 // This function should be called at the beginning of the program
170 void bmp085Calibration()
171 {
172   ac1 = bmp085ReadInt(0xAA);
173   ac2 = bmp085ReadInt(0xAC);
174   ac3 = bmp085ReadInt(0xAE);
175   ac4 = bmp085ReadInt(0xB0);
176   ac5 = bmp085ReadInt(0xB2);
177   ac6 = bmp085ReadInt(0xB4);
178   b1 = bmp085ReadInt(0xB6);
179   b2 = bmp085ReadInt(0xB8);
180   mb = bmp085ReadInt(0xBA);
181   mc = bmp085ReadInt(0xBC);
182   md = bmp085ReadInt(0xBE);
183 }
184 
185 // Calculate temperature in deg C
186 float bmp085GetTemperature(unsigned int ut){
187   long x1, x2;
188 
189   x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
190   x2 = ((long)mc << 11)/(x1 + md);
191   b5 = x1 + x2;
192 
193   float temp = ((b5 + 8)>>4);
194   temp = temp /10;
195 
196   return temp;
197 }
198 
199 // Calculate pressure given up
200 // calibration values must be known
201 // b5 is also required so bmp085GetTemperature(...) must be called first.
202 // Value returned will be pressure in units of Pa.
203 long bmp085GetPressure(unsigned long up){
204   long x1, x2, x3, b3, b6, p;
205   unsigned long b4, b7;
206 
207   b6 = b5 - 4000;
208   // Calculate B3
209   x1 = (b2 * (b6 * b6)>>12)>>11;
210   x2 = (ac2 * b6)>>11;
211   x3 = x1 + x2;
212   b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
213 
214   // Calculate B4
215   x1 = (ac3 * b6)>>13;
216   x2 = (b1 * ((b6 * b6)>>12))>>16;
217   x3 = ((x1 + x2) + 2)>>2;
218   b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
219 
220   b7 = ((unsigned long)(up - b3) * (50000>>OSS));
221   if (b7 < 0x80000000)
222     p = (b7<<1)/b4;
223   else
224     p = (b7/b4)<<1;
225 
226   x1 = (p>>8) * (p>>8);
227   x1 = (x1 * 3038)>>16;
228   x2 = (-7357 * p)>>16;
229   p += (x1 + x2 + 3791)>>4;
230 
231   long temp = p;
232   return temp;
233 }
234 
235 // Read 1 byte from the BMP085 at 'address'
236 char bmp085Read(unsigned char address)
237 {
238   unsigned char data;
239 
240   Wire.beginTransmission(BMP085_ADDRESS);
241   Wire.write(address);
242   Wire.endTransmission();
243 
244   Wire.requestFrom(BMP085_ADDRESS, 1);
245   while(!Wire.available())
246     ;
247 
248   return Wire.read();
249 }
250 
251 // Read 2 bytes from the BMP085
252 // First byte will be from 'address'
253 // Second byte will be from 'address'+1
254 int bmp085ReadInt(unsigned char address)
255 {
256   unsigned char msb, lsb;
257 
258   Wire.beginTransmission(BMP085_ADDRESS);
259   Wire.write(address);
260   Wire.endTransmission();
261 
262   Wire.requestFrom(BMP085_ADDRESS, 2);
263   while(Wire.available()<2)
264     ;
265   msb = Wire.read();
266   lsb = Wire.read();
267 
268   return (int) msb<<8 | lsb;
269 }
270 
271 // Read the uncompensated temperature value
272 unsigned int bmp085ReadUT(){
273   unsigned int ut;
274 
275   // Write 0x2E into Register 0xF4
276   // This requests a temperature reading
277   Wire.beginTransmission(BMP085_ADDRESS);
278   Wire.write(0xF4);
279   Wire.write(0x2E);
280   Wire.endTransmission();
281 
282   // Wait at least 4.5ms
283   delay(5);
284 
285   // Read two bytes from registers 0xF6 and 0xF7
286   ut = bmp085ReadInt(0xF6);
287   return ut;
288 }
289 
290 // Read the uncompensated pressure value
291 unsigned long bmp085ReadUP(){
292 
293   unsigned char msb, lsb, xlsb;
294   unsigned long up = 0;
295 
296   // Write 0x34+(OSS<<6) into register 0xF4
297   // Request a pressure reading w/ oversampling setting
298   Wire.beginTransmission(BMP085_ADDRESS);
299   Wire.write(0xF4);
300   Wire.write(0x34 + (OSS<<6));
301   Wire.endTransmission();
302 
303   // Wait for conversion, delay time dependent on OSS
304   delay(2 + (3<<OSS));
305 
306   // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
307   msb = bmp085Read(0xF6);
308   lsb = bmp085Read(0xF7);
309   xlsb = bmp085Read(0xF8);
310 
311   up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
312 
313   return up;
314 }
315 
316 void writeRegister(int deviceAddress, byte address, byte val) {
317   Wire.beginTransmission(deviceAddress); // start transmission to device 
318   Wire.write(address);       // send register address
319   Wire.write(val);         // send value to write
320   Wire.endTransmission();     // end transmission
321 }
322 
323 int readRegister(int deviceAddress, byte address){
324 
325   int v;
326   Wire.beginTransmission(deviceAddress);
327   Wire.write(address); // register to read
328   Wire.endTransmission();
329 
330   Wire.requestFrom(deviceAddress, 1); // read a byte
331 
332   while(!Wire.available()) {
333     // waiting
334   }
335 
336   v = Wire.read();
337   return v;
338 }
339 
340 float calcAltitude(float pressure){
341 
342   float A = pressure/101325;
343   float B = 1/5.25588;
344   float C = pow(A,B);
345   C = 1 - C;
346   C = C /0.0000225577;
347 
348   return C;
349 }

Logger meteorolog em Python

Envia comandos de aquisição de dados ao Arduino, salvando periodicamente os resultados no arquivo logfile.log. Também mantém um registro das datas de inicialização do programa no arquivo meteorolog.log.

meteorolog.py

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 #
 4 # Controlador da estação meteorologica
 5 # Por Rafael Pezzi
 6 #  Centro de Tecnologia Acadêmica - UFRGS
 7 #  http://cta.if.ufrgs.br
 8 #
 9 # Licença: GPL v3
10 #
11 # Baseado em projeto de Gilson Giuriatti
12 #  https://github.com/gilsong/labduino
13 
14 from pylab import *
15 import time, serial, datetime
16 
17 ser = serial.Serial('/dev/ttyUSB0', 115200)
18 time.sleep(2)
19 
20 meteorologfile = open('/home/miniand/meteorolog/meteorolog.log','a')
21 now=datetime.datetime.now()
22 meteorologfile.write(now.strftime("%Y-%m-%d %H:%M:%S")+" - Iniciando log meteorológico\n")
23 
24 medida = []
25 temperatura = []
26 umidade_ar = []
27 umidade_solo = []
28 pressao = []
29 
30 print "Iniciando Log da Estação Meterológica" 
31 
32 while True:
33   try:
34     ser.write('t')
35     t = float(ser.readline().replace('\r\n',''))
36   except KeyboardInterrupt:
37     break
38 
39   try:
40     ser.write('u')
41     u_ar = float(ser.readline().replace('\r\n',''))
42   except KeyboardInterrupt:
43     break
44 
45   try:
46     ser.write('s')
47     u_s = int(ser.readline().replace('\r\n',''))
48   except KeyboardInterrupt:
49     break
50 
51   try:
52     ser.write('l')
53     lum = int(ser.readline().replace('\r\n',''))
54   except KeyboardInterrupt:
55     break
56 
57   try:
58     ser.write('p')
59     pressao = int(ser.readline().replace('\r\n',''))
60     now=datetime.datetime.now()
61     logfile = open('/home/miniand/meteorolog/logfile.log','a')
62     print now.strftime("%Y%m%d%H%M%S"),"\t",  t,"\t", u_ar,"\t", u_s, "\t", pressao, "\t", lum
63     logfile.write(now.strftime("%Y%m%d%H%M%S")+"\t"+str(t)+"\t"+str(u_ar)+"\t"+str(u_s)+"\t"+str(pressao)+"\t"+str(lum)+'\n')
64     logfile.close()
65     time.sleep(59)
66   except KeyboardInterrupt:
67     break
68 
69 ser.close();
70 

Programas de visualização

Dados utilizados:26-Fev-2013_-_04-Mar-2013.log

O programa abaixo converte o formato de data utilizado no log da estação para um formato "plotável".

dataplot.py

 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3 import matplotlib.dates as mdates
 4 
 5 data, temp, u_ar, u_solo, pressao, lum = np.loadtxt("26-Fev-2013_-_04-Mar-2013.log", unpack=True,
 6         converters={ 0: mdates.strpdate2num('%Y%m%d%H%M%S')})
 7 
 8 plt.figure(1)
 9 plt.plot_date(x=data, y=temp, fmt="r-")
10 plt.ylabel("Temperatura (C)")
11 plt.grid(True)
12 plt.show()
13 
14 plt.figure(2)
15 plt.plot_date(x=data, y=u_ar, fmt="r-")
16 plt.ylabel("Umidade relativa do ar (%)")
17 plt.grid(True)
18 plt.show()
19 
20 plt.figure(3)
21 plt.plot_date(x=data, y=u_solo, fmt="r-")
22 plt.ylabel("Umidade do solo (u.a.)")
23 plt.grid(True)
24 plt.show()
25 
26 plt.figure(4)
27 plt.plot_date(x=data, y=pressao, fmt="r-")
28 plt.ylabel("Pressao atmosferica (Pa)")
29 plt.grid(True)
30 plt.show()
31 
32 plt.figure(5)
33 plt.plot_date(x=data, y=lum, fmt="r-")
34 plt.ylabel("Luminosidade (u.a.)")
35 plt.grid(True)
36 plt.show()

O programa abaixo apresenta gráfico da serie temporal e histograma dos dados fornecidos, com intervalo de tempo programável

graficos.py

  1 # -*- coding:utf-8 -*-
  2 # Programa de visualização e estatísticas de dados meteorológicos 
  3 # coletados pela estação Meteorolog do Centro de Tecnologia Acadêmica
  4 # Dados no formato DataHora Temperatura Umidade_do_Ar Solo Pressão Luminosidade 
  5 # DataHora no formato  AAAAMMDDHHmmSS onde
  6 #          AAAA = Ano
  7 #          MM = Mês
  8 #          DD = Dia
  9 #          HH = Hora
 10 #          mm = Minuto
 11 #          ss = Segundo
 12 #
 13 # Mais informações:
 14 #  http://cta.if.ufrgs.br/projects/estacao-meteorologica-modular/wiki/Meteorolog
 15 #
 16 # Autor: Rafael Pezzi - Centro de Tecnologia Acadêmica - IF/UFRGS
 17 #
 18 # Este programa é softare livre, disponível sob os termos da
 19 # GNU Affero General Public License V3 
 20 # http://www.gnu.org/licenses/agpl-3.0.html
 21 
 22 import numpy as np
 23 import matplotlib.pyplot as plt
 24 import matplotlib.dates as mdates
 25 import random as random
 26 import datetime as datetime
 27 import sys , os
 28 
 29 print "Estatísticas Meteorológicas Meteorolog - Centro de Tecnologia Acadêmica" 
 30 
 31 # Testa se o número de argumentos está correto 
 32 if len(sys.argv) < 2:
 33     sys.stderr.write('Uso: python '+ sys.argv[0]+' arquivo_de_log\n' )
 34     sys.exit(1)
 35 # e se o arquivo de log existe
 36 if not os.path.exists(sys.argv[1]):
 37     sys.stderr.write('ERRO: Arquivo '+sys.argv[1]+' não encontrado!\n')
 38     sys.exit(1)
 39 
 40 # Ativa/desativa seleção de intervalo
 41 # Caso negativo (False), todos dados do arquivo de log serão computados
 42 #seleciona_intervalo = False
 43 seleciona_intervalo = True
 44 
 45 # Defina aqui o intervalo de tempo a se analisado
 46 #  TODO: Incluir seleção pela linha de comando de execução  
 47 sel_Inicio = datetime.datetime(2013,03,01,00,00,00)
 48 sel_Fim = datetime.datetime(2014,03,10,23,59,59)
 49 
 50 # Armazena os dados coletados em matrizes unidimensionais
 51 data, temp, u_ar, u_solo, pressao, lum = np.loadtxt(sys.argv[1], unpack=True,
 52         converters={ 0: mdates.strpdate2num('%Y%m%d%H%M%S')})
 53 
 54 ## Seria útil incluir um algoritmo de filtragem para remover pontos expurios 
 55 ##   observados em algumas partes por mil medidas de temperatura
 56 
 57 # Exibe informações dos dados
 58 print "Dados de "+str(mdates.num2date(data[0]).strftime('%Y-%m-%d %H:%M:%S'))+u" até "+str(mdates.num2date(data[len(data)-1]).strftime('%Y-%m-%d %H:%M:%S'))
 59 print "Série com "+str(len(data))+" amostras\n" 
 60 
 61 # Seleciona dados em um intervalo de tempo
 62 if (seleciona_intervalo == True):
 63 
 64     # Cria listas temporárias para seleção
 65     # Acho que pode ser otimizado, usando iteradores direto em arrays
 66     #  crítico para series de dados gigantes
 67     selec_data=[]; selec_temp=[];  selec_u_ar=[] 
 68     selec_u_solo=[]; selec_pressao=[]; selec_lum=[] 
 69     for j in enumerate(data):
 70         if mdates.date2num(sel_Inicio) <= j[1] <= mdates.date2num(sel_Fim):
 71             selec_data.append(data[j[0]])
 72             selec_temp.append(temp[j[0]])
 73             selec_u_ar.append(u_ar[j[0]])
 74             selec_u_solo.append(u_solo[j[0]])
 75             selec_pressao.append(pressao[j[0]])
 76             selec_lum.append(lum[j[0]])
 77 
 78     # Copia dados selecionados para matrizes originais
 79     data=np.asarray(selec_data)
 80     temp=np.asarray(selec_temp)
 81     u_ar=np.asarray(selec_u_ar)
 82     u_solo=np.asarray(selec_u_solo)
 83     pressao=np.asarray(selec_pressao)
 84     lum=np.asarray(selec_lum)
 85 
 86     # Exibe informações sobre o periodo selecionado
 87     print "Selecionado período:" 
 88     print str(sel_Inicio)+" até "+str(sel_Fim)
 89     print "Série com "+str(len(data))+" amostras\n" 
 90 
 91 ## Análise da temperatura
 92 T_min=temp.min()
 93 T_max=temp.max()
 94 T_med=temp.mean()
 95 T_std=temp.std()
 96 print "Temperatura: \nmin: "+str(T_min)+"°C\tmax: "+str(T_max)+"°C\tmédia: "+str("%.2f" % T_med)+"°C\tDesvio: "+str("%.1f" % T_std)+"°C" 
 97 
 98 ## Análise da umidade relativa do Ar
 99 U_ar_min=u_ar.min()
100 U_ar_max=u_ar.max()
101 U_ar_med=u_ar.mean()
102 U_ar_std=u_ar.std()
103 print "\nUmidade Relativa do Ar: \nmin: "+str(U_ar_min)+"%\tmax: "+str(U_ar_max)+"%\tmédia: "+str("%.1f" % U_ar_med)+"%\tDesvio: "+str("%.1f" % U_ar_std)+"%" 
104 
105 # Análise da pressão atomsférica
106 P_min=pressao.min()
107 P_max=pressao.max()
108 P_med=pressao.mean()
109 P_std=pressao.std()
110 
111 print "\nPressão: \nmin: "+str(int(P_min))+" Pa\tmax: "+str(int(P_max))+" Pa\tmédia: "+ str("%.0f" % P_med)+" Pa\tDesvio: "+str("%.2f" % P_std)+" Pa" 
112 
113 # Análise da luminosidade
114 L_min=lum.min()
115 L_max=lum.max()
116 L_med=lum.mean()
117 L_std=lum.std()
118 
119 print "\nLuminosidade: \nmin: "+str(int(L_min))+" u.a.\tmax: "+str(int(L_max))+" u.a.\tmédia: "+ str("%.0f" % L_med)+" u.a.\tDesvio: "+str("%.2f" % L_std)+" u.a." 
120 
121 # Apresentação de histrograma:
122 # Temperatura
123 plt.figure() # Cria nova figura
124 plt.ylabel(u"Número de eventos")
125 plt.xlabel(u"Temperatura (°C)")
126 plt.hist(temp,bins=25)
127 #Inclui título com média e desvio padrão
128 #plt.text(plt.xlim()[0]+0.5,0.9*plt.ylim()[1],u"Média: "+str("%.2f" % temp.mean())+u"°C\nDesvio Padrão: "+str("%.2f" % temp.std())+u"°C") # Este coloca dentro da figura
129 plt.title(u"Temperatura média: "+str("%.2f" % T_med)+u"°C  |  Desvio Padrão: "+str("%.2f" % temp.std())+u"°C")
130 plt.grid(True)
131 
132 # Apresentação de histrograma:
133 # Umidade Rel. do Ar
134 plt.figure()
135 plt.ylabel(u"Número de eventos")
136 plt.xlabel("Umidade Relativa (%)")
137 plt.hist(u_ar,bins=range(26,100,2))
138 #plt.text(plt.xlim()[0]+1,0.9*plt.ylim()[1],u"Média: "+str("%.2f" % u_ar.mean())+u" %\nDesvio Padrão: "+str("%.2f" % u_ar.std())+" %")
139 plt.title(u"UR média: "+str("%.2f" % u_ar.mean())+u" %  |  Desvio Padrão: "+str("%.2f" % u_ar.std())+" %")
140 plt.grid(True)
141 
142 # Apresentação de histrograma:
143 # Pressão
144 plt.figure()
145 plt.ylabel(u"Número de eventos")
146 plt.xlabel(u"Pressão atmosférica (Pa)")
147 plt.hist(pressao,bins=25)
148 #plt.text(1.001*plt.xlim()[0],0.9*plt.ylim()[1],u"Média: "+str("%.2f" % pressao.mean())+u" Pa\nDesvio Padrão: "+str("%.2f" % pressao.std())+" Pa")
149 plt.title(u"Pressão média: "+str("%.2f" % pressao.mean())+u" Pa  |  Desvio Padrão: "+str("%.2f" % pressao.std())+" Pa")
150 plt.grid(True)
151 
152 # Apresentação de histrograma:
153 # Luminosidade
154 plt.figure()
155 plt.ylabel(u"Número de eventos")
156 plt.xlabel(u"Luminosidade (u.a.)")
157 plt.hist(lum,bins=25)
158 #plt.text(1*plt.xlim()[0]+60,0.9*plt.ylim()[1],u"Média: "+str("%.2f" % lum.mean())+u"\nDesvio Padrão: "+str("%.2f" % lum.std())+" ")
159 plt.title(u"Luminosidade média: "+str("%.2f" % lum.mean())+u"  |  Desvio Padrão: "+str("%.2f" % lum.std())+" ")
160 plt.grid(True)
161 
162 ## Apresentação das series temporais de medidas
163 # Temperatura
164 plt.figure()
165 # Gira o texto do eixo temporal
166 plt.xticks(rotation=70)
167 plt.plot_date(x=data, y=temp, fmt="r.")
168 
169 # Define os limites temporais do gráfico 
170 #   útil para evitar escalas exageradas devido a dadas incorretas - ocorreu na estação sem relógio
171 plt.xlim(data[0], data[len(data)-1])
172 plt.ylabel(u"Temperatura (°C)")
173 plt.grid(True)
174 # Altera as margens para a margem inferior comportar a data
175 plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)
176 
177 # Umidade Relativa do Ar
178 plt.figure()
179 plt.xticks(rotation=70)
180 plt.plot_date(x=data, y=u_ar, fmt="r.")
181 plt.xlim(data[0], data[len(data)-1])
182 plt.ylabel("Umidade relativa do ar (%)")
183 plt.grid(True)
184 plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)
185 
186 '''
187 # Condutividade do solo
188 plt.figure()
189 plt.xticks(rotation=70)
190 plt.plot_date(x=data, y=u_solo, fmt="r.")
191 plt.xlim(data[0], data[len(data)-1])
192 plt.ylabel("Umidade do solo (u.a.)")
193 plt.grid(True)
194 plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)
195 '''
196 
197 # Pressão
198 plt.figure()
199 plt.xticks(rotation=70)
200 plt.plot_date(x=data, y=pressao, fmt="r.")
201 plt.xlim(data[0], data[len(data)-1])
202 plt.ylabel(u"Pressão atmosférica (Pa)")
203 plt.grid(True)
204 plt.subplots_adjust(left=0.13, right=0.9, top=0.9, bottom=0.2)
205 
206 # Luminosidade
207 plt.figure()
208 plt.xticks(rotation=70)
209 plt.plot_date(x=data, y=lum, fmt="r.")
210 plt.xlim(data[0], data[len(data)-1])
211 plt.ylabel("Luminosidade (u.a.)")
212 plt.grid(True)
213 plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)
214 
215 #Apresenta os gráficos gerados
216 plt.show()

Amostra de dados

Dados coletados entre os dias 26 de Fevereiro de 2013 e 04 de Março de 2013, em intervalos irregulares: 26-Fev-2013_-_04-Mar-2013.log. Abaixo gráficos condensados dos pontos medidos - sem calibração da escala de tempo.

Gráficos

Exemplo Temperatura

Exemplo Umidade Relativa do Ar

Exemplo Luminosidade

Exemplo Condutividade do Solo

Condutividade_Solo.png - Exemplo Condutividade do Solo (16.5 kB) Rafael Pezzi, 04/03/2013 22:08

26-Fev-2013_-_04-Mar-2013.log - Amostra de dados coletados (301 kB) Rafael Pezzi, 04/03/2013 22:08

Temperatura.png - Exemplo Temperatura (21.7 kB) Rafael Pezzi, 04/03/2013 22:08

Luminosidade.png - Exemplo Luminosidade (26.2 kB) Rafael Pezzi, 04/03/2013 22:08

Umidade_Ar.png - Exemplo Umidade Relativa do Ar (27 kB) Rafael Pezzi, 04/03/2013 22:08

Meteorolog-MiniPC_Arduino_Relay_Shield.JPG - Meteorolog - MiniPC MK802 + Arduino com Relay Shield (125.8 kB) Rafael Pezzi, 04/03/2013 22:26

Meteorolog-MiniProtoboard.JPG - MiniProtoboard com Sensores Meteorolog (101.1 kB) Rafael Pezzi, 04/03/2013 22:26

estação-arduino-CTA-proto1.png - Esquema KiCAD da Estação Meteorolog (19.6 kB) Rafael Pezzi, 04/03/2013 22:26

estação-arduino-CTA-proto1_mini.png - Esquema KiCAD Estação Meteorolog - Mini (77.6 kB) Rafael Pezzi, 04/03/2013 22:29

Pressão.png (19.5 kB) Rafael Pezzi, 05/03/2013 20:26

meteorolog.ino - Código Arduino da Estação Meteorológica (7.8 kB) Rafael Pezzi, 05/03/2013 22:10

meteorolog.py - Logger em Python da estação meteorológica (1.6 kB) Rafael Pezzi, 05/03/2013 22:10

dataplot.py (859 Bytes) Lucas Leal, 20/03/2013 09:14

temp.png (43.2 kB) Lucas Leal, 20/03/2013 09:14

u_solo.png (36.3 kB) Lucas Leal, 20/03/2013 09:14

u_ar.png (48.1 kB) Lucas Leal, 20/03/2013 09:14

pressao.png (47 kB) Lucas Leal, 20/03/2013 09:14

lum.png (48.9 kB) Lucas Leal, 20/03/2013 09:14

meteorolog-phi.png (230.8 kB) Lucas Leal, 27/05/2013 13:08

meteorolog-phi_schem.jpg (95.8 kB) Lucas Leal, 07/06/2013 17:52

graficos.py - Cria gráficos temporais e histogramas da serie de medidas com limites programáveis (7.7 kB) Rafael Pezzi, 10/06/2013 18:02

meteorolog-schem.jpg (27.4 kB) Lucas Leal, 11/06/2013 16:31

meteorolog-phi.fz (319 kB) Lucas Leal, 11/06/2013 16:31

meteorolog-schem.jpg (51.9 kB) Lucas Leal, 11/06/2013 16:34

meteorolog-schem.jpg (51.3 kB) Lucas Leal, 13/06/2013 18:23

meteorolog-phi.fz (374.5 kB) Lucas Leal, 13/06/2013 18:23

meteorolog_2_0.ino (10 kB) Lucas Leal, 13/06/2013 18:23