Contact author of the project - report bugs, issues: martinius96@gmail.com

Available libraries for microcontrollers (Arduino / ESP)


Library archive (.zip) extract to C:/Users/[User]/Documents/Arduino/libraries
Library name Library function Download
NewPing

Library for AVR microcontrollers (ATmega) Arduino Uno / Nano / Mega, ESP32, ESP8266 (Espressif Systems). It allows to perform measurements with ultrasonic distance sensors RCW, US-XXX, IOE-SR0X, SR0X, HC-SR0X, HY-SRF0X, DYP-MEXXX, Parallax PING)))™.

Download
VL53L1X

Library for Arduino, ESP8266 and ESP32 microcontrollers. Allows you to perform ToF measurements with STMicroelectronics VL53L1X laser sensors.

Download
Sample source codes for microcontrollers compatible with the Watmonitor interface are available on Github.
  • ESP32 with FreeRTOS support, Ultra Low Power, Over The Air, ESP-IDF, Arduino Core. WiFi / PHY Ethernet via RMII interface / LoRa
  • ESP8266 with Ultra Low Power, Over The Air, Arduino Core, WiFi
  • Arduino with Wiznet W5100 - W5500 Ethernet module support, ENC28J60, Arduino Core
  • Raspberry Pi Pico W with MicroPython implementation
  • Sketches

    HTTP - ESP32 + WiFi - FreeRTOS Real-time operating system FreeRTOSWiFi in use


    
    /*|-----------------------------------------------------------------------------------|*/
    /*|Project: Water level monitor - HTTP - FreeRTOS - HC-SR04 / JSN-SR04T / HY-SRF05    |*/
    /*|ESP32 (DevKit, Generic)                                                            |*/
    /*|Autor: Martin Chlebovec (martinius96)                                              |*/
    /*|E-mail: martinius96@gmail.com                                                      |*/
    /*|Project info: https://martinius96.github.io/hladinomer-studna-scripty/en/          |*/
    /*|Test web interface: http://arduino.clanweb.eu/studna_s_prekladom/?lang=en          |*/
    /*|Buy me coffee: paypal.me/chlebovec                                                 |*/
    /*|Revision: 11th September 2022                                                      |*/
    /*|-----------------------------------------------------------------------------------|*/
    
    #include <WiFi.h>
    #include <NewPing.h>
    
    const char * ssid = "MY_WIFI"; //WiFi SSID name
    const char * password = "MY_WIFI_PASSWORD"; //WiFi password
    
    const char* host = "hladinomer.eu"; //host (server)
    String url = "/data.php"; //URL address to to target PHP file
    
    #define pinTrigger    22
    #define pinEcho       23
    NewPing sonar(pinTrigger, pinEcho);
    
    TaskHandle_t Task1; //ULTRASONIC MEASUREMENT
    TaskHandle_t Task2; //WIFI HTTP SOCKET
    QueueHandle_t  q = NULL;
    
    WiFiClient client;
    static void Task1code( void * parameter);
    static void Task2code( void * parameter);
    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, password); //pripoj sa na wifi siet s heslom
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
      }
      Serial.println(F(""));
      Serial.println(F("Wifi connected with IP:"));
      Serial.println(WiFi.localIP());
      q = xQueueCreate(20, sizeof(int));
      if (q != NULL) {
        Serial.println(F("Queue FIFO buffer is created"));
        vTaskDelay(1000 / portTICK_PERIOD_MS); //wait for a second
        xTaskCreatePinnedToCore(
          Task1code,   /* Task function. */
          "Task1",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task1,      /* Task handle to keep track of created task */
          1);          /* pin task to core 1 */
        Serial.println(F("Ultrasonic measurement task started"));
        xTaskCreatePinnedToCore(
          Task2code,   /* Task function. */
          "Task2",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task2,      /* Task handle to keep track of created task */
          0);          /* pin task to core 0 */
        Serial.println(F("HTTP Socket task started"));
      } else {
        Serial.println(F("Queue creation failed"));
      }
    }
    
    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        WiFi.begin(ssid, password); //pripoj sa na wifi siet s heslom
      }
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      yield();
    
    }
    
    static void Task1code( void * parameter) {
      if (q == NULL) {
        Serial.println(F("Queue in Measurement task is not ready"));
        return;
      }
      while (1) {
        int distance = sonar.ping_cm();
        delay(50);
        Serial.print(F("Test measurement: "));
        Serial.print(distance);
        Serial.println(F(" cm"));
        if (distance > 0) {
          distance = 0;
          for (int i = 0; i < 10; i++) {
            distance += sonar.ping_cm();
            delay(50);
          }
          distance = distance / 10;
          Serial.print(F("Distance to water level is: "));
          Serial.print(distance);
          Serial.println(F(" cm."));
          xQueueSend(q, (void *)&distance, (TickType_t )0); //add the measurement value to Queue
          for (int countdown = 300; countdown >= 0; countdown--) {
            Serial.print(F("Next measurement in: "));
            Serial.print(countdown);
            Serial.println(F(" seconds"));
            vTaskDelay(1000 / portTICK_PERIOD_MS);
          }
        }
      }
    }
    static void Task2code( void * parameter) {
      int distance;
      if (q == NULL) {
        Serial.println(F("Queue in HTTP socket task is not ready"));
        return;
      }
      while (1) {
        xQueuePeek(q, &distance, portMAX_DELAY); //read measurement value from Queue and run code below, if no value, WAIT....
        String data = "hodnota=" + String(distance) + "&token=123456789";
        client.stop();
        if (client.connect(host, 80)) {
          Serial.println(F("Connected to server successfully"));
          client.println("POST " + url + " HTTP/1.0");
          client.println("Host: " + (String)host);
          client.println(F("User-Agent: ESP"));
          client.println(F("Connection: close"));
          client.println(F("Content-Type: application/x-www-form-urlencoded;"));
          client.print(F("Content-Length: "));
          client.println(data.length());
          client.println();
          client.println(data);
          Serial.println(F("Datas were sent to server successfully"));
          xQueueReset(q); //EMPTY QUEUE, IF REQUEST WAS SUCCESSFUL, OTHERWISE RUN REQUEST AGAIN
          while (client.connected()) {
            String line = client.readStringUntil('\n');
            if (line == "\r") {
              break;
            }
          }
          String line = client.readStringUntil('\n');
        } else {
          Serial.println(F("Connection to webserver was NOT successful"));
        }
        client.stop();
      }
    }
    

    HTTP - ESP32 + PHY Ethernet LAN8720 - FreeRTOSReal-time operating system FreeRTOSPHY Ethernet LAN8720 in use via RMII interface


    
    /*|----------------------------------------------------------------------------|*/
    /*|Project: Ultrasonic water level monitor - HC-SR04 / JSN-SR04T / HY-SRF05... |*/
    /*|ESP32 (DevKit, Generic) + PHY Ethernet LAN8720 / TLK110, RMII interface     |*/
    /*|Author: Martin Chlebovec (martinius96)                                      |*/
    /*|E-mail: martinius96@gmail.com                                               |*/
    /*|Buy me a coffee at: paypal.me/chlebovec                                     |*/
    /*|Project info: https://martinius96.github.io/hladinomer-studna-scripty/en     |*/
    /*|Test web interface: http://arduino.clanweb.eu/studna_s_prekladom/?lang=en   |*/
    /*|Revision: 11. September 2022                                                |*/
    /*|----------------------------------------------------------------------------|*/
    
    #include <ETH.h>
    #include <NewPing.h>
    
    const char* host = "hladinomer.eu"; //host (server)
    String url = "/data.php"; //URL address to to target PHP file
    
    boolean eth_state = false;
    #define pinTrigger    4 //CONNECT TO TRIGGER PIN OF ULTRASONIC SENSOR
    #define pinEcho       5 //CONNECT TO ECHO PIN OF ULTRASONIC SENSOR
    NewPing sonar(pinTrigger, pinEcho);
    
    /*
         ETH_CLOCK_GPIO0_IN   - default: external clock from crystal oscillator
         ETH_CLOCK_GPIO0_OUT  - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
         ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
         ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
    */
    #ifdef ETH_CLK_MODE
    #undef ETH_CLK_MODE
    #endif
    #define ETH_CLK_MODE    ETH_CLOCK_GPIO17_OUT
    
    // Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
    #define ETH_POWER_PIN   -1
    
    // Type of the Ethernet PHY (LAN8720 or TLK110)
    #define ETH_TYPE        ETH_PHY_LAN8720
    
    // I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
    #define ETH_ADDR        1
    
    // Pin# of the I²C clock signal for the Ethernet PHY, DONT USE THIS PIN FOR ultrasonic sensor in this sketch
    #define ETH_MDC_PIN     23
    
    // Pin# of the I²C IO signal for the Ethernet PHY
    #define ETH_MDIO_PIN    18
    
    TaskHandle_t Task1; //ULTRASONIC MEASUREMENT
    TaskHandle_t Task2; //PHY ETHERNET HTTP SOCKET
    QueueHandle_t  q = NULL;
    
    
    WiFiClient client;
    static void Task1code( void * parameter);
    static void Task2code( void * parameter);
    void WiFiEvent(WiFiEvent_t event);
    
    void setup() {
      Serial.begin(115200);
      WiFi.onEvent(WiFiEvent);
      ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
      delay(5000);
      q = xQueueCreate(20, sizeof(int));
      if (q != NULL) {
        Serial.println(F("Queue FIFO buffer is created"));
        vTaskDelay(1000 / portTICK_PERIOD_MS); //wait for a second
        xTaskCreatePinnedToCore(
          Task1code,   /* Task function. */
          "Task1",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task1,      /* Task handle to keep track of created task */
          1);          /* pin task to core 1 */
        Serial.println(F("Ultrasonic measurement task started"));
        xTaskCreatePinnedToCore(
          Task2code,   /* Task function. */
          "Task2",     /* name of task. */
          10000,       /* Stack size of task */
          NULL,        /* parameter of the task */
          1,           /* priority of the task */
          &Task2,      /* Task handle to keep track of created task */
          0);          /* pin task to core 0 */
        Serial.println(F("HTTP Socket task started"));
      } else {
        Serial.println(F("Queue creation failed"));
      }
    }
    
    void loop() {
      yield();
    }
    
    static void Task1code( void * parameter) {
      if (q == NULL) {
        Serial.println(F("Queue in Measurement task is not ready"));
        return;
      }
      while (1) {
        int distance = sonar.ping_cm();
        delay(50);
        Serial.print(F("Test measurement: "));
        Serial.print(distance);
        Serial.println(F(" cm"));
        if (distance > 0) {
          distance = 0;
          for (int i = 0; i < 10; i++) {
            distance += sonar.ping_cm();
            delay(50);
          }
          distance = distance / 10;
          Serial.print(F("Distance to water level is: "));
          Serial.print(distance);
          Serial.println(F(" cm."));
          xQueueSend(q, (void *)&distance, (TickType_t )0); //add the measurement value to Queue
          for (int countdown = 300; countdown >= 0; countdown--) {
            Serial.print(F("Next measurement in: "));
            Serial.print(countdown);
            Serial.println(F(" seconds"));
            vTaskDelay(1000 / portTICK_PERIOD_MS);
          }
        }
      }
    }
    static void Task2code( void * parameter) {
      int distance;
      if (q == NULL) {
        Serial.println(F("Queue in HTTP socket task is not ready"));
        return;
      }
      while (1) {
        xQueuePeek(q, &distance, portMAX_DELAY); //read measurement value from Queue and run code below, if no value, WAIT....
        String data = "hodnota=" + String(distance) + "&token=123456789";
        client.stop();
        while (eth_state != true) {
          vTaskDelay(1 / portTICK_PERIOD_MS);
        }
        if (client.connect(host, 80)) {
          Serial.println(F("Connected to server successfully"));
          client.println("POST " + url + " HTTP/1.0");
          client.println("Host: " + (String)host);
          client.println(F("User-Agent: ESP"));
          client.println(F("Connection: close"));
          client.println(F("Content-Type: application/x-www-form-urlencoded;"));
          client.print(F("Content-Length: "));
          client.println(data.length());
          client.println();
          client.println(data);
          Serial.println(F("Datas were sent to server successfully"));
          xQueueReset(q); //EMPTY QUEUE, IF REQUEST WAS SUCCESSFUL, OTHERWISE RUN REQUEST AGAIN
          while (client.connected()) {
            String line = client.readStringUntil('\n');
            if (line == "\r") {
              break;
            }
          }
          String line = client.readStringUntil('\n');
        } else {
          Serial.println(F("Connection to webserver was NOT successful"));
        }
        yield();
        client.stop();
      }
    }
    
    void WiFiEvent(WiFiEvent_t event)
    {
      switch (event) {
        case ARDUINO_EVENT_ETH_START:
          eth_state = false;
          Serial.println("ETH Started");
          //set eth hostname here
          ETH.setHostname("esp32-ethernet");
          break;
        case ARDUINO_EVENT_ETH_CONNECTED:
          eth_state = false;
          Serial.println("ETH Connected");
          break;
        case ARDUINO_EVENT_ETH_GOT_IP:
          eth_state = true;
          Serial.print("ETH MAC: ");
          Serial.print(ETH.macAddress());
          Serial.print(", IPv4: ");
          Serial.print(ETH.localIP());
          if (ETH.fullDuplex()) {
            Serial.print(", FULL_DUPLEX");
          }
          Serial.print(", ");
          Serial.print(ETH.linkSpeed());
          Serial.println("Mbps");
          break;
        case ARDUINO_EVENT_ETH_DISCONNECTED:
          eth_state = false;
          Serial.println("ETH Disconnected");
          break;
        case ARDUINO_EVENT_ETH_STOP:
          eth_state = false;
          Serial.println("ETH Stopped");
          break;
        default:
          break;
      }
    }