Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kakopappa/2b20b0086bb0a6de500c08407acd3943 to your computer and use it in GitHub Desktop.
Save kakopappa/2b20b0086bb0a6de500c08407acd3943 to your computer and use it in GitHub Desktop.
Sinric Pro Water Tank (Water Level Monitor) using ultrasonic sensor : https://help.sinric.pro/pages/tutorials/custom-device-types/ultrasonic-sensor/HC-SR04.html
//#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif
#include <SinricPro.h>
#include "WaterLevelIndicator.h"
// Grab it from https://portal.sinric.pro.
#define APP_KEY "" //Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET "" //Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define DEVICE_ID "" //Should look like "6534xxxxxxxc08c6ea1b"
#define SSID "" // Your WiFi SSID
#define PASS "" // Your WiFi Password
#define BAUD_RATE 115200
#define EVENT_WAIT_TIME 60000 // send event every 60 seconds
#if defined(ESP8266)
const int trigPin = 12;
const int echoPin = 14;
#elif defined(ESP32)
const int trigPin = 5;
const int echoPin = 18;
#elif defined(ARDUINO_ARCH_RP2040)
const int trigPin = 15;
const int echoPin = 14;
#endif
int EMPTY_TANK_HEIGHT = 150; // Variable for height when the tank is empty
int FULL_TANK_HEIGHT = 25; // Variable for height when the tank is full
WaterLevelIndicator &waterLevelIndicator = SinricPro[DEVICE_ID];
long duration;
float distanceInCm;
int waterLevelAsPer;
int lastWaterLevelAsPer;
float lastDistanceInCm;
// RangeController
void updateRangeValue(int value) {
waterLevelIndicator.sendRangeValueEvent("rangeInstance1", value);
}
// PushNotificationController
void sendPushNotification(String notification) {
waterLevelIndicator.sendPushNotification(notification);
}
// RangeController
// Below function will trigger when you change the sliders
bool onRangeValue(const String &deviceId, const String& instance, int &rangeValue) {
if(instance == "rangeInstance2") {
EMPTY_TANK_HEIGHT = rangeValue;
Serial.printf("Empty tank height changed to %d\r\n", rangeValue);
} else if(instance == "rangeInstance3") {
FULL_TANK_HEIGHT = rangeValue;
Serial.printf("Full tank height changed to %d\r\n", rangeValue);
}
return true;
}
bool onAdjustRangeValue(const String &deviceId, const String& instance, int &valueDelta) {
if(instance == "rangeInstance2") {
EMPTY_TANK_HEIGHT += valueDelta;
Serial.printf("Empty tank height adjusted by %d\r\n", valueDelta);
} else if(instance == "rangeInstance3") {
FULL_TANK_HEIGHT += valueDelta;
Serial.printf("Full tank height adjusted by %d\r\n", valueDelta);
}
return true;
}
void handleSensor() {
if (SinricPro.isConnected() == false) {
return;
}
static unsigned long last_millis;
unsigned long current_millis = millis();
if (last_millis && current_millis - last_millis < EVENT_WAIT_TIME) return; // Wait untill 1 min
last_millis = current_millis;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distanceInCm = duration/29 / 2;
if(distanceInCm <= 0) {
Serial.printf("Invalid reading: %f..\r\n", distanceInCm);
return;
}
if(lastDistanceInCm == distanceInCm) {
Serial.printf("Water level did not changed. do nothing...!\r\n");
return;
}
int change = abs(lastDistanceInCm - distanceInCm);
if(change < 2) {
Serial.println("Too small change in water level (waves?). Ignore...");
return;
}
lastDistanceInCm = distanceInCm;
waterLevelAsPer = map((int)distanceInCm ,EMPTY_TANK_HEIGHT, FULL_TANK_HEIGHT, 0, 100);
waterLevelAsPer = constrain(waterLevelAsPer, 1, 100);
Serial.printf("Distance (cm): %f. %d%%\r\n", distanceInCm, waterLevelAsPer);
/* Update water level on server */
updateRangeValue(waterLevelAsPer);
/* Send a push notification if the water level is too low! */
if(waterLevelAsPer < 5) {
sendPushNotification("Water level is too low!");
}
}
/*********
* Setup *
*********/
void setupSensor() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void setupSinricPro() {
// RangeController
// setup Empty tank slider
waterLevelIndicator.onRangeValue("rangeInstance2", onRangeValue);
waterLevelIndicator.onAdjustRangeValue("rangeInstance2", onAdjustRangeValue);
// Setup Full tank slider.
waterLevelIndicator.onRangeValue("rangeInstance3", onRangeValue);
waterLevelIndicator.onAdjustRangeValue("rangeInstance3", onAdjustRangeValue);
SinricPro.onConnected([]{ Serial.printf("[SinricPro]: Connected\r\n"); });
SinricPro.onDisconnected([]{ Serial.printf("[SinricPro]: Disconnected\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
}
void setupWiFi() {
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.setAutoReconnect(true);
#elif defined(ESP32)
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
#endif
WiFi.begin(SSID, PASS);
Serial.printf("[WiFi]: Connecting to %s", SSID);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
delay(250);
}
Serial.printf("connected\r\n");
}
void setup() {
Serial.begin(BAUD_RATE);
setupSensor();
setupWiFi();
setupSinricPro();
}
/********
* Loop *
********/
void loop() {
handleSensor();
SinricPro.handle();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment