diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h
index 9a6ce8abc..16bf2f2c0 100644
--- a/tasmota/language/bg-BG.h
+++ b/tasmota/language/bg-BG.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h
index d98361640..5f066e2fc 100644
--- a/tasmota/language/cs-CZ.h
+++ b/tasmota/language/cs-CZ.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h
index 05835a49c..ed8d7b612 100644
--- a/tasmota/language/de-DE.h
+++ b/tasmota/language/de-DE.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h
index 0ddd43918..215d42733 100644
--- a/tasmota/language/el-GR.h
+++ b/tasmota/language/el-GR.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h
index b175cc193..783c6e343 100644
--- a/tasmota/language/en-GB.h
+++ b/tasmota/language/en-GB.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h
index 12e732bc2..3b68654c5 100644
--- a/tasmota/language/es-ES.h
+++ b/tasmota/language/es-ES.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h
index e9c31da46..15b9b06fb 100644
--- a/tasmota/language/fr-FR.h
+++ b/tasmota/language/fr-FR.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h
index f836a92b9..32e114af9 100644
--- a/tasmota/language/he-HE.h
+++ b/tasmota/language/he-HE.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h
index da313caaa..74143fac2 100644
--- a/tasmota/language/hu-HU.h
+++ b/tasmota/language/hu-HU.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h
index efaecc1a5..7297a9b74 100644
--- a/tasmota/language/it-IT.h
+++ b/tasmota/language/it-IT.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h
index 794b97e84..a32ec4b10 100644
--- a/tasmota/language/ko-KO.h
+++ b/tasmota/language/ko-KO.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h
index 288da67d5..f78f63a8b 100644
--- a/tasmota/language/nl-NL.h
+++ b/tasmota/language/nl-NL.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h
index e15ccbbc2..2424fecdb 100644
--- a/tasmota/language/pl-PL.h
+++ b/tasmota/language/pl-PL.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h
index 9b24d05c8..f6526e5f1 100644
--- a/tasmota/language/pt-BR.h
+++ b/tasmota/language/pt-BR.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h
index 9565fc7a5..5a0903b9d 100644
--- a/tasmota/language/pt-PT.h
+++ b/tasmota/language/pt-PT.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h
index 700958875..d1f1a975c 100644
--- a/tasmota/language/ru-RU.h
+++ b/tasmota/language/ru-RU.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h
index dbee001e9..a5d98e87a 100644
--- a/tasmota/language/sk-SK.h
+++ b/tasmota/language/sk-SK.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h
index a8e5aa6a8..403416835 100644
--- a/tasmota/language/sv-SE.h
+++ b/tasmota/language/sv-SE.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h
index 430289372..6303befea 100644
--- a/tasmota/language/tr-TR.h
+++ b/tasmota/language/tr-TR.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk-UA.h
index 2b4873e7a..ee335b8e5 100644
--- a/tasmota/language/uk-UA.h
+++ b/tasmota/language/uk-UA.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h
index 5a71e95dc..8c409882e 100644
--- a/tasmota/language/zh-CN.h
+++ b/tasmota/language/zh-CN.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "安"
diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h
index 9883972f1..5ca55679a 100644
--- a/tasmota/language/zh-TW.h
+++ b/tasmota/language/zh-TW.h
@@ -643,6 +643,7 @@
#define D_SENSOR_LE01MR_TX "LE-01MR Tx"
#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0"
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
+#define D_SENSOR_HRXL_RX "HRXL Rx"
// Units
#define D_UNIT_AMPERE "安"
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 5494fbcf3..cdc976bb0 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -224,6 +224,7 @@ enum UserSelectablePins {
GPIO_LE01MR_TX, // F&F LE-01MR energy meter
GPIO_CC1101_GDO0, // CC1101 pin for RX
GPIO_CC1101_GDO2, // CC1101 pin for RX
+ GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality
@@ -308,7 +309,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_DS18X20 "o|" D_SENSOR_DHT11 "o|"
D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|"
D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|"
- D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2
+ D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|"
+ D_SENSOR_HRXL_RX
;
const char kSensorNamesFixed[] PROGMEM =
@@ -797,6 +799,9 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_CC1101_GDO0, // CC1101 pin for RX
GPIO_CC1101_GDO2, // CC1101 pin for RX
#endif
+#ifdef USE_HRXL
+ GPIO_HRXL_RX,
+#endif
};
const uint8_t kModuleNiceList[] PROGMEM = {
diff --git a/tasmota/xsns_64_hrxl.ino b/tasmota/xsns_64_hrxl.ino
new file mode 100644
index 000000000..a82134c94
--- /dev/null
+++ b/tasmota/xsns_64_hrxl.ino
@@ -0,0 +1,126 @@
+/*
+ xsns_64_hrxl.ino - MaxBotix HRXL serial interface
+
+ Copyright (C) 2020 Jon Little
+
+ 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_HRXL
+/*********************************************************************************************\
+ * MaxBotix HRXL-MaxSonar ultrasonic range finders
+ * Source: https://www.maxbotix.com/documents/HRXL-MaxSonar-WR_Datasheet.pdf
+ *
+ * Hardware Serial will be selected if GPIO1 = [HRXL Rx]
+\*********************************************************************************************/
+
+#define XSNS_64 64
+
+#include
+
+#define HRXL_READ_TIMEOUT 400 // us; enough for 6 bytes@9600bps
+
+TasmotaSerial *HRXLSerial = nullptr;
+
+uint32_t hrxl_distance_mm = 0; // distance, mm
+bool hrxl_found = false;
+
+/*********************************************************************************************/
+
+void HRXLInit(void)
+{
+ hrxl_found = false;
+ if ((pin[GPIO_HRXL_RX] < 99))
+ {
+ HRXLSerial = new TasmotaSerial(pin[GPIO_HRXL_RX], -1, 1);
+ if (HRXLSerial->begin(9600))
+ {
+ if (HRXLSerial->hardwareSerial())
+ ClaimSerial();
+ hrxl_found = true;
+ HRXLSerial->setTimeout(HRXL_READ_TIMEOUT);
+ }
+ }
+}
+
+void HRXLEverySecond(void)
+{
+ if (!hrxl_found)
+ return;
+
+ int num_read=0;
+ int sum=0;
+ while (HRXLSerial->available()>5)
+ {
+ if (HRXLSerial->read() != 'R')
+ continue;
+
+ int d = HRXLSerial->parseInt();
+ if (d >= 30 && d<=5000)
+ {
+ sum += d;
+ num_read++;
+ }
+ }
+ if (num_read>1)
+ hrxl_distance_mm = int(sum / num_read);
+
+}
+
+
+void HRXLShow(bool json)
+{
+ char types[5] = "HRXL";
+ if (json)
+ {
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_DISTANCE "\":%d}"), types, hrxl_distance_mm);
+#ifdef USE_WEBSERVER
+ }
+ else
+ {
+ WSContentSend_PD(HTTP_SNS_RANGE, types, hrxl_distance_mm);
+#endif // USE_WEBSERVER
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns64(uint8_t function)
+{
+ if (pin[GPIO_HRXL_RX] >= 99)
+ return false;
+
+ switch (function)
+ {
+ case FUNC_INIT:
+ HRXLInit();
+ break;
+ case FUNC_EVERY_SECOND:
+ HRXLEverySecond();
+ break;
+ case FUNC_JSON_APPEND:
+ HRXLShow(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ HRXLShow(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ return false;
+}
+
+#endif // USE_HRXL