diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h
index b2b151644..9323c9174 100644
--- a/tasmota/language/bg-BG.h
+++ b/tasmota/language/bg-BG.h
@@ -641,6 +641,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 332a45920..6303708de 100644
--- a/tasmota/language/cs-CZ.h
+++ b/tasmota/language/cs-CZ.h
@@ -641,6 +641,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 1f534f27f..8cf6d8def 100644
--- a/tasmota/language/de-DE.h
+++ b/tasmota/language/de-DE.h
@@ -641,6 +641,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 fc540043e..4a59d87b8 100644
--- a/tasmota/language/el-GR.h
+++ b/tasmota/language/el-GR.h
@@ -641,6 +641,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 e5a82f411..e28e153e9 100644
--- a/tasmota/language/en-GB.h
+++ b/tasmota/language/en-GB.h
@@ -641,6 +641,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 9331a3f62..69c91c693 100644
--- a/tasmota/language/es-ES.h
+++ b/tasmota/language/es-ES.h
@@ -641,6 +641,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 1ca53402e..8b71a8067 100644
--- a/tasmota/language/fr-FR.h
+++ b/tasmota/language/fr-FR.h
@@ -641,6 +641,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 a8f3ba572..09a803be6 100644
--- a/tasmota/language/he-HE.h
+++ b/tasmota/language/he-HE.h
@@ -641,6 +641,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 2d888bd81..551d81014 100644
--- a/tasmota/language/hu-HU.h
+++ b/tasmota/language/hu-HU.h
@@ -641,6 +641,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 3ec7e9773..e23c86757 100644
--- a/tasmota/language/it-IT.h
+++ b/tasmota/language/it-IT.h
@@ -641,6 +641,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 2377fadb1..ddc815de5 100644
--- a/tasmota/language/ko-KO.h
+++ b/tasmota/language/ko-KO.h
@@ -641,6 +641,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 24bdc17e6..46e29e1fd 100644
--- a/tasmota/language/nl-NL.h
+++ b/tasmota/language/nl-NL.h
@@ -641,6 +641,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 c96df7c95..2a75d6f46 100644
--- a/tasmota/language/pl-PL.h
+++ b/tasmota/language/pl-PL.h
@@ -641,6 +641,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 38c1e4b48..f1b8fdbc5 100644
--- a/tasmota/language/pt-BR.h
+++ b/tasmota/language/pt-BR.h
@@ -641,6 +641,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 4ed7d874d..36188994d 100644
--- a/tasmota/language/pt-PT.h
+++ b/tasmota/language/pt-PT.h
@@ -641,6 +641,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 92307ba89..5690f9209 100644
--- a/tasmota/language/ru-RU.h
+++ b/tasmota/language/ru-RU.h
@@ -641,6 +641,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 327b4c11f..b7bd30f25 100644
--- a/tasmota/language/sk-SK.h
+++ b/tasmota/language/sk-SK.h
@@ -641,6 +641,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 30434d696..483633ae1 100644
--- a/tasmota/language/sv-SE.h
+++ b/tasmota/language/sv-SE.h
@@ -641,6 +641,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 637899101..62990d5aa 100644
--- a/tasmota/language/tr-TR.h
+++ b/tasmota/language/tr-TR.h
@@ -641,6 +641,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 0bf4736cb..fbeb0f782 100644
--- a/tasmota/language/uk-UA.h
+++ b/tasmota/language/uk-UA.h
@@ -641,6 +641,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 6e2621b4e..95ba59358 100644
--- a/tasmota/language/zh-CN.h
+++ b/tasmota/language/zh-CN.h
@@ -641,6 +641,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 b5445a3f6..b2ebcddd5 100644
--- a/tasmota/language/zh-TW.h
+++ b/tasmota/language/zh-TW.h
@@ -641,6 +641,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