2019年7月15日星期一

Weather Station With Data Logging


This weather station project is still in the making. This is only first part. Upgrades will be uploaded in next one or two months.

Step 1: Materials


Nearly all needed materials for this project can be bought on online store: DFRobot
For this project we will need:

-Weather station kit
-Arduino SD card modul
-SD card
-Solar power manager
-5V 1A Solar panel
-Some nylon cable ties-Mounting kit
-LCD display
-Breadboard
-Li- ion batteries (I used Sanyo 3.7V 2250mAh batteries)
-Waterproof plastic junction box
-Some wires
-Resistors (2x 10kOhm)

Step 2: Modules

For this project I used two different modules.

Solar power manager
This module can be powered with two different supplys, 3.7V battery, 4.5V - 6V solar panel or USB cable.
It has two diffrent outputs. 5V USB output which can be used for supplying Arduino or some other controller and 5V pins for powering different modules and sensors.

Specifications:
Solar Input Voltage (SOLAR IN): 4.5V~6V
Battery Input (BAT IN): 3.7V Single cell Li-polymer/Li-ion
BatteryCharge Current(USB/SOLAR IN): 900mA Max trickle charging, constant current, constant voltage three phases charging
Charging Cutoff Voltage (USB/SOLAR IN): 4.2V±1%
Regulated Power Supply: 5V 1A
Regulated Power Supply Efficiency (3.7V BAT IN): 86%@50%Load
USB/Solar Charge Efficiency: 73%@3.7V 900mA BAT IN

SD module
This module is fully compatible with Arduino. It allows you to add mass storage and data logging to your project.
I used it for collecting data from weather station with 16GB SD card.

Specifications:
Break out board for standard SD card and Micro SD (TF) card
Contains a switch to select the flash card slot
Sits directly on a Arduino
Also be used with other microcontrollers

Step 3: Weather Station Kit

The main component for this project is weather station kit. It is powered by 5V from Arduino or you can also use external 5V supply.
It has 4 pins (5V, GND, TX, RX). TXD data port uses 9600bps.

