Remote Smart Water Meter using LoRa and Cayenne via ENC28J60 Ethernet Module

Overview

Imagine being an employee of  WaterCo™’s (a water utility servicel company) meterer. [change this] Every day seems repetitive: meter this, meter that, and meter those. On your afternoon break, you browse through your social media feed to pass time. Along the feed, you come across one of CreateLabz’s mini-project: A Smart Water Meter.

It’s no easy feat to meter hundreds of households. Aside from the repetitive tasks, you could utilize your time for something more productive. So you walk up to your boss, and straight up told him this idea.

If implemented properly, households can see their current water consumption, water flow, and estimated calculated water bill in real time.

Software Used

Hardware Used


  • Robotdyn Mega 2560
  • 
    
  • ENC28J60 Ethernet Module
  • 
    
  • Dragino LoRa Shield v1.4
  • 
    
  • YF-S201 Hall Effect Water Flow Meter / Sensor
  • 
    

    Libraries Used

    Application Description

    This project is crafted in order to demonstrate the connectivity between two LoRa nodes. LoRa devices are usually implemented in the fields where battery consumption, and range is a critical factor.

    Although LoRa devices are set-up as a “star-of-stars” network topology, this node-to-node communication will be enough to transmit one sensor data to a server. If multiple clients are involved, a gateway is built to accommodate all receiving information towards the cloud service. It trades off the data capacity for its long range.

    Dragino LoRa Shield v1.4

    From the Dragino Wiki itself, The Dragino LoRa Shield is a long range transceiver on a Arduino shield form factor and based on Open source library.The LoRa Shield allows the user to send data and reach extremely long ranges at low data-rates.It provides ultra-long range spread spectrum communication and high interference immunity whilst minimizing current consumption.

    LoRa , which means Long Range, is a modulation scheme (Linear Chirp Spread Spectrum) developed by Semtech that uses frequency chirps with a linear relationship of frequency with time to encode information.

    This website describes and explains LoRa : https://www.iotforall.com/a-primer-for-loralorawan/

     

    This device will enable us to transfer the Water Flow Meter data to another node up to ~10km (in open area, theoretically).

     

    ENC28J60 Ethernet Module

    LoRa devices are set-up for data acquisition purposes. One method to store data is to use Micro/SD card modules. SD card modules are normally used when data sensors are logged in a long period of time. When data are needed in real-time, it’s better to use a cloud service. Cloud services, that specializes in data acquisition, usually has a built-in data visualizers.(such as line charts, gauges, and the like).

    When connecting to the internet, there are many options to choose from : GSM, WiFi, and LAN. For this particular project, we will use a LAN connection to connect to the internet.

    According to the datasheet, the ENC28J60 is a stand-alone Ethernet controller with an industry standard Serial Peripheral Interface (SPI). It is designed to serve as an Ethernet network interface for any controller equipped with SPI.

     

    myDevices Cayenne

    Expected Final Output !

    From their webpage, myDevices is an Internet of Things solutions company. We accelerate IoT development and empower enterprises to quickly design, prototype, and commercialize IoT solutions.

    1.CayenneClick this “Sign In” Button

    2.After the website redirects you, fill-up the necessary information

    3. Follow the steps provided by Cayenne. They are very simple and straightforward to follow. For this project, select “Arduino”

     

    4. Properly connect the Ethernet Module to the important wiring.

    5. Here comes the tricky part. Note that in any of the example sketches provided by Cayenne, there’s no sketch for ENC28J60. You need to download the following libraries listed above. The MQTT Username, Password, and Client ID is essential for authentication purposes.

     

    6. Cayenne will wait for a device to connect. Upload the “dummy” sketch so that Cayenne will register the device. This will create a temporary widget named “Channel 0”, that has receives the running sketch time in milliseconds.

    /**************************************************************
     * For this example you need UIPEthernet library:
     *   https://github.com/ntruchsess/arduino_uip
     *
     * Typical wiring would be:
     *  VCC -- 5V
     *  GND -- GND
     *  CS  -- D10
     *  SI  -- D11
     *  SCK -- D13
     *  SO  -- D12
     *  INT -- D2
     *
     *
     **************************************************************/
    #define CAYENNE_DEBUG         // Uncomment to show debug messages
    #define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
    
    #include <UIPEthernet.h>
    #include <CayenneMQTTEthernetClient.h>
    
    // Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
    char username[] = "MQTT_USERNAME";
    char password[] = "MQTT_PASSWORD";
    char clientID[] = "CLIENT_ID";
    
    void setup() {
      Serial.begin(9600);
      Cayenne.begin(username, password, clientID);
    }
    
    void loop() {
      Cayenne.loop();
    }
    
    // Default function for sending sensor data at intervals to Cayenne.
    // You can also use functions for specific channels, e.g CAYENNE_OUT(1) for sending channel 1 data.
    CAYENNE_OUT_DEFAULT()
    {
      // Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
      Cayenne.virtualWrite(0, millis());
      // Some examples of other functions you can use to send data.
      //Cayenne.celsiusWrite(1, 22.0);
      //Cayenne.luxWrite(2, 700);
      //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
    }
    
    // Default function for processing actuator commands from the Cayenne Dashboard.
    // You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
    CAYENNE_IN_DEFAULT()
    {
      CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
      //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
    }

    7. There are many available widgets in Cayenne for the user to explore. Sometimes when adding widgets, the data received by Cayenne will not be registered (although shown in Live Data). When such instance happens, try to remove, and re-add the widget.

    YF-S201 Hall Effect Water Flow Meter / Sensor

    According to Hobbytronics, this Water Flow Meter contains a rotating pinwheel to measure the flow of the liquid passing through. The rotating pinwheel generates a magnetic field that is sensed by a hall effect sensor, which is sealed.

    Along the project, you will also need these materials.

    Hose Coupler
    Hose End

    Water Hose

    Hall Effect Sensor

    A Hall Effect Sensor is a transducer/sensor, similar to a IR Proximity sensor, that changes its output voltage in proportion to a nearby magnetic field. If you had opened a hard disk drive or some motor with feedback, you can see this as a tiny Integrated Chip near the motor.

    Image result for Hall Effect Sensor
    Taken from https://www.slideshare.net/ADARSHARYA2/hall-effect-and-hall-effect-sensor

     

    Set-up the Hardware

    Client Set-up

    Server Set-up

    Jpeg

    Code

    Client

     

    // rf95_client.pde
    // -*- mode: C++ -*-
    // Example sketch showing how to create a simple messageing client
    // with the RH_RF95 class. RH_RF95 class does not provide for addressing or
    // reliability, so you should only use RH_RF95 if you do not need the higher
    // level messaging abilities.
    // It is designed to work with the other example rf95_server
    // Tested with Anarduino MiniWirelessLoRa, Rocket Scream Mini Ultra Pro with
    // the RFM95W, Adafruit Feather M0 with RFM95
    
    #include <SPI.h>
    #include <RH_RF95.h>
    
    // Singleton instance of the radio driver
    RH_RF95 rf95;
    
    //Timer
    unsigned long interval=15000; // the time we need to wait. In this case, 10 seconds.
    unsigned long previousMillis=0; // millis() returns an unsigned long.
    
    //Water Flow
    volatile int  flow_frequency;  // Measures flow meter pulses
    unsigned int  l_hour;          // Calculated litres/hour                      
    unsigned char flowmeter = 3;  // Flow Meter Pin number  
    unsigned long cloopTime;
    unsigned long currentTime;
    
    char cstr[10];
    void setup() 
    {
    
      Serial.begin(9600);
      pinMode(flowmeter, INPUT);
      attachInterrupt(digitalPinToInterrupt(3), flow, RISING); // Setup Interrupt     
       sei();                                                  // Enable interrupts  
      
      while (!Serial) ; // Wait for serial port to be available
      if (!rf95.init())
        Serial.println("init failed");
      // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
    
      // The default transmitter power is 13dBm, using PA_BOOST.
      // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
      // you can set transmitter powers from 5 to 23 dBm:
      //  driver.setTxPower(23, false);
    
       currentTime = millis();
       cloopTime = currentTime;
    }
    
    void loop()
    {
      unsigned long currentMillis = millis(); // grab current time
      
       // Every second, calculate and print litres/hour
       if(currentMillis >= (cloopTime + 1000))
       {     
          cloopTime = currentMillis;              // Updates cloopTime
          // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min. (Results in +/- 3% range)
          l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flow rate in L/hour 
          flow_frequency = 0;                   // Reset Counter
          Serial.print(l_hour, DEC);            // Print litres/hour
          Serial.println(" L/hour");
       }
      
      if ( (unsigned long)(currentMillis - previousMillis) >= interval) {
          itoa(l_hour, cstr, 10); //Integer to char[] conversion where itoa(value, str, base);
          
          rf95.send(cstr, sizeof(cstr));
          rf95.waitPacketSent();
          // save the "current" time
          previousMillis = millis();
     }
    
    }
    
    void flow ()                  // Interrupt function
    { 
       flow_frequency++;
    }

     

    Server

     

    #define CAYENNE_DEBUG         // Uncomment to show debug messages
    #define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
    #define LRCSPIN 10
    #define VIRTUAL_CHANNEL 1
    
    #include <UIPEthernet.h>
    #include <CayenneMQTTEthernetClient.h>
    #include <SPI.h>
    #include <RH_RF95.h>
    
    
    // Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
    char username[] = "35725a70-55ad-11e8-aa1d-033d1c994768";
    char password[] = "95e4b41ecfcd57bd28c00e6b1240fe4119529cee";
    char clientID[] = "3e81b320-6324-11e8-8974-21d815a438b9";
    
    //LoRa Stuff
    // Singleton instance of the radio driver
    RH_RF95 rf95;
    void setup() {
      Serial.begin(9600);
      
      while (!Serial) ; // Wait for serial port to be available
      if (!rf95.init())
        Serial.println("init failed"); 
        
      Cayenne.begin(username, password, clientID);
    
      
    }
    
    void loop() {
      Cayenne.loop();
    }
    
    CAYENNE_OUT_DEFAULT()
    {
      digitalWrite(LRCSPIN, LOW);
       if (rf95.available())
      {
        // Should be a message for us now   
        uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
        uint8_t len = sizeof(buf);
        if (rf95.recv(buf, &len))
        { 
          digitalWrite(LRCSPIN, HIGH);    
          Serial.println((char*)buf);
          
          Cayenne.virtualWrite(VIRTUAL_CHANNEL, atoi(buf) );
        }
        else
        {
          Serial.println("recv failed");
        }
      }
      
      delay(100);
    }

     

    Code Breakdown

     

    void flow (){ 
    flow_frequency++; 
    }

    Whenever a RISING edge of the Water Flow Sensor is noticed, this function is called. The function simply serves as counting up to the variable flow_frequency by 1.

    Conclusion

    Today’s innovation is more or less about improving the previous devices. Smart Water Meter , coupled with a pneumatic valve, can reduce water consumption via strict regulation. Another advantage of using such devices is its real-time update. Whether you are at office or vacation, it only requires internet connectivity to view the data.

    References

    Information

    http://community.mydevices.com/t/is-enc28j60-supported/1044/7

    http://www.hobbytronics.co.uk/download/YF-S201.ino

    http://www.hobbytronics.co.uk/yf-s201-water-flow-meter

    http://wiki.dragino.com/index.php?title=Lora_Shield

     

    Pictures

    http://www.hobbytronics.co.uk/yf-s201-water-flow-meter

    https://www.amazon.com/Tru-Flate-21-133-Male-Hose-Fitting/dp/B001ADWE78

    The post Remote Smart Water Meter using LoRa and Cayenne via ENC28J60 Ethernet Module appeared first on CreateLabz.

    CayenneDragino lora shieldEnc28j60EthernetInternet of thingsIotKnowledgebaseLoraMydevicesSmart water meterWater flow sensorWireless

    Leave a comment

    All comments are moderated before being published