How to build a rain sensor

How to build a rain sensor

Most recent cars include a cool gadget: automatic windshield wipers, which start to wipe as soon as it rains. As we are curious by nature, we wondered how car rain sensors work and whether it was possible to build one ourselves, without needing to put a windshield in the middle of the garden.





Some theory

In fact, car rain sensors are based on an optical principle: refraction. When a light ray goes from a transparent medium to another, it is deflected. This deflection depends on the respective refraction index of the two media and is described in the following relationship:

Deflection of a light ray when changing medium
Deflection of a light ray when changing medium


Note that if the ray is perpendicular to the transition surface, it is not deflected whatever the refraction indices. Moreover, this relationship highlights a critical angle beyond which the ray does not go through the interface between two media: it is reflected.

Light ray reflection when the incidence angle goes above a given threshold
Light ray reflection when the incidence angle goes above a given threshold



It is this principle which is used in rain sensors: a light ray is sent into a glass block. The angle of the ray is computed so that it reflects itself inside the block and ends up into a light sensor. But if a drop of water lies on to of the glass, the water refraction index being relatively close to that of glass, part of the ray manages to go out of the block. Therefore, less light reaches the sensor. Important advantage: this system is relatively insensitive to surrounding light which simply goes through the block without reaching the sensor.

Rain sensor sketch, a drop allows light to escape
Rain sensor sketch, a drop allows light to escape


Here is an illustration of the phenomenon with a laser inside a block of epoxy resin.

The ray is trapped in the optical block
The ray is trapped in the optical block



Most part of the light manages to go out of the block through the water drop
Most part of the light manages to go out of the block through the water drop



Application

The theory is relatively simple: you only need to light a powerful led at one end of a transparent block and to put a light sensor at the other end. We are not going to use a Yocto-Light which is a little too slow with only three measures per second. We are rather going to use a Yocto-Knob with a photo-transistor. It's a technique that we have often used: because the luminosity varies, the photo-transistor resistance varies. This can be detected by the Yocto-Knob.

Besides, the block in the shape of a truncated prism is not the most practical: it forces us to fix the led on one side and the photo-transistor at the other. There would therefore be a wire connecting both ends, which would not be very elegant. We have therefore selected a more practical shape allowing us to put the led and the sensor on the same side.

A more suitable shape for the optical block
A more suitable shape for the optical block



The main difficulty of this project is to build the optical block. There are probably many alternative methods to reach this goal. We decided to mold epoxy resin in the desired shape: the cast is built with Plexiglass panels glued together with a hot glue gun. Epoxy resin doesn't stick to Plexiglass. Therefore, when the resin is solid, you only need to disassemble the cast to extract a perfectly smooth block: no polishing needed.

The Plexiglass cast
The Plexiglass cast


We took the opportunity to put threaded inserts into the resin to be able to fix the block on a support. In the absence of threaded inserts, you can use nuts.

The final block, note the threaded inserts for assembly
The final block, note the threaded inserts for assembly


The problem with Epoxy resin is its yellowish color. It's a lesser evil: we made some tests with completely transparent polyester resin. The result was disappointing: removing the cast was more difficult than with Epoxy and the block needed polishing.

It's difficult to make a block without (too many) bubbles. You need to mix the resin and the hardener very delicately to prevent the formation of these bubbles. Expect to make several blocks before reaching a satisfying result.

Note that you need to be particularly careful when building the cast: the slightest leak could make the cast permanently attached to your work table.

Once we have a nice and clear block, we only need to fix it on a support containing the led and the photo-transistor, and to connect the whole to a Yocto-Knob. We now have a very design rain sensor, we only need to code the detection application.

Wiring is trivial: only three wires are needed
Wiring is trivial: only three wires are needed


A very design rain sensor
A very design rain sensor



Programming

Programming is very simple: we only need to interrogate the Yocto-Knob in a loop to obtain the luminosity detected by the photo-transistor and to compute the standard deviation of the latest read values. A large deviation means that the reception of light is very perturbed, therefore that it is raining. Here a Python example which computes this:




#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,math

from yocto_api import *
from yocto_anbutton import *

errmsg=YRefParam()

# Setup the API to use local USB devices
if YAPI.RegisterHub("usb", errmsg)!= YAPI.SUCCESS:
    sys.exit("init error"+errmsg.value)

# find any AnButtom function
channel = YAnButton.FirstAnButton()
if channel is None : sys.exit('No module connected')

# then find the first channel of the matching module
serial=channel.get_module().get_serialNumber()
channel1 = YAnButton.FindAnButton(serial + '.anButton1')

historic     = []
stdDev       = 0

# you might need to adjust these thresholds
historicSize = 30
level        = 2.0

while True:
  value= channel1.get_rawValue()
  historic.append(value)
  if len(historic)>historicSize:  historic.pop(0)
  l = len(historic)
  if  (l==historicSize):
    avg  = 0
    avg2 = 0
    for v in historic:
        avg+= v
        avg2+= v*v
    avg = avg / l
    avg2 = avg2 / l
    stdDev = math.sqrt(math.fabs(avg2 - avg*avg))
    if (stdDev>level):
        print("It's raining")
    else:
        print("It's not raining")
  YAPI.Sleep(10)
 



And here is the sensor in action:

  



Conclusion

This sensor enables you to quasi-instantaneously detect the presence of rain, but not the quantity of water falling. For this, we would need a rain gauge or pluviometer. We have some ideas about this, we'll write about it again some other time.

Add a comment 2 comments
Back to blog



1 - freds Saturday,august 17,2013 11H45

I have read the article on the optical rain sensor with interest. I am also interested in your idea for a rain gauge. Are you able to elaborate on the principal's of this idea?

2 - martinm (Yocto-Team)Saturday,august 17,2013 12H59

This is only a detector. If you're interested in a rain gauge, you should have a look here: http://www.yoctopuce.com/EN/article/how-to-build-an-usb-pluviometer

Yoctopuce, get your stuff connected.