Sunday, 19 April 2015

Weather Station - Rain Gauge

tipping bucket arduino
For the first build post I will be starting with the rain gauge. This is based off the tipping bucket rain gauge method. These are pretty easy to make and get running.



The design

Source
The above picture is from the 1-wire design which is a common picture, I used this to get the basic design principle. Mine is constructed from tin from an old juice concentrate can. The design was hand drawn to get the sizing that I wanted and I could see the life size thing. 

The enclosure is made with ABS plastic sheet that I had lying around, but anything that can be cut and glued should work. 

The design of the catchment area of the enclosure is very important as that plays a role in what the amount of rain is caught and the amount per tip. What is needed is a catchment area of $100cm ^ 2$ this equates to $10mm$ of rain being caught by the system, but because this is 100 times smaller, the $10mm = 1mm$ per $1m ^ 2$. Then the trick is to calibrate the sensor to tip at a specific point, this can be between .01 to 1mm of rain, but this is to the needs of the area. Mine by default ended up by being $0.25 mm$ per tip, this is nice as I can pick up the sometimes common drizzles where I live.

I was originally going to use the reed switch and magnet method as this uses less power to run the system, but the little glass tubes broke every time I worked with them, I went with a reflective IR sensor after that and ensured its current is 10$mA$ at 3.3 V.

BUILD 

The tin


Start by cutting off the base that is left on the bottom, then cut up the join mark of the tin, this gives one a straight line to follow when cutting. Next you will trim the top and bottom of the tin so that you can open it flat (the curly bit). Next is to mark out the dimensions on the flat piece.
design tipping bucket rain gauge



Next we cut and fold the strip of tin to shape, I used a steel ruler to give me a square edge when bending the tin.





Next you cut the sides of the bucket, this is done using the measurement across the base of 110mm, then cut two of these.

Next we will attach the side pieces to the main bucket. This is done by soldering with a small blow torch. 
  • Rough the sides along which you will be soldering
  • Apply some flux
  • Tin the the strips along which you roughed
  • Place flat and attach one side ONLY
Then what is needed is to drill the hole for the axle $3.2mm$, this is $5mm$ from the base, You will drill the side that is attached. Then you will place the other side behind that and aligning the two mark the hole on the unconnected piece. Then drill and attach it using the above method.

The drill bit was a bit small, so I used the copper shaft, and a hammer and opened the hole up so it moved freely
rain gauge tipping bucket
The finished bucket

The Enclosure

The enclosure for the bucket was made using ABS plastic sheet. The internal dimension of the rectangle is $120mm * 80mm$, this gives a catchment area of the $100cm ^ 2$. The height of the enclosure is 100mm, and the funnel is placed 20mm down from the total height, this gives some free board if there is a lot of rain.


When cutting $Side  l_1$ and $Side  l_2$ ensure to add $6mm$ on to the measurement so that the internal measurement stays $120 * 80$

Some Hot Glue
Bucket inside with space to spare
The next part was to add the supports for the bucket and the sensor. I again used ABS sheet and hot glue. The actual dimensions were cut to fit the inside because of the funnel.


From the first pic you can see the threshold adjustment screw that was placed about 33mm away from centre.

Sensor

Next is to attach the sensor components. This is done using a IR LED at $940nm$ and a matched Phototransistor. The reflector is attached to the bucket at centre, this is just a strip of the tin.


The signal is $Active_{HIGH}$ which keeps the current consumption down. Also I used a 330$\Omega$ resistor on the LED at 3.3$V$ as there is no need for a bright IR signal as it is <10mm away from the reflector. The signal is then connected to a Digital pin. I used a comparator to 'Level Shift' the 3.3V signal for the Arduino UNO to understand, this is as its max voltage varies between 1-1.5$V$.

$R5$ and $R4$ are chosen to give a voltage just below the active voltage, about 0.4V, with a final part being really weird that I only used a pull-up resistor of 1$k\Omega$ to get the circuit to work.


Reflector placed centre

 Catchment area

The catchment part of the tipping bucket rain gauge was not built off a drawing/design, so it was more of a process of elimination of fitment and seeing where how it would fit. I used one tin to make it, the centre square piece is $30 x 15mm$ this is from centre. The hole was drilled to a 3.2mm diameter and punched again so as to create a lip downwards for water flow. From the corners of the smaller rectangle lines were drawn outwards and then cut and soldered.



