Droplet - Monitoring water consumption at your house with Arduino Yun

Will find time to document better the droplet. For questions please do contact.

Repository: https://github.com/misaakidis/droplet-yun

Breadboard: Schematic:

Source Code:


  Copyright (C) 2014 Isaakidis Marios misaakidis@yahoo.gr

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


  Residential water consumption monitor with Arduino Yun.

    * Arduino Yun board (connected via Ethernet to the Internet)
    * NPN Hall Effect Sensor A 42E

  The circuit:
    * Vcc of the hall effect sensor to +3.3V
    * GND of the hall effect sensor to ground
    * OUTPUT of the hall effect sensor to digital pin 12
    * 220 Ohm transistor between Vcc and Output of the sensor

  created 17 Apr 2014
  by team YdroCare
    * Adonis Panayides
    * Marios Isaakidis
    * Prokopis Constantinou
    * Stefanos Christoforou



#include <Process.h>

const int led = 13;           // on-board led of Arduino Yun
const int hall_output = 12;    // output of the hall effect sensor

const int UID = 100;          // Unique Identifier for yun
const short broadcastInterval = 10; // Interval between broadcasts in seconds

const String curlStart = "curl -X POST -H \"Content-Type: application/json\" -d '";
const String curlClose = " }' http://ydorcareapi.azurewebsites.net/api/Measures";

int peaks = 0;                // peaks since last transmission
unsigned long epoch;          // UNIX timestamp when Arduino starts
unsigned long millisAtEpoch;  // millis at the time of timestamp
unsigned long lastBroadcast;     // timestamp at last broadcast
unsigned long currentBroadcast;  // timestamp at current broadcast

void setup() {
  // Initialize Bridge

  // Initialize serial communications:
  // Initialize the on-board led as output and the pin connected
  // to the hall effect sensor as input:
  pinMode(led, OUTPUT);
  pinMode(hall_output, INPUT);

  // Wait for serial to be connected, remove this in the future
  // Wait until connected to the Internet
  // Sync clock with NTP
  // Get time from Linino in Unix timestamp format
  epoch = timeInEpoch();
  lastBroadcast = epoch;
  Serial.println("Ready for broadcasting...");

void loop() {
  if((calcCurrentTimestamp() - lastBroadcast) > broadcastInterval) {

// Return current timestamp, calculated by initial Linino's epoch + seconds past since then
unsigned long calcCurrentTimestamp() {
  return epoch + ((millis() - millisAtEpoch) / 1000);

// Wait for a peak. Turn the led on while hall effect output is 0V.
// Then turn led off and increase the number of peaks.
void waitForPeak() {
  while(digitalRead(hall_output) == HIGH);
  digitalWrite(led, HIGH);
  delay(10);  // small delay because a pass of the magnet might be counted as multiple peaks
  while(digitalRead(hall_output) == LOW);
  digitalWrite(led, LOW);

// Asynchronously broadcast peaks in JSON format
void broadcastPeaks() {
  Process p;
  // Set currentBroadcast to current timestamp
  currentBroadcast = calcCurrentTimestamp();
  // Print to serial 
  Serial.print("Broadcasting peaks: ");
  String curlCmd = String(curlStart + "{ \"UID\": " + UID + ",  \"time_from\": " + lastBroadcast + 
                          ",  \"time_to\": " + currentBroadcast + ",  \"peaks\": " + peaks + curlClose);
  /*  Uncomment for debugging only
      since the above command was run asynchronously
      in order not to stall the peaks measurement
  while(p.available() > 0) {
  // Set lastbroadcast timestamp as the current timestamp, reset peaks counter
  lastBroadcast = currentBroadcast;
  peaks = 0;

// Check if connected to the Internet
int isConnectedToInternet() {
  Process p;
  int result;
  Serial.print("Checking connectivity... ");

  // Check if ping to google.com is successful
  p.runShellCommand("ping -W 1 -c 4 www.google.com >& /dev/null && echo 1 || echo 0");
  // Wait until execution is completed, return result
  result = p.parseInt();
  return result;

// Synchronize clock using NTP
void setClock() {  
  Process p;
  Serial.println("Setting clock.");
  // Sync clock with NTP
  p.runShellCommand("ntpd -nqp 0.openwrt.pool.ntp.org");
  // Block until clock sync is completed

// Return timestamp of Linino
unsigned long timeInEpoch() {
  Process time;                   // process to run on Linuino
  char epochCharArray[12] = "";   // char array to be used for atol

  // Get UNIX timestamp
  // When execution is completed, store in charArray
  while (time.available() > 0) {
    millisAtEpoch = millis();
    time.readString().toCharArray(epochCharArray, 12);
  // Return long with timestamp
  return atol(epochCharArray);

Subscribe to new posts (~1/week) RSS Feed

Enter your email address:
Delivered by FeedBurner

Creative Commons License This work by Isaakidis Marios is licensed under a Creative Commons Attribution 4.0 International License. Based on a work at misaakidis.github.io