Esse projeto faz a previsão do tempo baseado na diferença da pressão atmosférica. Eu costumo manter ele ligado e vejo que ele tem acertado bastante nos últimos dias, mas eu não apostaria todas as minhas fichas nele... Afinal de contas, quem consegue acertar a previsão do tempo ?

http://youtu.be/EZEcis8_g8o

Componentes:
- Arduino
- Display Nokia 5110
- Sensor barométrico BMP085
- Buzzer
- Resistor 300u

Seguem as conexões:

- pino CLK do lcd - ligar no pino 3 do arduino

- pino DIN do lcd - ligar no pino 4 do arduino
- pino DC do lcd - ligar no pino 5 do arduino

- pino CE do lcd - ligar no pino 7 do arduino
- pino RST do lcd - ligar no pino 6 do arduino
- pino BL do lcd - ligar no pino 2 do arduino
- pino GND do lcd - ligar no GND do arduino

- pino positivo do buzzer - ligar no pino 8 do arduino

- pino negativo do buzzer - ligar no pino GND do arduino

- polo 1 do botão - ligar no pino 9 do arduino e no polo 1 do resistor

- polo 2 do botão - ligar no pino 5v do arduini

- pino SLC do barômetro - ligar no pino A5 do arduino
- pino SDA do barômetro - ligar no pino A4 do arduino
- pino 5v do barômetro - ligar no pino 5v do arduino
- pino GND do barômetro - ligar no GND do arduino

- polo 1 do resistor - ligar no polo 1 do botão

- polo 2 do resistor - ligar no GND do arduino

Bibliotecas:

Adafruit_GFX.h Adafruit.zip
Adafruit_PCD8544.h Adafruit_PCD8544.zip
pitches.h Pitches.zip
Wire.h Wire.zip
Adafruit_BMP085.h BMP085.zip
EEPROM.h EEPROM.zip

Esquema:

esquema.png

E o código:

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include "pitches.h" //biblioteca para emitir notas musicais
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <EEPROM.h>
Adafruit_BMP085 bmp;
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6); //CLK DIN DC CE RST
//Other Settings
int contraste = 40;
int led = 2;
int boxval[8];
int pos[8] = {4,14,24,34,44,54,64,74};
int i,j,dot,c = 1,t,u,v,cont = 0;
int dotval[80];
float maxval, minval, medval;
int est_led = 0;
String sit = "Sem alteracao";
String sitant = "";
String func = "detalhes";
int bfunc = 9;
int est_bfunc = 0;
int func_cont = 1;
int buzz = 8; //som
int prev_cont, detalhes_cont, temporeal_cont, historico_cont;
float temperature, pressure, sealevel, altitude, altreal;

void setup(){
  Serial.begin(9600);
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    while (1) {}
  }
  beep(2);
  pinMode(led, OUTPUT);
  pinMode(bfunc, INPUT);
  pinMode(buzz, OUTPUT);
  display.begin();
  display.setContrast(contraste); //Ajusta o contraste do display
  display.clearDisplay();
  display.display();
  //a primeira vez, coleta os dados
  lesensor(); //Lê dados do BMP085
  medval = EEPROM.read(1); //le a valor medio
  if (medval == 0) medval = pressure;
  EEPROM.write(1,medval); //grava medval
  maxval = pressure;
  minval = pressure;
}

void loop(){

  lesensor(); //Lê dados do BMP085
  //////////////////////////////////////
  //Cálculo da previsão do tempo
  //////////////////////////////////////
  
  if (pressure > maxval) maxval = pressure;
  if (pressure < minval) minval = pressure;
  if (maxval - medval >= 600) alert(" ERRO ");
  if (maxval - medval >= 550 && maxval - medval <= 599) alert(" Tempo BOM ");
  if (maxval - medval >= 500 && maxval - medval <= 549) alert(" Tempo BOM ");
  if (maxval - medval >= 450 && maxval - medval <= 499) alert(" Tempo BOM ");
  if (maxval - medval >= 400 && maxval - medval <= 449) alert(" Tempo BOM ");
  if (maxval - medval >= 350 && maxval - medval <= 399) alert(" Tempo BOM ");
  if (maxval - medval >= 300 && maxval - medval <= 349) alert(" Tempo BOM ");
  if (maxval - medval >= 200 && maxval - medval <= 299) alert(" Tempo seco ");
  if (maxval - medval >= 100 && maxval - medval <= 199) alert("Sem alteracao");
  if (medval - minval >= 200 && medval - minval <= 299) alert(" Chuva fraca ");
  if (medval - minval >= 300 && medval - minval <= 399) alert(" Chuva forte ");
  if (medval - minval >= 400 && medval - minval <= 499) alert("Chuva torrenc");
  if (medval - minval >= 500 && medval - minval <= 599) alert(" TEMPESTADE ");
  if (medval - minval >= 600) alert(" ERRO ");
  //////////////////////////////////////
  //Detecta alteração de função
  //////////////////////////////////////
  est_bfunc = digitalRead(bfunc);
  if (est_bfunc == HIGH){
    display.clearDisplay();
    func_cont = func_cont + 1;
    if (func_cont == 1) func = "detalhes";
    if (func_cont == 2) func = "previsao";
    if (func_cont == 3) func = "temporeal";
    if (func_cont == 4) func = "historico";
    if (func_cont == 5) func = "cled";
    if (func_cont >= 6) func = "reset";
    if (func_cont >= 7) {func = "detalhes";func_cont = 1;}
    beep(1);
    delay(150);
  }

  if (func == "detalhes"){
    display.clearDisplay();
    t = 0; //zera o controle do led
    u = 0; //zera o controle do reset
    v = 0; //zera o contador do controle do som
    detalhes_cont = detalhes_cont + 1;
    if (detalhes_cont >= 10) {
      detalhes();
      display.clearDisplay();
      detalhes_cont = 0;
    }
  }
  if (func == "previsao") previsao();
  if (func == "temporeal"){
    temporeal_cont = temporeal_cont + 1;
    if (temporeal_cont >= 10) {
      temporeal();
      temporeal_cont = 0;
    }
  }
  if (func == "historico"){
    historico_cont = historico_cont + 1;
    if (historico_cont >= 20){
      historico();
      historico_cont = 0;
    }
  }
  if (func == "cled") cled();
  if (func == "reset") reset();
}

