Connected rainwater collector

Discover our connected rainwater collector, an ingenious device combining Node-RED, LoRa and Arduino to intelligently manage and monitor you

BeginnerWork in progressOver 2 days239
Connected rainwater collector

Things used in this project

Hardware components

Arduino MKR WAN 1300
Arduino MKR WAN 1300
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
SparkFun Qwiic Single Relay
SparkFun Qwiic Single Relay
×2
Water pump
×2

Software apps and online services

Node-RED
Node-RED
Arduino IDE
Arduino IDE
MQTT
MQTT

Story

Read more

Schematics

Operating diagram

This diagram explains how the connected rainwater collector works:
- Via an Arduino MKRWAN card, this tank uploads data onto the LoRa network;
- The data is processed on the TTN, then converted into MQTT format and sent to a Node-Red server;
- The server retrieves the data via a dashboard on the PC, which connects via a URL.

Code

Code and explanation

C/C++
This program is an example of an Arduino system that uses an ultrasonic sensor to measure a distance and transmits this information via LoRaWAN, a low-power, long-range communications protocol. It has two main inputs, "a" and "s", each with a specific function.

It uses the MKRWAN library to communicate with a LoRa modem and the Ultrasonic library to interact with an ultrasonic sensor.

There are two main operating states determined by user input:

When 'a' is entered:
It measures the distance using the ultrasonic sensor.
Depending on the distance measured (if less than or equal to 10 cm), it turns on one LED (on pin 8) and turns off the other (on pin 9), or vice versa.
It then sends the measured distance, the status of the LED on pin 8 (P1_state) and the status of the LED on pin 9 (P2_state) via the LoRa modem. The value 15 is also added to each message sent.
When 's' is entered :
It measures the distance again.
It switches off the two LEDs (on pins 8 and 9).
It sends the measured distance and the status of each LED (which are both 0 because they are off) via the LoRa modem. Again, the value 15 is added to each message sent.
It displays a message indicating that the "pumps" have been stopped.

This program repeats these operations every 61 seconds, as defined by the call to the delay function at the end of the main loop.
#include <MKRWAN.h>
#include "Ultrasonic.h"
#include "arduino_secrets.h"

Ultrasonic ultrasonic(7, 6); // Trig et Echo

LoRaModem modem;

// Uncomment if using the Murata chip as a module
// LoRaModem modem(Serial1);


// Please enter your sensitive data in the Secret tab or arduino_secrets.h
String appEui = SECRET_APP_EUI;
String appKey = SECRET_APP_KEY;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  while (!Serial);
  // change this to your regional band (eg. US915, AS923, ...)
  if (!modem.begin(EU868)) {
    Serial.println("Failed to start module");
    while (1) {}
  };
  Serial.print("Your module version is: ");
  Serial.println(modem.version());
  Serial.print("Your device EUI is: ");
  Serial.println(modem.deviceEUI());

  int connected = modem.joinOTAA(appEui, appKey);
  if (!connected) {
    Serial.println("Something went wrong; are you indoor? Move near a window and retry");
    while (1) {}
  }
  // Set poll interval to 60 secs.
  modem.minPollInterval(61);
  // NOTE: independent of this setting, the modem will
  // not allow sending more than one message every 2 minutes,
  // this is enforced by firmware and can not be changed.
}

void loop() {
  Serial.println();
  Serial.println("Enter a message to send to serial");
  Serial.println("(make sure that end-of-line 'NL' is enabled)");
  fflush(stdin);
  String cmd = "";
  while (!Serial.available());
  cmd = Serial.readStringUntil('\n');

  if(cmd == "a"){
    Serial.println(cmd);
    int dist = ultrasonic.Ranging(CM);
    int P1_state = 0;
    int P2_state = 0;
    if (dist <= 10) {
      digitalWrite(9, LOW);
      digitalWrite(8, HIGH);
      P1_state = 1;
      P2_state = 0;
      Serial.println("led 8 high");
      }
    else {
      digitalWrite(9, HIGH);
      digitalWrite(8, LOW);
      P1_state = 0;
      P2_state = 1;
      Serial.println("led 9 high");
      }  
    Serial.print(dist);
    Serial.println(" cm");
    Serial.print("Etat P1: ");
    Serial.println(P1_state);
    Serial.print("Etat P2: ");
    Serial.println(P2_state);

    byte msg[4] ;

    int err;
    modem.beginPacket();
    msg[0] = dist;
    msg[1] = P1_state;
    msg[2] = P2_state;
    msg[3] = 15;
    modem.write(msg, 4);
    err = modem.endPacket(true);
    if (err > 0) {
      Serial.println("Message sent correctly to LoRa!");
    } else {
      Serial.println("Error sending message :(");
      Serial.print("err:");
      Serial.println(err);
      Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength");
      Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)");
    }
  }
  else if(cmd == "s"){
    Serial.println(cmd);
    int dist = ultrasonic.Ranging(CM);
    int P1_state = 0;
    int P2_state = 0;
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    byte msg[4] ;

    int err;
    modem.beginPacket();
    msg[0] = dist;
    msg[1] = P1_state;
    msg[2] = P2_state;
    msg[3] = 15;
    modem.write(msg, 4);
    err = modem.endPacket(true);
    if (err > 0) {
      Serial.println("Message sent correctly to LoRa!");
    } else {
      Serial.println("Error sending message :(");
      Serial.print("err:");
      Serial.println(err);
      Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength");
      Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)");
    }
    Serial.println("Pompes stoppées");
  }

  delay(61000);
  Serial.println("ok");
  //if (!modem.available()) {
//    Serial.println("No downlink message received at this time.");
//    return;
//  }
//  char rcv[64];
//  int i = 0;
//  while (modem.available()) {
//    rcv[i++] = (char)modem.read();
//  }
//  Serial.print("Received: ");
//  for (unsigned int j = 0; j < i; j++) {
//    Serial.print(rcv[j] >> 4, HEX);
//    Serial.print(rcv[j] & 0xF, HEX);
//    Serial.print(" ");
//  }
//  Serial.println();
}

Credits

Valentin BRUGE

Valentin BRUGE

1 project • 0 followers
Nicolas DAILLY

Nicolas DAILLY

28 projects • 16 followers
Associated Professor at UniLaSalle - Amiens / Head of the Computer Network Department / Teach Computer and Telecommunication Networks
fcaron

fcaron

12 projects • 1 follower
Mathieu HELWIG

Mathieu HELWIG

1 project • 0 followers

Comments