diff --git a/BUILDS.md b/BUILDS.md
index f3dbeadab..f724c74bd 100644
--- a/BUILDS.md
+++ b/BUILDS.md
@@ -219,6 +219,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_IR_REMOTE_FULL | - | - / - | - | - | x | - | Enable ALL protocols
| | | | | | | |
| USE_SR04 | - | - / - | - | x | - | - |
+| USE_ME007 | - | - / - | - | - | - | - |
| USE_DYP | - | - / - | - | - | - | - |
| USE_TM1638 | - | - / x | - | x | - | - |
| USE_HX711 | - | - / x | - | x | - | - |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41d2a4511..e2e2a23fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge (#17247)
- Berry crypto module, with AES_GCM by default and EC_CC25519 optional
- IPv6 support for Ethernet (ESP32)
+- Support for ME007-ULS narrow FoV ultrasonic distance sensor by Mathias Buder (#17376)
### Changed
- TasmotaSerial library from v3.5.0 to v3.6.0
diff --git a/CODE_OWNERS.md b/CODE_OWNERS.md
index 0df3e4a1f..b2c3231cb 100644
--- a/CODE_OWNERS.md
+++ b/CODE_OWNERS.md
@@ -111,7 +111,7 @@ In addition to @arendst the following code is mainly owned by:
| xsns_20_novasds | Norbert Richter
| xsns_21_sgp30 | Gerhard Mutz
| xsns_22_sr04 | Nuno Ferreira, @arendst
-| xsns_23 |
+| xsns_23_me007 | Mathias Buder
| xsns_24_si1145 |
| xsns_25 |
| xsns_26_lm75ad | Andre Thomas
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 48a7f2f3e..16fa550aa 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -128,6 +128,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069)
+- Support for ME007-ULS narrow FoV ultrasonic distance sensor by Mathias Buder [#17376](https://github.com/arendst/Tasmota/issues/17376)
- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Teleinfo TEMPO (BBR) contract [#17160](https://github.com/arendst/Tasmota/issues/17160)
- Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge [#17247](https://github.com/arendst/Tasmota/issues/17247)
diff --git a/tasmota/berry/include/be_gpio_defines.h b/tasmota/berry/include/be_gpio_defines.h
index eee29d979..ff68ac354 100644
--- a/tasmota/berry/include/be_gpio_defines.h
+++ b/tasmota/berry/include/be_gpio_defines.h
@@ -149,6 +149,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MCP39F5_RST", (int32_t) GPIO_MCP39F5_RST },
{ "MCP39F5_RX", (int32_t) GPIO_MCP39F5_RX },
{ "MCP39F5_TX", (int32_t) GPIO_MCP39F5_TX },
+ { "ME007_RX", (int32_t) GPIO_ME007_RX },
+ { "ME007_TRIG", (int32_t) GPIO_ME007_TRIG },
{ "MGC3130_RESET", (int32_t) GPIO_MGC3130_RESET },
{ "MGC3130_XFER", (int32_t) GPIO_MGC3130_XFER },
{ "MHZ_RXD", (int32_t) GPIO_MHZ_RXD },
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index 60799d67c..e425b018a 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -177,6 +177,7 @@
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
+//#define USE_ME007 // Add support for ME007 ultrasonic devices (+1k5 code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
@@ -449,6 +450,7 @@
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
+#undef USE_ME007 // Disable support for ME007 ultrasonic devices (+1k5 code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_MODBUS_BRIDGE // Disable support for software Modbus Bridge (+3k code)
@@ -580,6 +582,7 @@
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
+#undef USE_ME007 // Disable support for ME007 ultrasonic devices (+1k5 code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_MODBUS_BRIDGE // Disable support for software Modbus Bridge (+3k code)
@@ -728,6 +731,7 @@
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
+#undef USE_ME007 // Disable support for ME007 ultrasonic devices (+1k5 code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_MODBUS_BRIDGE // Disable support for software Modbus Bridge (+3k code)
@@ -882,6 +886,7 @@
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
+#undef USE_ME007 // Disable support for ME007 ultrasonic devices (+1k5 code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_MODBUS_BRIDGE // Disable support for software Modbus Bridge (+3k code)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index aa1c0d823..0219dc4bc 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -113,6 +113,7 @@
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor
#undef USE_SR04 // Disable support for HC-SR04 ultrasonic devices (+1k code)
+#undef USE_ME007 // Disable support for ME007 ultrasonic devices (+1k5 code)
#undef USE_DYP // Disable support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_MODBUS_BRIDGE // Disable support for software Modbus Bridge (+3k code)
@@ -445,6 +446,7 @@
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
+//#define USE_ME007 // Add support for ME007 ultrasonic devices (+1k5 code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
@@ -665,6 +667,7 @@
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
+//#define USE_ME007 // Add support for ME007 ultrasonic devices (+1k5 code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index e4e622cb8..60a85240a 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -202,7 +202,8 @@ enum UserSelectablePins {
GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ
GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins
GPIO_LD2410_TX, GPIO_LD2410_RX, // HLK-LD2410
- GPIO_MBR_TX_ENA, GPIO_NRG_MBS_TX_ENA, // Modbus Bridge Serial Transmit Enable
+ GPIO_MBR_TX_ENA, GPIO_NRG_MBS_TX_ENA, // Modbus Bridge Serial Transmit Enable
+ GPIO_ME007_TRIG, GPIO_ME007_RX, // ME007 Serial/Trigger interface
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -453,6 +454,7 @@ const char kSensorNames[] PROGMEM =
D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|"
D_SENSOR_LD2410_TX "|" D_SENSOR_LD2410_RX "|"
D_SENSOR_MBR_TX_ENA "|" D_SENSOR_NRG_MBS_TX_ENA "|"
+ D_SENSOR_ME007_TRIG "|" D_SENSOR_ME007_RX "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -773,6 +775,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin
AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin
#endif
+#ifdef USE_ME007
+ AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino)
+ AGPIO(GPIO_ME007_RX), // ME007 Rx pin (xsns_23_me007.ino)
+#endif
#ifdef USE_TM1638
AGPIO(GPIO_TM1638CLK), // TM1638 Clock
AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index b3ff8c4b7..90d1cc897 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 3281cdc47..ff00e7b10 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Дебитомер"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 8ac3e95c7..cd7303851 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Cabal"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 9707e8836..2dda6f462 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index cdd50b101..a655df3ed 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index 308dc79bb..25a808e28 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index a42565b7e..805cefd30 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index b3608171e..68d8da907 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 8f0425f16..917389ff3 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 10a5a9798..70a30215b 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 653dba154..33360d150 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index 66cce299b..52f536ec4 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index f595ca2ec..a962827bd 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x - TX"
#define D_SENSOR_CM11_RX "CM110x - RX"
#define D_SENSOR_FLOWRATEMETER "Portata"
+#define D_SENSOR_ME007_TRIG "ME007 - Tri"
+#define D_SENSOR_ME007_RX "ME007 - RX"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index d397732fd..d09b81e03 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 2e738f427..7d0624efb 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index c4ace8791..10c0b3b68 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index 288d5c74b..1fce258ee 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 8e30a194a..af1763dc8 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 30458b06f..0dd99d363 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 22baa6b7f..8de5385e5 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 2c26bc49e..01859df42 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index 8e0b22ed6..d0607da30 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 9feaf5034..dcb243c02 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 96fae7c7e..cc5c3de2f 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index e0a9df039..ef0035a26 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index c96261c13..b3f8cf5fe 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index c0072dba0..a4fd10115 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -915,6 +915,8 @@
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
+#define D_SENSOR_ME007_TRIG "ME007 Tri"
+#define D_SENSOR_ME007_RX "ME007 Rx"
// Units
#define D_UNIT_AMPERE "安培"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index b73e0ff80..8d2a50a6e 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -773,17 +773,20 @@
// -- Serial sensors ------------------------------
//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
-//#define USE_CM110x // Add support for CM110x CO2 sensors (+2k7code)
+//#define USE_CM110x // Add support for CM110x CO2 sensors (+2k7code)
#define CO2_LOW 800 // Below this CO2 value show green light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
- //#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
- //#define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
+// #define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
+// #define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+1k5 code)
#define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4)
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
- #define SR04_MAX_SENSOR_DISTANCE 500 // Set sensor max detection distance
+// #define SR04_MAX_SENSOR_DISTANCE 500 // Set sensor max detection distance
+//#define USE_ME007 // Add support for ME007 ultrasonic devices (+1k5 code)
+// #define ME007_MAX_SENSOR_DISTANCE 800 // Set sensor max detection distance
+// #define ME007_ENABLE_MEDIAN_FILTER // Enables that distance measurements are filtered with an median filter of length 5
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
// #define SERIAL_BRIDGE_BUFFER_SIZE 256 // Serial Bridge receive buffer size (Default ESP8266 = 256, ESP32 = 800)
@@ -792,7 +795,7 @@
//#define USE_TCP_BRIDGE // Add support for Serial to TCP bridge (+1.3k code)
//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, pause, stop, track, volume and reset
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
-// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
+// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index b70ed8c93..fa6b4c336 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -858,7 +858,9 @@ void ResponseAppendFeatures(void)
#ifdef USE_LD2410
feature9 |= 0x00000400; // xsns_102_ld2410.ino
#endif
-// feature9 |= 0x00000800;
+#ifdef USE_ME007
+ feature9 |= 0x00000800; // xsns_23_me007.ino
+#endif
// feature9 |= 0x00001000;
// feature9 |= 0x00002000;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_23_me007.ino b/tasmota/tasmota_xsns_sensor/xsns_23_me007.ino
new file mode 100644
index 000000000..ebef6edd3
--- /dev/null
+++ b/tasmota/tasmota_xsns_sensor/xsns_23_me007.ino
@@ -0,0 +1,535 @@
+/*
+ xsns_23_me007ula.ino - ME007 ultrasonic sensor support for Tasmota
+
+ Copyright (C) 2022 Mathias Buder
+
+ This program is free software: you can redistribute 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 distributed 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_ME007
+/*********************************************************************************************\
+ * ME007 - Ultrasonic distance sensor
+ *
+ * Code for ME007 family of ultrasonic distance sensors
+ * References:
+ * - https://wiki.dfrobot.com/Water-proof%20Ultrasonic%20Sensor%20(ULS)%20%20SKU:%20SEN0300
+\*********************************************************************************************/
+
+/*********************************************************************************************/
+/* Includes*/
+/*********************************************************************************************/
+#include
+
+/*********************************************************************************************/
+/* Defines */
+/*********************************************************************************************/
+#define XSNS_23 23
+
+#define ME007_VERSION "1.0.0" /**< Driver version X.Y.Z: X:Major, Y: Minor, Z: Patch */
+
+#define ME007_DEBUG_MSG_TAG "ME7: "
+#define ME007_WS_MQTT_MSG_TAG "ME7"
+#define ME007_SENSOR_ERROR_CNT_CURRENT_TAG "ErrorCounterCurrent"
+#define ME007_SENSOR_ERROR_CNT_TOTAL_TAG "ErrorCounterTotal"
+#define ME007_SENSOR_VERSION_TAG "DriverVersion"
+
+#define ME007_MIN_SENSOR_DISTANCE 30U /**< Minimum measurement distance @unit cm */
+#ifndef ME007_MAX_SENSOR_DISTANCE
+#define ME007_MAX_SENSOR_DISTANCE 800U /**< Maximum measurement distance @unit cm */
+#endif
+#define ME007_SERIAL_IF_BAUD_RATE 9600U /**< Serial interface baud rate @unit Baud */
+#define ME007_SERIAL_SOF 0xFF /**< Start of frame indicator (header) */
+#define ME007_SERIAL_FRAME_SIZE 6U /**< Total frame size: Header (1Byte) + Distance (2 byte) + Temperature (2 byte) + Checksum (1 byte) = 6 byte */
+#define ME007_SERIAL_MAX_WAIT_TIME 120U /**< Max. wait time for data after trigger signal @unit ms */
+#define ME007_SERIAL_MAX_DATA_RECEIVE_TIME 500U /**< Max. time to receive entire data frame @unit ms */
+#define ME007_TRIG_SIG_DURATION_MS 1U /**< Time duration of trigger low-pulse @unit ms */
+#define ME007_MEDIAN_FILTER_SIZE 5U /**< Median filter samples, must be an odd number @unit sample */
+#define ME007_MEDIAN_FILTER_MEDIAN_IDX ( ( uint8_t )( ME007_MEDIAN_FILTER_SIZE - 1U) / 2U ) /**< Median filter samples @unit sample */
+#define ME007_MEDIAN_FILTER_MEASURE_DELAY 30U /**< Small delay between consecutive measurements @unit ms */
+#define ME007_SENSOR_NUM_ERROR 10U /**< Number of tries to detect sensor */
+
+/*********************************************************************************************/
+/* Enums */
+/*********************************************************************************************/
+/**
+ * @details Sensor readings type
+ */
+enum ME007_SHOW_TYPE
+{
+ ME007_SHOW_TYPE_JS = 0U, /**< @details Domain log message tag string */
+ ME007_SHOW_TYPE_WS
+};
+
+/**
+ * @details Sensor serial interface mode type
+ */
+typedef enum ME007_SERIAL_RECEIVE_TYPE_TAG
+{
+ ME007_SERIAL_RECEIVE_TYPE_SOF = 0U, /**< @details Receive Start-Of-Frame character */
+ ME007_SERIAL_RECEIVE_TYPE_DATA /**< @details Receive data (distance + temperature + checksum) */
+} ME007_SERIAL_RECEIVE_TYPE;
+
+/**
+ * @details Sensor serial interface byte type
+ */
+enum ME007_SERIAL_BYTE_TYPE
+{
+ ME007_SERIAL_BYTE_TYPE_SOF = 0U, /**< @details Receive Start-Of-Frame character */
+ ME007_SERIAL_BYTE_TYPE_DIST_H, /**< @details Distance MSB */
+ ME007_SERIAL_BYTE_TYPE_DIST_L, /**< @details Distance LSB */
+ ME007_SERIAL_BYTE_TYPE_TEMP_H, /**< @details Temperature MSB */
+ ME007_SERIAL_BYTE_TYPE_TEMP_L, /**< @details Temperature LSB */
+ ME007_SERIAL_BYTE_TYPE_CHECKSUM /**< @details Frame checksum */
+};
+
+/**
+ * @details Global sensor error type
+ */
+typedef enum ME007_ERROR_TYPE_TAG
+{
+ ME007_ERROR_TYPE_NONE = 0U, /**< @details No error present */
+ ME007_ERROR_TYPE_TIMEOUT, /**< @details Serial frame not receive in time */
+ ME007_ERROR_TYPE_CRC /**< @details Checksum calculate/compare failed */
+} ME007_ERROR_TYPE;
+
+/**
+ * @details Global sensor state type
+ */
+typedef enum ME007_STATE_TYPE_TAG
+{
+ ME007_STATE_NOT_DETECTED = 0U, /**< @details Sensor not detected */
+ ME007_STATE_DETECTED /**< @details Sensor detected */
+} ME007_STATE_TYPE;
+
+/*********************************************************************************************/
+/* Structures */
+/*********************************************************************************************/
+
+/**
+ * @details Global sensor data structure
+ */
+struct
+{
+ uint8_t pin_rx_u8; /**< @details Serial interface receive pin */
+ uint8_t pin_trig_u8; /**< @details Sensor trigger pin */
+ ME007_STATE_TYPE state_e; /**< @details Global sensor state */
+ float distance_cm_f32; /**< @details Output distance measurement @unit cm */
+ float temperature_deg_f32; /**< @details Output temperature measurement @unit °C */
+ uint8_t error_cnt_current_u8; /**< @details Measurement error counter (current) */
+ uint16_t error_cnt_total_u16; /**< @details Measurement error counter (total) */
+} me007_data_s;
+
+/*********************************************************************************************/
+/* Global Variables */
+/*********************************************************************************************/
+TasmotaSerial* gp_serial_if = nullptr; /**< @details Pointer to serial interface object */
+
+/*********************************************************************************************/
+/* Function Prototypes */
+/*********************************************************************************************/
+
+/**
+ * @details This function initializes the sensor driver and its underlying serial interface.
+ */
+void me007_init( void );
+
+/**
+ * @details This function performs a single distance/temperature measurement.
+ * @param[out] float* p_distance_cm_f32 Pointer to variable supposed to store the current distance reading.
+ * @param[out] float* p_temperature_f32 Pointer to variable supposed to store the current temperature reading.
+ * @return ME007_ERROR_TYPE Status of current measurement.
+ */
+ME007_ERROR_TYPE me007_measure( float* const p_distance_cm_f32, float* const p_temperature_f32 );
+
+/**
+ * @details This function sorts a list if float values in ascending order.
+ * @param[in] const void* p_list Pointer to list to be sorted
+ * @param[in] const uint8_t size_u8 Size of list to be sorted.
+ */
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+void me007_sort_asc( float* const p_list, const uint8_t size_u8 );
+#endif
+
+/**
+ * @details This function performs multiple sensor measurements and filters the output if enables.
+ */
+void me007_read_value( void );
+
+/**
+ * @details This function sends the current distance/temperature measurements to the web-interface / MQTT / Domoticz.
+ * @param[in] ME007_SHOW_TYPE type_e Variable to decide where to output the sensor measurements.
+ */
+void me007_show( const ME007_SHOW_TYPE type_e );
+
+/*********************************************************************************************/
+/* Function Definitions */
+/*********************************************************************************************/
+void me007_init( void )
+{
+ AddLog( LOG_LEVEL_INFO, PSTR( ME007_DEBUG_MSG_TAG "Initializing ..." ) );
+
+ /* Check if sensor pins are selected/used in web-interface */
+ if ( ( false == PinUsed( GPIO_ME007_TRIG ) )
+ || ( false == PinUsed( GPIO_ME007_RX ) ) )
+ {
+ AddLog( LOG_LEVEL_ERROR, PSTR( ME007_DEBUG_MSG_TAG "Serial/Trigger interface not configured" ) );
+ return;
+ }
+
+ /* Init some global sensor data structure elements */
+ me007_data_s.state_e = ME007_STATE_NOT_DETECTED;
+ me007_data_s.error_cnt_current_u8 = 0U;
+ me007_data_s.error_cnt_total_u16 = 0U;
+
+ /* Store real pin number */
+ me007_data_s.pin_rx_u8 = Pin( GPIO_ME007_RX );
+ me007_data_s.pin_trig_u8 = Pin( GPIO_ME007_TRIG );
+
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Using GPIOs: Trigger: %i / Rx: %i)" ),
+ me007_data_s.pin_trig_u8,
+ me007_data_s.pin_rx_u8 );
+
+ /* Configure serial interface */
+ /* Only Rx pin is required as ME007 is controlled using its trigger pin. Therefore, passing value "-1" as transmit_pin argument */
+ gp_serial_if = new TasmotaSerial( me007_data_s.pin_rx_u8, -1, 2U );
+
+ if ( ( nullptr != gp_serial_if )
+ && ( true == gp_serial_if->begin( ME007_SERIAL_IF_BAUD_RATE ) ) )
+ {
+ if ( true == gp_serial_if->hardwareSerial() )
+ {
+ ClaimSerial();
+ }
+
+ pinMode( me007_data_s.pin_trig_u8, OUTPUT ); /**< @details Configure trigger pin as output */
+ digitalWrite( me007_data_s.pin_trig_u8, HIGH ); /**< @details Set trigger pin to high-level as it ME007 requires a falling edge to initiate measurement */
+
+ /* Detect sensor */
+ AddLog( LOG_LEVEL_INFO, PSTR( ME007_DEBUG_MSG_TAG "Detecting ..." ) );
+ for ( uint8_t idx_u8 = 0U; idx_u8 < ME007_SENSOR_NUM_ERROR; ++idx_u8 )
+ {
+ ME007_ERROR_TYPE detected_e = me007_measure( &me007_data_s.distance_cm_f32,
+ &me007_data_s.temperature_deg_f32 );
+ if ( ME007_ERROR_TYPE_NONE == detected_e )
+ {
+ me007_data_s.state_e = ME007_STATE_DETECTED;
+ break;
+ }
+ else
+ {
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Measurement error: %i" ), idx_u8 );
+ }
+ }
+ AddLog( LOG_LEVEL_INFO, PSTR( ME007_DEBUG_MSG_TAG "%s" ), me007_data_s.state_e == ME007_STATE_DETECTED ? "Detected" : "Not detected, Sensor deactivated" );
+ }
+ else
+ {
+ AddLog( LOG_LEVEL_ERROR, PSTR( ME007_DEBUG_MSG_TAG "Serial interface unavailable" ) );
+ }
+}
+
+ME007_ERROR_TYPE me007_measure( float* const p_distance_cm_f32, float* const p_temperature_f32 )
+{
+ ME007_SERIAL_RECEIVE_TYPE state_e = ME007_SERIAL_RECEIVE_TYPE_SOF; /**< @details Always start trying to receive SOF */
+ uint8_t buffer_vu8[ME007_SERIAL_FRAME_SIZE] = {0U};
+ uint8_t buffer_idx_u8 = 0U;
+ uint8_t data_byte_u8 = 0U;
+ uint32_t timestamp_ms_u32 = 0U;
+
+ if ( ( nullptr != p_distance_cm_f32 )
+ && ( nullptr != p_temperature_f32 )
+ && ( nullptr != gp_serial_if ) )
+ {
+ /* Trigger new sensor measurement */
+ digitalWrite( me007_data_s.pin_trig_u8, LOW );
+ timestamp_ms_u32 = millis(); /**< @details Store trigger time */
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Sensor reading triggered" ) );
+ delay( ME007_TRIG_SIG_DURATION_MS ); /**< @details Wait 1ms to give the oin time to go low */
+ digitalWrite( me007_data_s.pin_trig_u8, HIGH );
+
+ /* Give sensor some time to take a measurement and send the result */
+ /* Max. wait time should be T2max + T3max = 61 ms (see https://wiki.dfrobot.com/Water-proof%20Ultrasonic%20Sensor%20(ULS)%20%20SKU:%20SEN0300, section "Serial Output" for details) */
+ while ( ( timestamp_ms_u32 + ME007_SERIAL_MAX_WAIT_TIME ) >= millis() )
+ {
+ if ( 0U < gp_serial_if->available() )
+ {
+ /* Read 1 byte of data */
+ data_byte_u8 = gp_serial_if->read();
+
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Serial: Byte received: 0x%x" ), data_byte_u8 );
+
+ /* Serial Data Frame Layout
+ +──────────────────+─────────────────────+────────────────────+────────────────────────+───────────────────────+────────────+
+ | Frame Header ID | Distance Data High | Distance Data Low | Temperature Data High | Temperature Data Low | Checksum |
+ +──────────────────+─────────────────────+────────────────────+────────────────────────+───────────────────────+────────────+
+ | 0xFF | Data_H | Data_L | Temp_H | Temp_L | SUM |
+ +──────────────────+─────────────────────+────────────────────+────────────────────────+───────────────────────+────────────+ */
+
+ switch ( state_e )
+ {
+ case ME007_SERIAL_RECEIVE_TYPE_SOF:
+ if ( ME007_SERIAL_SOF == data_byte_u8 )
+ {
+ buffer_vu8[buffer_idx_u8++] = data_byte_u8;
+ state_e = ME007_SERIAL_RECEIVE_TYPE_DATA;
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "(Idx: %i) Serial: SOF detected" ), buffer_idx_u8 );
+ }
+ break;
+
+ case ME007_SERIAL_RECEIVE_TYPE_DATA:
+ buffer_vu8[buffer_idx_u8++] = data_byte_u8;
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "(Idx: %i) Receiving data: 0x%x" ), buffer_idx_u8, data_byte_u8 );
+
+ /* If all bytes have been received: calculate checksum and assembly date */
+ if ( ME007_SERIAL_FRAME_SIZE <= buffer_idx_u8 )
+ {
+ /* Calculate expected checksum (only lower 8 bit shall be used) */
+ uint8_t checksum_u8 = ( buffer_vu8[ME007_SERIAL_BYTE_TYPE_SOF]
+ + buffer_vu8[ME007_SERIAL_BYTE_TYPE_DIST_H]
+ + buffer_vu8[ME007_SERIAL_BYTE_TYPE_DIST_L]
+ + buffer_vu8[ME007_SERIAL_BYTE_TYPE_TEMP_H]
+ + buffer_vu8[ME007_SERIAL_BYTE_TYPE_TEMP_L] ) & 0x00FF;
+
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Comparing expected sum %i to checksum %i" ), checksum_u8, buffer_vu8[ME007_SERIAL_BYTE_TYPE_CHECKSUM] );
+
+ /* Compare expected and receive checksum */
+ if ( checksum_u8 == buffer_vu8[ME007_SERIAL_BYTE_TYPE_CHECKSUM] )
+ {
+ /* Assemble and scale distance to cm */
+ *p_distance_cm_f32 = ( ( buffer_vu8[ME007_SERIAL_BYTE_TYPE_DIST_H] << 8U ) + buffer_vu8[ME007_SERIAL_BYTE_TYPE_DIST_L] ) / 10.0F;
+
+ /* Apply physical sensor measurement limits */
+ if ( ME007_MIN_SENSOR_DISTANCE > *p_distance_cm_f32 )
+ {
+ *p_distance_cm_f32 = 0.0F;
+ }
+ else if ( ME007_MAX_SENSOR_DISTANCE < *p_distance_cm_f32 )
+ {
+ *p_distance_cm_f32 = ME007_MAX_SENSOR_DISTANCE;
+ }
+ else
+ {
+ /* Ok: Measurement is within the physical sensor measurement limits */
+ }
+
+ /* Assemble and scale temperature °C */
+ /* Check sign-bit (MSB) */
+ if ( 0x80 == ( buffer_vu8[ME007_SERIAL_BYTE_TYPE_TEMP_H] & 0x80 ) )
+ {
+ buffer_vu8[2U] ^= 0x80;
+ }
+
+ *p_temperature_f32 = ( ( buffer_vu8[ME007_SERIAL_BYTE_TYPE_TEMP_H] << 8U ) + buffer_vu8[ME007_SERIAL_BYTE_TYPE_TEMP_L] ) / 10.0F;
+
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Distance: %s cm, Temperature: %s °C" ),
+ String( *p_distance_cm_f32, 1U ).c_str(),
+ String( *p_temperature_f32, 1U ).c_str() );
+
+ /* All ok: Measurement valid */
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Measurement valid" ) );
+ return ME007_ERROR_TYPE_NONE;
+ }
+ else
+ {
+ /* Checksum nok: Measurement invalid */
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Checksum nok: Measurement invalid" ) );
+ return ME007_ERROR_TYPE_CRC;
+ }
+ }
+ break;
+
+ default: /* Should never happen */
+ break;
+ }
+ }
+ }
+ }
+
+ /* Timeout: Measurement invalid */
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Timeout: Measurement invalid" ) );
+ return ME007_ERROR_TYPE_TIMEOUT;
+}
+
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+void me007_sort_asc( float* const p_list, const uint8_t size_u8 )
+{
+ if( NULL != p_list )
+ {
+ for( uint8_t idx_u8 = 0U; idx_u8 < size_u8; ++idx_u8 )
+ {
+ for( uint8_t idy_u8 = ( idx_u8 + 1U ); idy_u8 < size_u8; ++idy_u8 )
+ {
+ if( p_list[idx_u8] > p_list[idy_u8] )
+ {
+ float tmp_f32 = p_list[idx_u8];
+ p_list[idx_u8] = p_list[idy_u8];
+ p_list[idy_u8] = tmp_f32;
+ }
+ }
+ }
+ }
+}
+#endif
+
+void me007_read_value( void )
+{
+ float distance_cm_f32 = 0.0F;
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+ float distance_buffer_vf32[ME007_MEDIAN_FILTER_SIZE] = {0.0F};
+#endif
+
+ /* Record some sensor measurements */
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+ for ( uint8_t idx_u8 = 0U; idx_u8 < ME007_MEDIAN_FILTER_SIZE; ++idx_u8 )
+ {
+#endif
+ ME007_ERROR_TYPE status_e = me007_measure( &distance_cm_f32,
+ &me007_data_s.temperature_deg_f32 );
+
+ switch ( status_e )
+ {
+ case ME007_ERROR_TYPE_NONE:
+
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+ /* Store valid distance measurement into histogram buffer */
+ distance_buffer_vf32[idx_u8] = distance_cm_f32;
+#else
+ me007_data_s.distance_cm_f32 = distance_cm_f32;
+#endif
+
+ if ( 0U < me007_data_s.error_cnt_current_u8 )
+ {
+ me007_data_s.error_cnt_current_u8--; /* Decrease current measurement errors by one */
+ }
+ break;
+
+ case ME007_ERROR_TYPE_CRC:
+ case ME007_ERROR_TYPE_TIMEOUT:
+ me007_data_s.error_cnt_current_u8++; /* Increase current measurement errors by one */
+ me007_data_s.error_cnt_total_u16++; /* Store total number of measurement errors */
+ break;
+
+ default: /* Should never happen */
+ break;
+ }
+
+ /* Check error counter and only print message to error log (for now)
+ in case error was present for at least ME007_SENSOR_NUM_ERROR cycles.
+ For some reason, the checksum check fails quite ofter and because
+ of that it wouldn't make sense to deactivate ME007 in case
+ ME007_SENSOR_NUM_ERROR is exceeded. */
+ if ( ME007_SENSOR_NUM_ERROR <= me007_data_s.error_cnt_current_u8 )
+ {
+ AddLog( LOG_LEVEL_ERROR, PSTR( ME007_DEBUG_MSG_TAG "Error @ counter: %i" ), me007_data_s.error_cnt_current_u8 );
+ }
+
+ DEBUG_SENSOR_LOG( PSTR( ME007_DEBUG_MSG_TAG "Error counter: Current: %i, Total: %i" ),
+ me007_data_s.error_cnt_current_u8,
+ me007_data_s.error_cnt_total_u16 );
+
+#ifdef ME007_ENABLE_MEDIAN_FILTER
+ /* Add small delay between measurement */
+ if ( ( ME007_MEDIAN_FILTER_SIZE - 1U ) > idx_u8 )
+ {
+ delay( ME007_MEDIAN_FILTER_MEASURE_DELAY );
+ }
+ }
+
+ /* Sort median filter buffer and assign median value to current distance measurement */
+ me007_sort_asc( distance_buffer_vf32, ME007_MEDIAN_FILTER_SIZE );
+
+ /* Update distance measurement */
+ me007_data_s.distance_cm_f32 = distance_buffer_vf32[ME007_MEDIAN_FILTER_MEDIAN_IDX];
+#endif
+
+}
+
+void me007_show( const ME007_SHOW_TYPE type_e )
+{
+ switch ( type_e )
+ {
+ case ME007_SHOW_TYPE_JS:
+ ResponseAppend_P( PSTR( ",\"" ME007_WS_MQTT_MSG_TAG "\":{\"" D_JSON_DISTANCE "\":%1_f,\"" D_JSON_TEMPERATURE "\":%1_f,\"" ME007_SENSOR_ERROR_CNT_CURRENT_TAG "\":%i,\"" ME007_SENSOR_ERROR_CNT_TOTAL_TAG "\":%i,\"" ME007_SENSOR_VERSION_TAG "\":\"" ME007_VERSION "\"}" ),
+ &me007_data_s.distance_cm_f32,
+ &me007_data_s.temperature_deg_f32,
+ me007_data_s.error_cnt_current_u8,
+ me007_data_s.error_cnt_total_u16 );
+#ifdef USE_DOMOTICZ
+ if ( 0U == TasmotaGlobal.tele_period )
+ {
+ DomoticzFloatSensor( DZ_COUNT, me007_data_s.distance_cm_f32 ); /**< @details Send distance as Domoticz counter value */
+ DomoticzFloatSensor( DZ_TEMP, me007_data_s.temperature_deg_f32 ); /**< @details Send distance as Domoticz temperature value */
+ }
+#endif /* USE_DOMOTICZ */
+ break;
+#ifdef USE_WEBSERVER
+ case ME007_SHOW_TYPE_WS:
+ WSContentSend_PD( HTTP_SNS_F_DISTANCE_CM,
+ ME007_WS_MQTT_MSG_TAG,
+ &me007_data_s.distance_cm_f32 );
+
+ WSContentSend_PD( HTTP_SNS_F_TEMP,
+ ME007_WS_MQTT_MSG_TAG,
+ Settings->flag2.temperature_resolution,
+ &me007_data_s.temperature_deg_f32 );
+ break;
+#endif /* USE_WEBSERVER */
+
+ default: /* Should never happen */
+ break;
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns23( uint32_t function )
+{
+ bool result_b = false;
+
+ switch ( function )
+ {
+ case FUNC_INIT:
+ me007_init();
+ break;
+
+ case FUNC_EVERY_SECOND:
+ if ( ME007_STATE_DETECTED == me007_data_s.state_e )
+ {
+ me007_read_value();
+ result_b = true;
+ }
+ break;
+
+ case FUNC_JSON_APPEND:
+ if ( ME007_STATE_DETECTED == me007_data_s.state_e )
+ {
+ me007_show( ME007_SHOW_TYPE_JS );
+ }
+ break;
+
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ if ( ME007_STATE_DETECTED == me007_data_s.state_e )
+ {
+ me007_show( ME007_SHOW_TYPE_WS );
+ }
+ break;
+#endif // USE_WEBSERVER
+ }
+ return result_b;
+}
+
+#endif // USE_ME007
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 06cab64e5..a67a9f617 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -288,7 +288,7 @@ a_features = [[
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
- "USE_DINGTIAN_RELAY","USE_HMC5883L","USE_LD2410","",
+ "USE_DINGTIAN_RELAY","USE_HMC5883L","USE_LD2410","USE_ME007",
"","","","",
"","","","",
"","","","",
diff --git a/tools/lv_gpio/lv_gpio_enum.h b/tools/lv_gpio/lv_gpio_enum.h
index 933d83f02..d57740364 100644
--- a/tools/lv_gpio/lv_gpio_enum.h
+++ b/tools/lv_gpio/lv_gpio_enum.h
@@ -82,6 +82,8 @@ SBR_TX = GPIO_SBR_TX
SBR_RX = GPIO_SBR_RX
SR04_TRIG = GPIO_SR04_TRIG
SR04_ECHO = GPIO_SR04_ECHO
+ME007_TRIG = GPIO_ME007_TRIG
+ME007_RX = GPIO_ME007_RX
SDM120_TX = GPIO_SDM120_TX
SDM120_RX = GPIO_SDM120_RX
SDM630_TX = GPIO_SDM630_TX