<// Include the Wire library for I2C access.
#include <Wire.h>
// Include the Love Electronics BMP180 library.
#include <BMP180.h>
#include <LiquidCrystal.h>
#include "DHT.h"
//DHT dht(10, DHT11); //wenn ihr einen DHT 11 benutzt
DHT dht(10, DHT22); //wenn ihr einen DHT 22 benutzt
//Die 10 gibt den digitalen Ein-/Ausgang auf dem Board an, an dem der Datenbus des DHT-Sensors angeschlossen ist
//___________________________________________________________________________________
#define uint unsigned int
#define ulong unsigned long
#define PIN_ANEMOMETER 2 // Digital 2
#define PIN_RAINGAUGE 3 // Digital 3
#define PIN_VANE 5 // Analog 5
// How often we want to calculate wind speed or direction
#define MSECS_CALC_WIND_SPEED 5000
#define MSECS_CALC_WIND_DIR 5000
#define MSECS_CALC_RAIN_FALL 30000
volatile int numRevsAnemometer = 0; // Incremented in the interrupt
volatile int numDropsRainGauge = 0; // Incremented in the interrupt
ulong nextCalcSpeed; // When we next calc the wind speed
ulong nextCalcDir; // When we next calc the direction
ulong nextCalcRain; // When we next calc the rain drop
ulong time; // Millis() at each start of loop().
// ADC readings:
#define NUMDIRS 8
ulong adc[NUMDIRS] = {26, 45, 77, 118, 161, 196, 220, 256};
// These directions match 1-for-1 with the values in adc, but
// will have to be adjusted as noted above. Modify 'dirOffset'
// to which direction is 'away' (it's West here).
char *strVals[NUMDIRS] = {"W","NW","N","SW","NE","O","SO","O"};
byte dirOffset=0;
//___________________________________________________________________________________
LiquidCrystal lcd(12, 11, 5, 4, 1, 0);
// Store an instance of the BMP180 sensor.
BMP180 barometer;
// We are going to use the on board LED for an indicator.
int indicatorLed = 13;
// Store the current sea level pressure at your location in Pascals.
float seaLevelPressure = 102400;
void setup()
{
dht.begin();
lcd.begin(16, 2);
// We start the serial library to output our messages.
//Serial.begin(9600);
// We start the I2C on the Arduino for communication with the BMP180 sensor.
Wire.begin();
// Set up the Indicator LED.
pinMode(indicatorLed, OUTPUT);
// We create an instance of our BMP180 sensor.
barometer = BMP180();
// We check to see if we can connect to the sensor.
if(barometer.EnsureConnected())
{
lcd.setCursor(0,0);
lcd.println("Connected to BMP180."); // Output we are connected to the computer.
digitalWrite(indicatorLed, HIGH); // Set our LED.
delay(1000);
// When we have connected, we reset the device to ensure a clean start.
barometer.SoftReset();
// Now we initialize the sensor and pull the calibration data.
barometer.Initialize();
}
else
{
lcd.setCursor(0,0);
lcd.println("Could not connect to BMP180.");
digitalWrite(indicatorLed, LOW); // Set our LED.
delay(1000);
}
//________________________________________________________
// Serial.begin(9600);
pinMode(PIN_ANEMOMETER, INPUT);
digitalWrite(PIN_ANEMOMETER, HIGH);
digitalWrite(PIN_RAINGAUGE, HIGH);
attachInterrupt(0, countAnemometer, FALLING);
attachInterrupt(1, countRainGauge, FALLING);
nextCalcRain = millis() + MSECS_CALC_RAIN_FALL;
nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;
nextCalcDir = millis() + MSECS_CALC_WIND_DIR;
//________________________________________________________
}
//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
numRevsAnemometer++;
}
//=======================================================
// Interrupt handler for rain gauge. Called each time the reed
// switch triggers (one drop).
//=======================================================
void countRainGauge() {
numDropsRainGauge++;
}
//=======================================================
// Find vane direction.
//=======================================================
void calcWindDir() {
int val;
byte x, reading;
val = analogRead(PIN_VANE);
val >>=2; // Shift to 255 range
reading = val;
// Look the reading up in directions table. Find the first value
// that's >= to what we got.
for (x=0; x<NUMDIRS; x++) {
if (adc[x] >= reading)
break;
}
//Serial.println(reading, DEC);
x = (x + dirOffset) % 8; // Adjust for orientation
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Dir: ");
lcd.print(strVals[x]); // vorher println !!!
delay(1000);
}
//=======================================================
// Calculate the wind speed, and display it (or log it, whatever).
// 1 rev/sec = 1.492 mph = 2.40114125 kph
//=======================================================
void calcWindSpeed() {
int x, iSpeed;
// This will produce kph * 10
// (didn't calc right when done as one statement)
long speed = 24011;
speed *= numRevsAnemometer;
speed /= MSECS_CALC_WIND_SPEED;
iSpeed = speed; // Need this for formatting below
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Wind: ");
x = iSpeed / 10;
lcd.print(x);
lcd.print('.');
x = iSpeed % 10;
lcd.print(x);
lcd.setCursor(10,0);
lcd.print("(");
lcd.print(strVals[x]);
lcd.print(")");
//lcd.setCursor(0,1);
//calcRainFall(); // ------> !!!
delay(1000);
numRevsAnemometer = 0; // Reset counter
}
//=======================================================
// Calculate the rain , and display it (or log it, whatever).
// 1 bucket = 0.2794 mm
//=======================================================
void calcRainFall() {
int x, iVol;
// This will produce mm * 10000
// (didn't calc right when done as one statement)
long vol = 2794; // 0.2794 mm
vol *= numDropsRainGauge;
vol /= MSECS_CALC_RAIN_FALL;
iVol = vol; // Need this for formatting below
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Rain fall: ");
x = iVol / 10000;
lcd.print(x);
lcd.print('.');
x = iVol % 10000;
lcd.print(x);
lcd.println(); //
delay(1000);
numDropsRainGauge = 0; // Reset counter
}
void loop()
{
if(barometer.IsConnected)
{
// Retrive the current pressure in Pascals.
long currentPressure = barometer.GetPressure();
// Print out the Pressure.
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Pressure: ");
lcd.print(currentPressure);
lcd.print(" Pa");
// Retrive the current altitude (in meters). Current Sea Level Pressure is required for this.
float altitude = barometer.GetAltitude(seaLevelPressure);
// Print out the Altitude.
lcd.setCursor(0,1);
lcd.print("Altitude: ");
lcd.print(altitude);
lcd.print(" m");
delay(1000);
// Retrive the current temperature in degrees celcius.
float currentTemperature = barometer.GetTemperature();
// Print out the Temperature
/lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temperature: ");
lcd.print(currentTemperature);
//lcd.write(176);
lcd.print("C");/
//Auslesen und Zwischenspeichern der Temperarur- und Feuchtigkeitswerte
int t = dht.readTemperature();
int h = dht.readHumidity();
//Anzeigen der Werte
lcd.clear();
lcd.setCursor(0,0); //Selektion 1. Zeile (man beginnt beim Zählen mit 0)
lcd.print("T.: ");
lcd.print(t);
lcd.print("'C");
lcd.setCursor(0,1); //Selektion 2. Zeile
lcd.print("F.: ");
lcd.print(h);
lcd.print("%");
delay(2000);
time = millis();
if (time >= nextCalcSpeed) {
calcWindSpeed();
nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;
}
if (time >= nextCalcDir) {
calcWindDir();
nextCalcDir = time + MSECS_CALC_WIND_DIR;
}
if (time >= nextCalcRain) {
calcRainFall();
nextCalcRain = time + MSECS_CALC_RAIN_FALL;
}
calcRainFall(); // Kann entweder hier benutzt werden oder in der calcWindSpeed()-Funktion weiter oben !!!
lcd.println(); // Start a new line. //
delay(2000); // Show new results every second.
}
}