Station météo

Station météo arduino

Code

#define uint  unsigned int
#define ulong unsigned long
#define PIN_ANEMOMETER  2  
#define PIN_RAINGAUGE  3     
#define PIN_VANE  5 
 
#define MSECS_CALC_WIND_SPEED 5000
#define MSECS_CALC_WIND_DIR   5000
#define MSECS_CALC_RAIN_FALL  30000
volatile int numRevsAnemometer = 0;
volatile int numDropsRainGauge = 0; 
ulong nextCalcSpeed;         
ulong nextCalcDir;                  
ulong nextCalcRain;                 
ulong time;         
              
#define NUMDIRS 8
ulong   adc[NUMDIRS] = {26, 45, 77, 118, 161, 196, 220, 256};
 
char *strVals[NUMDIRS] = {« W », »NW », »N », »SW », »NE », »S », »SE », »E »};
byte dirOffset=0;
 
void setup() {
   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;
}
 
void loop() {
   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;
   }
}
 
void countAnemometer() {
   numRevsAnemometer++;
}
 
void countRainGauge() {
   numDropsRainGauge++;
}
 
void calcWindDir() {
   int val;
   byte x, reading;
   val = analogRead(PIN_VANE);
   val >>=2;                        // Shift to 255 range
   reading = val;
 
   for (x=0; x<NUMDIRS; x++) {
      if (adc[x] >= reading)
         break;
   }
 
   x = (x + dirOffset) % 8;   
   Serial.print( »  Dir: « );
   Serial.println(strVals[x]);
}
 
void calcWindSpeed() {
   int x, iSpeed;
   long speed = 24011;
   speed *= numRevsAnemometer;
   speed /= MSECS_CALC_WIND_SPEED;
   iSpeed = speed;         
   Serial.print(« Wind speed: « );
   x = iSpeed / 10;
   Serial.print(x);
   Serial.print(‘.’);
   x = iSpeed % 10;
   Serial.print(x);
   numRevsAnemometer = 0;       
}
 
void calcRainFall() {
   int x, iVol;
   long vol = 2794; // 0.2794 mm
   vol *= numDropsRainGauge;
   vol /= MSECS_CALC_RAIN_FALL;
   iVol = vol;         
   Serial.print(« Rain fall: « );
   x = iVol / 10000;
   Serial.print(x);
   Serial.print(‘.’);
   x = iVol % 10000;
   Serial.print(x);
   Serial.println();
   
   numDropsRainGauge = 0;       
}

Remarque

Les numéros des broches sont à adapter au microcontrôleur utilisé