The whole thing is hot glued 20mm down from the top. In the third image you can see that the surface is ruffed for the application of white Hammerite. This was also applied to all metal parts after being ruffed.

Test Run

I tested the rain gauge for a day or two when it was raining and it was actually very accurate. I left it for a while after it rained to look at it again and saw some flash rust on some areas which must have been exposed, this was before painting, this was odd as the tin had some sealant over it. It also come up on the shaft which was a bummer. This was solved by partial sanding and spraying with silicone spray. Also after the tipping bucket was painted, it was also sprayed with the silicone and the catchment area. This was done to help the water flow better because it was pooling in some areas and causing it to fail.


Some pictures


rain gauge

~Code~

The code is written for an Arduino for testing so as to have access to the serial functionality for debugging and retrieval of the logged rain value. Pin 3 is the button with a pull-up, Pin 2 is the tipping bucket signal.

/* AWS - Rain Gauge test code
#Logs the rain fall to eeprom when a push button is pressed
#This version works nicely with no interrupts because of the
#function checking the button state for a change and because
#the bucket does not move at lightning speed
 
By Reece May
Blog: https://www.bariumelectronics.blogspot.com
Written: 3/30/2015
*/
 
#include <EEPROM.h>
 
//Variables
int count = 0;
float mm_const = 0.25;  //calibrated mm of rain for a mm/m^2/tip
float mm_rain = 0.00;
int state = 0;
int button_state = 0;
 
void setup(){
  pinMode(3, INPUT_PULLUP);
  pinMode(2, INPUT);
  pinMode(13, OUTPUT);
  //  DDRB |= (1 << 1);
  //  PORTB |= (1 << 1);
 
  Serial.begin(9600);
  Serial.println("Rain Gauge Test Code");
}
int previous = 1;  //no false reading on boot
 
int tip(int to_test){
  int current = to_test;
 
  if(current != previous){
    previous = current;
    return current;
  }
  else return 0;
}
 
void loop(){
 
  //   digitalRead(3);//(PINB & (1 << 0));
 
  button_state = digitalRead(2);
  delay(10);
  if(tip(button_state)){
    count += 1;
    //   Serial.println(count);
  }
  else count = count;
  //Function to see if log button is pushed and stores tip count once
  if(digitalRead(3) == 0 && !state){
    digitalWrite(13, 1);
    delay(50);
    EEPROM.write(0, count);  //writes count as no need for float storage
    delay(50);
    digitalWrite(13, 0);
    state = 1;  //run only once, this is 0 when Serial is called
  }
  if(Serial.available()){
    if(Serial.read() == 'k'){
      byte rea = EEPROM.read(0);
      mm_rain = (rea) * mm_const;
      delay(100);
      Serial.print("count: ");
      Serial.println(rea);
      Serial.print("rain: ");
      Serial.println(mm_rain);
 
      state = 0; 
    }
    else if(Serial.read() == 'c'){
      count = 0;
      mm_rain = 0;
      Serial.println(count);
      Serial.println(mm_rain);
    }
  }
}

The function $tip()$ is something I wrote for another program which became useful in this code, it just checks to see if the variable that you put in. When it is only working with logical 1 and 0, and you place it in an if() statement looking for a logic 1, it only ever triggers on a 0-1 transition. One thing though with this was that I had to set "int previous = 1; //no false reading on boot" because as the comment says, I was getting false readings from the code on the first time the thing ran

The code originally used interrupts, but with one tip it triggered about 100+ counts and gave some seriously weird results. So I just made it loop in the code to check for the change, and because the code never opens serial and also looks for the log button, its pretty much immediate. I do believe though that I will probably add the interrupt functionality for the rain gauge and the anemometer.

When the log button is pressed it stores the $count$ variable into eeprom and flashes th onboard LED, $state$ also makes it so you can only do this once until you open serial and read the value. This was done because when it was setup away from the PC and then powered on and off, data was lost or when it was connected to the PC and the terminal was opened, data was lost because of restarting :(

Results

The results of the rain gauge were good. I compared the values with a normal rain gauge. The system was tested over about three days, the tipping bucket was within about $0.5mm$ at most from the reading on the normal rain gauge. This also picked up about a $0.75mm$ drizzle. The readings are very accurate and I believe I have made a decent design of this and it looks nice. 

The op-amp circuit and the tipping bucket combined draw a total of $9.1mA$ at $3.3V$, this I think is reasonable and should make it excellent for battery operation.

No comments:

Post a Comment