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¶
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¶
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.
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.
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".
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
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.