The best tools to make your project dreams come true

Login or Signup
USD

10/22/2018 | By Maker.io Staff

How to Make a Smart Rain Gauge

Rain sensors are very trivial, consisting of a pair of electrodes that send a signal when rain is detected. Determining how much rain has fallen, however, is not as easy. In this project, we will build a smart rain depth gauge.

Things You Will Need

  • Arduino Uno
  • Copper clad material
  • 100R resistor
  • 1K resistor
  • USB B cable
  • PC, Linux, Mac, or Raspberry Pi with Raspbian
  • Python 3
  • Schematic

    How to Make a Smart Rain Gauge

    Check out the full schematic here.

    Adafruit.IO Setup

    This month, we learned how to set up and use Adafruit.io, so we now need to take this knowledge and do the following.

  • Create an Adafruit.io account.
  • Create a new feed called “WaterLevel”.
  • Create a dashboard called “WaterLevel”.
  • Add a gauge item to our dashboard whose min value is 0 and max value is 100.
  • How to Make a Smart Rain Gauge 

    Water level feed

    How to Make a Smart Rain Gauge 

    Water level dashboard

    How to Make a Smart Rain Gauge 

    The main dashboard

    We will also need to get our private key so we can send messages to Adafruit.io. You can find your key by either clicking the key icon or by clicking “View AIO Key” in the menu.

    How to Make a Smart Rain Gauge

    How It Works: The Water Sensor

    The water sensor in this project is incredibly simple, and it is based on soil sensors. Two prongs are placed inside a rain capture container, and, as the level rises, the resistance between the two probes decreases. One of our probes is connected to 5V through a 100R resistor, while the other probe is directly connected to the base of a transistor. As the resistance between the two probes decreases, the current flowing through the base of the transistor increases, and, therefore, the current flow through the transistor increases. This increase in current flow results in a bigger potential difference across the 1K resistor, and, therefore, the voltage output of the water level sensor increases.

    How It Works: The Arduino

    The Arduino’s function is to take readings from the water level sensor and then transmit this information to a connected computer using a serial port. But raw readings from the water sensor circuit need to be processed before they can be sent, as the output from the water sensor is not linear. Processing the data is somewhat tricky, as the data shows a somewhat logarithmic output, but trying to convert the readings to a linear pattern using logs proved futile. Instead, a more trivial approach was taken, but the result was surprisingly accurate!

    Firstly, raw readings are taken at these water levels: full, half, quarter, and empty. The full and empty levels are then saved to two variables, maxValue and minValue respectively (this is used to determine the range of possible values). Then, the recorded value has the minValue subtracted from it, which creates a 0-adjusted output (i.e., no water = 0). The last step involves converting the 0-adjusted value to a linear scale of 0 to 100. This is achieved by splitting our reading into four comparisons, which check for half, quarter, and eighth ranges. When the value from the sensor falls into one of these categories, we map the reading to a linear scale using the map function. While this is crude, it is effective enough for a rough estimation of the water level. The last stage in the code is to print the linear value to the serial port so our Python program can send the data to Adafruit.io. You may notice that we have two print instructions; the first print function prints the value, while the second print function prints a newline command, which is needed by the Python readline serial function.

    Copy Code
    const int analogInPin = A0;   // Analog input pin that the potentiometer is attached to
    const int minValue = 630;     // Used for creating a linear scale
    const int maxValue = 750;
    
    float value;
    float difference = maxValue - minValue;
    
    void setup() 
    {
      // put your setup code here, to run once:
      Serial.begin(9600); 
    }
    
    
    void loop() 
    {
      // Read the value from the sensor
      value = analogRead(analogInPin);
    
      // Zero adjust the result
      value = value - minValue;
    
      // Check if the value has fallen below the min value
      if(value < 0)
        value = 0;
    
      // Convert the reading to a 0 to 100 scale
      value = (value * 100) / difference;
    
      // If the reading goes beyond 100 then max it out
      if(value >= 100)
        value = 100;
    
      // ***********************************************************
      // Non-linear to linear simple conversion
    
      // Water level 50% to 100%
      if(value > 80)
      {
        value = map(value, 80, 100, 50, 100);
      }
      
      // Water level 25% to 50%
      else if(value > 50)
      {
        value = map(value, 50, 80, 25, 50);
      }
      
      // Water level 0% to 25%
      else
      {
        value = map(value, 0, 50, 0, 25);
      }
    
      Serial.print(value);
      Serial.print("\n");
      delay(3000);
    }
     How It Works: The Python Program

    Using IoT services can be tricky at times, but this project perfectly demonstrates why Adafruit.io is arguably one of the best services out there and why Python is a beautiful language!

    First, install the adafruit python libraries. Open a terminal window or command prompt and use the following PIP command:

    pip install adafruit-io

    You will also need the serial library, which can be installed using the following PIP command:

    pip install pyserial

    The adafruit.io library is incredibly easy, and, for our application, we only need to learn two functions:

  • Client(key): This creates an object where the key is our private key.
  • .send(feed, value): This sends value to the feed.
  • The first portion of our program imports the relevant libraries, creates an adafruit.io object called adafruitio, and creates a serial port object called serialPort. The main bulk of the Python code simply reads data from the serial port and then attempts to write this value to adafruit.io using the send command. You may have noticed the typecasting when assigning the waterlevel value to serialstring; this is needed because the serialstring value will be a string and not a float.

     

    Copy Code
    from Adafruit_IO import Client
    import serial
    
    # Adafruit IO related variables
    adafruitKey = "b9aaf9f4054849429c8f32cbf2e3af5a"
    adafruitio = Client(adafruitKey)
    
    # Create a serial port object
    serialPort = serial.Serial(port = "COM10", baudrate=9600,
                               bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE)
    
    # Program variables
    waterlevel = 0
    serialstring = ""
    
    # Main Program Loop
    while(1):
        serialstring = serialPort.readline()
        try:       
            print("Reading taken")
            waterlevel = float(serialstring)
            adafruitio.send('WaterLevel', waterlevel)
            print("Sent to Adafruit IO")
        except:
            pass

    from Adafruit_IO import Client

    import serial


    # Adafruit IO related varibles

    adafruitKey = "b9aaf9f4054849429c8f32cbf2e3af5a"

    adafruitio = Client(adafruitKey)


    # Create a serial port object

    serialPort = serial.Serial(port = "COM10", baudrate=9600,

                              bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE)


    # Program variables

    waterlevel = 0

    serialstring = ""


    # Main Program Loop

    while(1):

       serialstring = serialPort.readline()

       try:       

           print("Reading taken")

           waterlevel = float(serialstring)

           adafruitio.send('WaterLevel', waterlevel)

           print("Sent to Adafruit IO")

       except:

           pass


    Construction and Testing

    This project is very easy to construct using only an Arduino Uno, some wire, and a breadboard. The water level sensor itself was built using three pieces of copper clad material, which are stuck together using super glue. Make sure that the probes are not electrically connected at all. When sticking the cross piece to the two probes, make sure the copper sides all face away from each other.

    How to Make a Smart Rain Gauge

    Ideally, the project should be located near a container that collects rain water, so an enclosure may be helpful. However, long wires could instead be used on the probes. They would rest outside while the rest of the project sits on a windowsill.

    How to Make a Smart Rain Gauge