Weather station kit consist of:
Anemometer
Wind vane
Rain bucket
Sensor Board
Stainless steel studdle (30CM)(11.81")
Component package
It can be used to measure:
Wind speed
Wind direction
Amount of rainfall

It has build in humidity and temperature sensor which can also measure barometric pressure.
Anemometer can measure wind speed up to 25 m/s. Wind direction is displayed in degrees.
More info about this kit and sample code can be found on: DFRobot wiki

Step 4: How to Assemble Weather Station Kit


The assembly of this kit is quite easy but for more info about assembly watch a tutorial on how to assemble this kit.

Tutorial: How to assemble weather station kit


Step 5: Supply and Housing



Battery:
For this project I used 3.7V li-ion batteries. I made battery pack from 5x of this batteries. Every battery has about 2250 mAh, so a pack of 5x gives about 11250 mAh when connected in parallel.
Connection: As I mentioned I connected batteries in parallel, because in parallel you keep the original voltage but gain greater battery capacity. For example: If you have two 3.7V 2000 mAh battery and you connect it in parallel you will get 3.7V and 4000 mAh.
If you want to achive greater voltage then you need to connect them in series. For example: If you connect two 3.7V 2000 mAh battery in series you will get 7,4V and 2000 mAh.

Solar panel:

I used 5V 1A solar panel. This panel has about max 5W of output power. Output voltage goes up to 6V. When I tested panel in cloudy weather its output voltage was about 5.8-5.9V.
But if you want to fully supply this weather station with solar energy you need to add 1 or 2 solar panels and lead-acid battery or something else to store energy and to supply station when there is no sun.

HOUSING:
It doesn't seems but housing is one of the most important parts of this system, because it protects vital components from outside elements.

So I choose waterproof plastic junction box. It has just large enough to fit all the components inside. It is about 19x15 cm.

Step 6: Wiring and Code



Arduino:

All the components are connected with Arduino.
-SD module:
5V -> 5V
GND -> GND
MOSI -> digital pin 9
MISO -> digital pin 11
SCK -> digital pin 12
SS -> digital pin 10
Weather station board:
5V -> 5V
GND -> GND
TX -> RX on Arduino
RX -> TX on Arduino

Battery pack is connected directly to power manager (3.7V battery input). I also made connection from battery to analog pin A0 on Arduino for voltage monitoring.
Solar panel is connected directy to this modul (solar input). Solar panel is also connected to voltage divider. Voltage divider output is connected to analog pin A1 on Arduino.

I also made connection so that you can connect LCD display on it to check the voltage. So LCD is connected to 5V, GND and SDA from LCD goes to SDA on Arduino and the same with SCK pin.

Arduino is connected to power manager module with USB cable.

CODE:

Code for this weather station can found on DFRobot wiki. I also attached my code with all the upgrades.
-If you want to get the right wind direction for your position, you need to manualy change degress values in the program.
So all the data is stored into txt file named test. You can rename this file if you want. I writes all the possible values from weather station and it also writes in battery voltage and solar voltage. So that you can see how is the consumption of battery.

Step 7: Measuring Voltage and Testing




I needed to make voltage monitoring on battery and solar panel for my project.

For monitoring the voltage on battery I used analog pin. I connected + from battery to analog pin A0 and - from battery to GND on Arduino. In programm I used "analogRead" function and "lcd.print()" for displaying voltage value on LCD. Third picture shows voltage on battery. I measured it with Arduino and also with multimeter so that I could compare the value. Difference between this two values was about 0.04V.

Because output voltage from solar panel is greater than 5V I neede to make voltage divider. Analog input can take maximum of 5V input voltage. I made it with two 10kOhm resistor. Use of two resistor with equal value, divides voltage exactly to half. So if you connect 5V, output voltage will be about 2.5V. This voltage divider is on the first picture. Difference between voltage value on LCD and on multimeter was about 0.1-0.2V
Equasion for voltage divider output is: Vout=(Vcc*R2)/R1+R2

Testing
When I connected everything together and packed all the components into housing I needed to make outside test. So I took out weather station outside to see how it will work in real outside conditions. The main purpose of this test was to see how will batteries work or how much it will discharge during this test. While testing outside temperature was about 1°C outside and about 4°C inside the housing.

Battery voltage dropped from 3.58 to about 3.47 in five hours.

Code

#include <SD.h>   //SD
#include <SPI.h>  //SD

File myFile;      //SD

int pinCS = 10;
////////////
//LCD
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BACKLIGHT_PIN 3

LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
///////////
int sensorPin = A0;    //battery voltage pin
int sensorValue = 0;
/////////////////// 
int sensorPin_solar = A1;  //solar panel voltage pin
int sensorValue_solar = 0;
////////////////

char                 databuffer[35];
double               temp;

void getBuffer()                                                                    //Get weather status data
{
  int index;
  for (index = 0;index < 35;index ++)
  {
    if(Serial.available())
    {
      databuffer[index] = Serial.read();
      if (databuffer[0] != 'c')
      {
        index = -1;
      }
    }
    else
    {
      index --;
    }
  }
}

int transCharToInt(char *_buffer,int _start,int _stop)                               //char to int)
{
  int _index;
  int result = 0;
  int num = _stop - _start + 1;
  int _temp[num];
  for (_index = _start;_index <= _stop;_index ++)
  {
    _temp[_index - _start] = _buffer[_index] - '0';
    result = 10*result + _temp[_index - _start];
  }
  return result;
}

int WindDirection()                                                                  //Wind Direction
{
  return transCharToInt(databuffer,1,3);
}

float WindSpeedAverage()                                                             //air Speed (1 minute)
{
  temp = 0.44704 * transCharToInt(databuffer,5,7);
  return temp;
}

float WindSpeedMax()                                                                 //Max air speed (5 minutes)
{
  temp = 0.44704 * transCharToInt(databuffer,9,11);
  return temp;
}

float Temperature()                                                                  //Temperature ("C")
{
  temp = (transCharToInt(databuffer,13,15) - 32.00) * 5.00 / 9.00;
  return temp;
}

float RainfallOneHour()                                                              //Rainfall (1 hour)
{
  temp = transCharToInt(databuffer,17,19) * 25.40 * 0.01;
  return temp;
}

float RainfallOneDay()                                                               //Rainfall (24 hours)
{
  temp = transCharToInt(databuffer,21,23) * 25.40 * 0.01;
  return temp;
}

int Humidity()                                                                       //Humidity
{
  return transCharToInt(databuffer,25,26);
}

float BarPressure()                                                                  //Barometric Pressure
{
  temp = transCharToInt(databuffer,28,32);
  return temp / 10.00;
}

void setup()
{

  lcd.begin (20,4);  
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();
  //////////
  Serial.begin(9600);
  ////////
   pinMode(pinCS, OUTPUT);
  // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }
  //////////
}
void loop()
{ 
  //////////////////
  sensorValue = analogRead(sensorPin);                 //Monitoring battery voltage
  float voltage = sensorValue*(5.0/1023.0);
  lcd.setCursor(0,3); //0,3
  lcd.print("Voltage bat: ");
  lcd.print(voltage);
  lcd.print(" V");
  /////////////////
  sensorValue_solar = analogRead(sensorPin_solar);
  float voltage_solar = 2*sensorValue_solar*(5.0/1023.0)-0.07;
  Serial.println(voltage_solar);
 // lcd.setCursor(0,2);              //This is example how to set your LCD commands
//  lcd.print("Voltage sol: ");
//  lcd.print(voltage_solar);
// lcd.print(" v");

  /////////////////////
  getBuffer();              //Begin!
  ///////
  if(WindDirection()==0){
    Serial.print("Wind Direction: ");
    Serial.print("SW");
    Serial.println("  ");
  }
  if(WindDirection()==45){
    Serial.print("Wind Direction: ");
    Serial.print(" W");
    Serial.println("  ");
  }
  if(WindDirection()==90){
    Serial.print("Wind Direction: ");
    Serial.print("NW");
    Serial.println("  ");
  }
  if(WindDirection()==135){
    Serial.print("Wind Direction: ");
    Serial.print(" N");
    Serial.println("  ");
  }
  if(WindDirection()==180){
    Serial.print("Wind Direction: ");
    Serial.print("NE");
    Serial.println("  ");
  }
  if(WindDirection()==225){
    Serial.print("Wind Direction: ");
    Serial.print(" E");
    Serial.println("  ");
  }
  if(WindDirection()==270){
    Serial.print("Wind Direction: ");
    Serial.print("SE");
    Serial.println("  ");
  }
  if(WindDirection()==315){
    Serial.print("Wind Direction: ");
    Serial.print(" S");
    Serial.println("  ");
  }
 // Serial.print("Wind Direction: ");
  //Serial.print(WindDirection());
 // Serial.println("  ");
  Serial.print("Average Wind Speed (One Minute): ");
  Serial.print(WindSpeedAverage());
  Serial.println("m/s  ");
  Serial.print("Max Wind Speed (Five Minutes): ");
  Serial.print(WindSpeedMax());
  Serial.println("m/s");
 // lcd.setCursor(0,0);
 // lcd.print("Max Speed");
 // lcd.print(" ");
  //lcd.print(WindSpeedMax());
 // lcd.print(" ");
 // lcd.print("m/s");
  Serial.print("Rain Fall (One Hour): ");
  Serial.print(RainfallOneHour());
  Serial.println("mm  ");
  Serial.print("Rain Fall (24 Hour): ");
  Serial.print(RainfallOneDay());
  Serial.println("mm");
  Serial.print("Temperature: ");
  Serial.print(Temperature());
  Serial.println("C  ");
 // lcd.setCursor(0,2);
 // lcd.print("Temperature: ");
 // lcd.print(Temperature());
 // lcd.print("C ");
  Serial.print("Humidity: ");
  Serial.print(Humidity());
  Serial.println("%  ");
  Serial.print("Barometric Pressure: ");
  Serial.print(BarPressure());
  Serial.println("hPa");
  Serial.println("");
  Serial.println("");


 
   ////
   myFile = SD.open("test.txt", FILE_WRITE);
  if (myFile) {    
     if(WindDirection()==0){
    myFile.print("Wind Direction: ");
    myFile.print("SW");
    myFile.println("  ");
  }
  if(WindDirection()==45){
    myFile.print("Wind Direction: ");
    myFile.print(" W");
    myFile.println("  ");
  }
  if(WindDirection()==90){
    myFile.print("Wind Direction: ");
    myFile.print("NW");
    myFile.println("  ");
  }
  if(WindDirection()==135){
    myFile.print("Wind Direction: ");
    myFile.print(" N");
    myFile.println("  ");
  }
  if(WindDirection()==180){
    myFile.print("Wind Direction: ");
    myFile.print("NE");
    myFile.println("  ");
  }
  if(WindDirection()==225){
    myFile.print("Wind Direction: ");
    myFile.print(" E");
    myFile.println("  ");
  }
  if(WindDirection()==270){
    myFile.print("Wind Direction: ");
    myFile.print("SE");
    myFile.println("  ");
  }
  if(WindDirection()==315){
    myFile.print("Wind Direction: ");
    myFile.print(" S");
    myFile.println("  ");
  }
 // myFile.print("Wind Direction: ");
 // myFile.print(WindDirection());
 // myFile.println("  ");
  myFile.print("Average Wind Speed (One Minute): ");
  myFile.print(WindSpeedAverage());
  myFile.println("m/s  ");
  myFile.print("Max Wind Speed (Five Minutes): ");
  myFile.print(WindSpeedMax());
  myFile.println("m/s");
  myFile.print("Rain Fall (One Hour): ");
  myFile.print(RainfallOneHour());
  myFile.println("mm  ");
  myFile.print("Rain Fall (24 Hour): ");
  myFile.print(RainfallOneDay());
  myFile.println("mm");
  myFile.print("Temperature: ");
  myFile.print(Temperature());
  myFile.println("C  ");
  myFile.print("Humidity: ");
  myFile.print(Humidity());
  myFile.println("%  ");
  myFile.print("Barometric Pressure: ");
  myFile.print(BarPressure());
  myFile.println("hPa");
  myFile.println("");
  myFile.println("");
  myFile.print("Voltage bat: ");
  myFile.print(voltage);
  myFile.println(" V");
  myFile.print("Voltage sol: ");
  myFile.print(voltage_solar);
  myFile.println(" V"); 
  
  
    myFile.close(); // close the file
  }
  // if the file didn't open, print an error:
  else {
    Serial.println("error opening test.txt");
  }
  delay(100);
}

没有评论:

发表评论