Basement leak detector with Raspberry Pi 2, Windows 10 IoT Core and Azure

Since receiving my Raspberry Pi 2 I’ve been working on it, starting with the requisite blinky LED light, lighting up the LED when a button a pressed, and reading temperature, humidity, altitude, and barometric pressure using a BME280. I’ve slowly become more familiar with using Visual Studio 2015 and Windows 10 IoT frameworks to interface with the Raspberry Pi. So it was time to embark on my own project: a basement water leak detector that would send notification to Azure IoT. The bill of materials is pretty simple:

  • Raspberry Pi 2
  • Moisture sensor from modmypi

This moisture sensor is great for beginners because it has a digital output. Most of the other moisture sensors have analog outputs which means you need an analog-to-digital converter like a MCP 3008 to convert the sensors output to a digital level. Plus you would have to interface to the ADC through an SPI interface which can be more involving that simple GPIO pins.

First you wire up the probes to the sensor with 2 of the included Female-to-Female wires. Then connect the sensor to your Raspberry Pi 2 in the following configuration:

  • VCC to Pin 1 3.3V
  • GND to Pin 9 GND
  • D0 to any available GPIO pin (in my case I used GPIO 4)

Before writing any code you can test if the sensor is working by checking the red power light on the sensor board. Dipping the probe into water should trigger a green LED on the sensor board.

IMG_0032

Now that you have the hardware wired up its time to write some code. Fire up Visual Studio 2015 and start a new blank project of type Universal Windows (Visual C#). Next, right-click on References and add Windows IoT extensions for UWP. In MainPage.xaml add a button and call it “LED” so you can visually tell if moisture is detected. Add a text field below that called “GpioStatus” for status messages. In MainPage.xaml.cs add

using Windows.Devices.Gpio 
using Microsoft.Azure.Devices.Client

so that you can access the GPIO pins and send data to Azure IoT hub. We want the app to constantly monitor for moisture so we set it to run on a timer loop. Before starting the loop though we use the Azure IoT SDK to create a client to communicate with Azure IoT hub (I have blanked out the shared key, you have to supply your own, and you have to create a valid Device ID using Device Explorer) and initialize the GPIO pin we are using to grab the input so we define a function InitGPIO() for that:

public MainPage()
        {
            InitializeComponent();

            deviceClient = DeviceClient.CreateFromConnectionString("HostName=xxxxx.azure-devices.net;DeviceId=RaspberryPi2;SharedAccessKey=xxxxxxxxxxxxxx", TransportType.Http1);


            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(1000);
            timer.Tick += Timer_Tick;

            InitGPIO();

            if (pin != null)
            {
                timer.Start();
            }
        }
private void InitGPIO()
        {
            var gpio = GpioController.GetDefault();

            // Show an error if there is no GPIO controller
            if (gpio == null)
            {
                pin = null;
                GpioStatus.Text = "There is no GPIO controller on this device.";
                return;
            }

            pin = gpio.OpenPin(MOISTURE_PIN);
            pin.SetDriveMode(GpioPinDriveMode.Input);
            pinValue = pin.Read();
            GpioStatus.Text = "GPIO pin 4 initialized correctly.";
        }

Now in the timer loop we simply check the value of GPIO pin 4. If it is LOW then there is moisture and we trigger the UI to show a red alert.

  private void Timer_Tick(object sender, object e)
        {
            Double pinValueDouble;
            pinValue = pin.Read();
            if (pinValue == GpioPinValue.Low)
            {
                LED.Fill = redBrush;
                GpioStatus.Text = "Moisture Detected!";
                pinValueDouble = 100.0;
            }
            else
            {
                LED.Fill = grayBrush;
                GpioStatus.Text = "";
                pinValueDouble = 0.0;
            }
            SendDataToAzure(pinValueString);
        }

        private async Task SendDataToAzure(Double val)
        {
            var telemetryDataPoint = new
            {
                time = DateTime.Now,
                MoistureDetected = val
            };

            var jsonString = JsonConvert.SerializeObject(telemetryDataPoint);
            var msg = new Message(Encoding.UTF8.GetBytes(jsonString));
            await deviceClient.SendEventAsync(msg);
        }

That’s all there is to it. Now when the probe detects moisture it will trigger a visual alert (if you have a monitor connected to the Raspberry Pi, but if not it will send a message to Azure IoT with a value of 100 if there is moisture. (NewtonSoft JSON serializer is used to create a nicely formatted JSON payload) I am using 100 because it is a binary on/off event and I am planning to plot this with some temperature data later, so this will make it easier to plot on a chart. Once the message is sent to Azure IoT hub,  a stream analytics job can either log the message, send it to BI for analysis, or send a notification. In the next post I will detail how to handle the message.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s