void beep(int tipo){
  if (tipo == 1){
    tone(buzz, NOTE_DS8,8);
    delay(20);
    noTone(buzz);
  }
  if (tipo == 2){
    int melody[] = {NOTE_DS8, NOTE_A7, NOTE_F7, NOTE_C7, NOTE_C6};
    int noteDurations[] = { 8, 8, 8, 8, 4, 4 };
    for (int thisNote = 0; thisNote < 5; thisNote++) {
      int noteDuration = 1000/noteDurations[thisNote];
      tone(buzz, melody[thisNote],noteDuration);
      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);
      noTone(buzz);
    }
  }
}

void detalhes(){
  display.drawRoundRect(0,0,84,48,1,BLACK);
  display.setCursor(3,3);
  display.print("Temp: ");
  display.print(temperature, 1); //display 2 decimal places
  display.print("c");
  display.setCursor(3,13);
  display.print("Pres: ");
  display.print(pressure / 100, 0); //whole number only.
  display.print("mPa");
  display.setCursor(3,23);
  display.print("nMAR: ");
  display.print(sealevel, 2); //display 4 decimal places
  display.setCursor(3,33);
  display.print("Alt : ");
  display.print(altreal, 2); //display 2 decimal places
  display.print("M");
  display.display();
  display.clearDisplay();
}

void previsao(){
  display.drawRoundRect(0,0,84,48,1,BLACK);
  display.setCursor(3,4);
  display.print("==Previsao==");
  display.setCursor(3,13);
  display.setTextColor(WHITE, BLACK);
  display.print(sit);
  display.setTextColor(BLACK);
  display.drawRect(3,25,78,21,BLACK);
  display.drawLine(3,35,78,35,BLACK);
  display.drawLine(29,25,29,45,BLACK);
  display.drawLine(55,25,55,45,BLACK);
  display.setCursor(5,27);
  display.print("Min");
  display.setCursor(31,27);
  display.print("Med");
  display.setCursor(57,27);
  display.print("Max");
  display.setCursor(5,37);
  display.print(int(minval/100));
  display.setCursor(31,37);
  display.print(int(medval/100));
  display.setCursor(57,37);
  display.print(int(maxval/100));
  display.display();
}

void temporeal(){
  int box = map(pressure,medval-200,medval+200,0,25);
  display.setCursor(0,0);
  display.print("T.Real:");
  display.fillRect(50,0,50,10,WHITE);
  display.setCursor(42,0);
  display.print(pressure / 100);
  display.drawLine(0,10,0,42,BLACK);
  display.drawLine(0,42,84,42,BLACK);
  display.setCursor(0,44);
  display.print("| | | | | | |");
  if (cont<=7){ // desenha os 8 primeiros boxes
    display.fillRect(pos[cont],40-box,6,box,BLACK);
    boxval[cont] = box;
    cont = cont + 1;
  }
  else {
    for (i=0;i<=7;i++){
      display.fillRect(pos[i],15,6,25,WHITE);
      display.fillRect(pos[i],40-boxval[i+1],6,boxval[i+1],BLACK);
      boxval[i] = boxval[i+1];
      display.display();
    }
    display.fillRect(pos[7],15,6,25,WHITE);
    display.fillRect(pos[7],40-box,6,box,BLACK);
    boxval[7] = box;
  }

  display.display();
}

void historico(){
  dot = map(pressure,medval-500,medval+500,0,25);
  display.setCursor(0,0);
  display.print("Hist:");
  display.fillRect(50,0,50,10,WHITE);
  display.setCursor(42,0);
  display.print(pressure / 100);
  display.drawLine(0,10,0,42,BLACK);
  display.drawLine(0,42,84,42,BLACK);
  if (c<=79){ // desenha as 80 primeiras linhas
    display.drawFastVLine(c,40-dot,1,BLACK);
    dotval[c] = dot;
    c = c + 1;
  }
  else {
    for (i=1;i<=79;i++){
      display.drawFastVLine(i,15,25,WHITE);
      display.drawFastVLine(i,40-dotval[i+1],1,BLACK);
      dotval[i] = dotval[i+1];
      display.display();
    }
    display.drawFastVLine(80,15,25,WHITE);
    display.drawFastVLine(80,40-dot,1,BLACK);
    dotval[79] = dot;
  }
  display.display();
}

