diff --git a/tasmota/xsns_76_dyp.ino b/tasmota/xsns_76_dyp.ino
new file mode 100644
index 000000000..7e873fe30
--- /dev/null
+++ b/tasmota/xsns_76_dyp.ino
@@ -0,0 +1,158 @@
+/*
+ xsns_76_dyp.ino - DYP ME007 serial interface
+
+ Copyright (C) 2020 Janusz Kostorz
+
+ This program is free software: you can reDYPDistanceribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is DYPDistanceributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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, see .
+*/
+
+#ifdef USE_DYP
+
+/*********************************************************************************************\
+ * DYP ME007 ultrasonic distanceance sensor (300...4000mm), serial version
+ *
+ * Every one second code check last received value from sensor via serial port and return:
+ * -1 for checksum error
+ * 0 for distance below 300mm
+ * 300...4000 for measured distance
+ * 4999 for distance above 4000mm
+ * 5999 for not connected sensor
+ *
+\*********************************************************************************************/
+
+#define XSNS_76 76
+
+#include
+
+TasmotaSerial *DYPSerial = nullptr;
+
+#define DYP_CRCERROR -1
+#define DYP_BELOWMIN 0
+#define DYP_MIN 300
+#define DYP_MAX 4000
+#define DYP_ABOVEMAX 4999
+#define DYP_NOSENSOR 5999
+
+uint16_t DYPDistance = 0; // distance in milimeters
+bool DYPSensor = false; // sensor available
+
+/*********************************************************************************************/
+
+void DYPInit(void)
+{
+ DYPSensor = false;
+ if (PinUsed(GPIO_DYP_RX))
+ {
+ DYPSerial = new TasmotaSerial(Pin(GPIO_DYP_RX), -1, 1);
+ if (DYPSerial->begin(9600))
+ {
+ if (DYPSerial->hardwareSerial())
+ ClaimSerial();
+ DYPSensor = true;
+ }
+ }
+}
+
+void DYPEverySecond(void)
+{
+ if (!DYPSensor)
+ return;
+
+ // check for serial data
+ if (DYPSerial->available() < 6)
+ {
+ DYPDistance = DYP_NOSENSOR;
+ return;
+ }
+
+
+ // trash old data (only 7 last bytes are nedded for calculate DYPDistance)
+ while (DYPSerial->available() > 7)
+ DYPSerial->read();
+
+
+ // read data from serial port - * 0xFF MSB LSB CRC *
+ while (DYPSerial->available() > 3)
+ {
+ // check for start byte signature
+ if (DYPSerial->read() != 0xFF)
+ continue;
+
+ // check for data bytes
+ if (DYPSerial->available() > 2)
+ {
+ uint8_t msb = DYPSerial->read();
+ uint8_t lsb = DYPSerial->read();
+ if (((uint16_t)(0xFF + msb + lsb) & 0xFF) == DYPSerial->read()) {
+ uint16_t data = (msb << 8) | lsb;
+ if (data < DYP_MIN)
+ data = DYP_BELOWMIN;
+ if (data > DYP_MAX)
+ data = DYP_ABOVEMAX;
+ DYPDistance = data;
+ }
+ else {
+ DYPDistance = DYP_CRCERROR;
+ }
+ }
+ }
+
+
+}
+
+void DYPShow(bool json)
+{
+ char types[5] = "DYP";
+ if (json)
+ {
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_DISTANCE "\":%d}"), types, DYPDistance);
+ #ifdef USE_WEBSERVER
+ }
+ else
+ {
+ WSContentSend_PD(HTTP_SNS_RANGE, types, DYPDistance);
+ #endif // USE_WEBSERVER
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns76(uint8_t function)
+{
+ if (!PinUsed(GPIO_DYP_RX))
+ return false;
+
+ switch (function)
+ {
+ case FUNC_INIT:
+ DYPInit();
+ break;
+ case FUNC_EVERY_SECOND:
+ DYPEverySecond();
+ break;
+ case FUNC_JSON_APPEND:
+ DYPShow(1);
+ break;
+ #ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ DYPShow(0);
+ break;
+ #endif // USE_WEBSERVER
+ }
+ return false;
+}
+
+#endif // USE_DYP