Connecting a weather station to your Arduino

Interrupts

Basically, an interrupt is a signal to a processor by either software or hardware that an event needs immediate attention. I use hardware interrupts in the SDL_Weather_80422 class.

Every time the anemometer rotates, a magnet closes a reed relay connecting one pin to another. Looking at the schematic for the WeatherArduino board, you can see that one end of the reed relay is connected to a 10kohm resistor that pulls up that end to +5V. The other end is connected to ground. When the relay closes, the output line is pulled down to ground momentarily and then goes back to +5V when the line is released.

I am connecting this line to one of the Arduino Mega interrupts (Int5). I set this interrupt to respond to a rising edge (ground going to +5V when the relay is released). Similar statements set up an interrupt to respond to the rain bucket relay closing (Listing 4). Counting these interrupts is how the Arduino determines the wind speed and how much rain has fallen.

Listing 4

Setting Interrupts

01 pinMode(pinAnem, INPUT);   // pinAnem is input to which a switch is connected
02 digitalWrite(pinAnem, HIGH);    // Configure internal pull-up resistor
03 pinMode(pinRain, INPUT);   // pinRain is input to which a switch is connected
04 digitalWrite(pinRain, HIGH);    // Configure internal pull-up resistor
05 attachInterrupt(_intAnem, serviceInterruptAnem, RISING);
06 attachInterrupt(_intRain, serviceInterruptRain, RISING);

Interrupt Service Routine

The interrupt service routine (ISR) for both interrupts are similar. Listing 5 is the ISR for the anemometer. Look through the code to see how the data is passed both directions. Getting an ISR to work properly is a little difficult in a C++ class with the Arduino, which is one reason SDL_Weather_80422 is designed to be a singleton class.

Listing 5

Anemometer ISR

01 unsigned long lastWindTime;
02
03 void serviceInterruptAnem()
04 {
05   unsigned long currentTime= (unsigned long)(micros()-lastWindTime);
06
07   lastWindTime=micros();
08   if(currentTime>1000)   // debounce
09   {
10      SDL_Weather_80422::_currentWindCount++;
11     if(currentTime<SDL_Weather_80422::_shortestWindTime)
12     {
13      SDL_Weather_80422::_shortestWindTime=currentTime;
14     }
15   }
16 }

Specifically, notice the statements in lines 5-8. The truth of the matter is that mechanical devices bounce as they close – usually on the order of a millisecond – which is why I ignore any interrupts that happen less than 1,000µsec (1msec) after a previous interrupt (line 8). In this way, I set a maximum speed at which I can take measurements with the anemometer. In this case, it's 1,492mph, so I'm not too worried about it, not living on Venus.

As a side note, my father, Folke Cigard Shovic, patented a bounceless relay in the 1950s for use in Minuteman ICBMs. As far as the Air Force could tell, it was bounceless when measured with the equipment of the day. I'd be interested in testing it with today's test equipment to see if that is still true.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content