void cled(){
  display.setCursor(0,0);
  if (est_led == 0){
    display.print("Acendendo LED");
    display.setCursor(14,36);
    display.setTextColor(WHITE, BLACK);
    display.print(" Cancela ");
    display.setTextColor(BLACK);
    display.drawRect(22,15,40,10,BLACK);
    display.display();
    t = t + 1;
    delay(100);
    display.fillRect(17+(t*2.5),15,5,10,BLACK);
    display.display();
    if (t >= 16) {
      digitalWrite(led, HIGH);
      func = "detalhes";
      est_led = 1;
      func_cont = 7;
      t = 0;
    }
  }
  else {
    display.print("Apagando LED..");
    display.setCursor(14,36);
    display.setTextColor(WHITE, BLACK);
    display.print(" Cancela ");
    display.setTextColor(BLACK);
    display.drawRect(22,15,40,10,BLACK);
    display.display();
    t = t + 1;
    delay(100);
    display.fillRect(17+(t*2.5),15,5,10,BLACK);
    display.display();
    if (t >= 16) {
      digitalWrite(led, LOW);
      func = "detalhes";
      est_led = 0;
      func_cont = 7;
      t = 0;
    }
  }
}

void reset(){
  display.setCursor(0,0);
  display.print("Resetando...");
  display.setCursor(14,36);
  display.setTextColor(WHITE, BLACK);
  display.print(" Cancela ");
  display.setTextColor(BLACK);
  display.drawRect(22,15,40,10,BLACK);
  display.display();
  u = u + 1;
  delay(100);
  display.fillRect(18+(u*2.5),15,5,10,BLACK);
  display.display();
  if (u >= 16) {
    EEPROM.write(1,0); //reset medval
    func = "detalhes";
    func_cont = 7;
    u=0;
  }
}

void alert(String sit1){
  if (sit1 != sitant){
    sit = sit1;
    func = "previsao";
    beep(2);
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);
    delay(80);
    digitalWrite(led, HIGH);
    est_led = 1;
  }
  sitant = sit1;
}

void lesensor(){
  temperature = bmp.readTemperature();
  pressure = bmp.readPressure();
  altitude = bmp.readAltitude();
  sealevel = int(bmp.readSealevelPressure()/100);
  altreal = bmp.readAltitude(101500);
}

Boa sorte !

Exibições: 3021

Comentar

Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!

Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)

Comentário de Flavio da Silva Ribeiro em 21 maio 2020 às 14:21

Parabéns pelo projeto.

Também estou desenvolvendo uma estação meteorologica experimental com arduino. A Estação Meteorológica Mandacaru. http://labdegaragem.com/group/estacao-meteorologica-arduino/forum/t...

Certamente vou tentar implementar essas funcionalidades do seu projeto em minha estação experimental.

Muito obrigado por compartilhar.

Comentário de Alan David em 14 maio 2015 às 19:48

Ola amigo teu projeto ta show. Gostaria de uma ajuda tua, gostaria de mostrar o valor de corrente lido em um sensor de corrente na tela. Poderia me ajudar? Segue o link da discussão que abri aqui no Lab. Desde ja agradeço. 

http://labdegaragem.com/forum/topics/autonomia-de-bateria

ja fiz alumas alteraçoes desde a proposta inicial. Mas realente o que ta pegando e colocar o valor na tela.

Comentário de Glauco Poltronieri em 28 outubro 2014 às 22:15

Pessoal, Boa Noite, Chegou da Polonia ontem um brinquefo que comprei, trata-se de um Igate para Aprs (Radioamadorismo) e nele tem uma conexão para estação meteorológica ou telemetria, porem teria que desenvolver o projeto, eles ate vendem uma interface para colocar um sensor Db18....porem custa caro e demora mais de 30 dias pra chegar, gostaria de saber se alguém tem o projeto de alguma estação meteorológica para fornecer, de preferencia completa, lembrando que tem uma entrada RS-232 para ligara estação.

O nome do brinquedo é Microsat WX3IN1 MINI e o site para quem quiser visitar é www.microsat.com.pl

Obrigado a todos pela oportunidade....

Comentário de Murilo Lima Nogueira em 6 outubro 2014 às 20:47

Charles Vassiliades, parabéns pelo projeto, percebi que você gosta de Estação Meteorológica. Por isso te convido á participar do grupo "Estação Meteorológica - Arduino", a fim de discutirmos e criarmos uma estação completa com arduino. Conto com a sua participação.

http://labdegaragem.com/group/estacao-meteorologica-arduino

Abraços,

Atenciosamente Murilo Lima Nogueira.

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço