From fcc6d5437b1af84f39756a2056bb978cf17a64f2 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 11 Oct 2018 17:33:07 +0200
Subject: [PATCH] Add HX711 Load Cell
* Add support for DS3231 Real Time Clock
* Add support for HX711 Load Cell
* Add command WeightRes 0..3 to control display of decimals for kilogram
---
sonoff/_changelog.ino | 3 +
sonoff/language/bg-BG.h | 6 +
sonoff/language/cs-CZ.h | 6 +
sonoff/language/de-DE.h | 6 +
sonoff/language/el-GR.h | 6 +
sonoff/language/en-GB.h | 6 +
sonoff/language/es-AR.h | 6 +
sonoff/language/fr-FR.h | 6 +
sonoff/language/he-HE.h | 6 +
sonoff/language/hu-HU.h | 6 +
sonoff/language/it-IT.h | 6 +
sonoff/language/nl-NL.h | 6 +
sonoff/language/pl-PL.h | 6 +
sonoff/language/pt-BR.h | 6 +
sonoff/language/pt-PT.h | 6 +
sonoff/language/ru-RU.h | 6 +
sonoff/language/tr-TR.h | 7 +-
sonoff/language/uk-UK.h | 6 +
sonoff/language/zh-CN.h | 6 +
sonoff/language/zh-TW.h | 6 +
sonoff/settings.h | 4 +-
sonoff/sonoff.h | 2 +-
sonoff/support.ino | 10 +
sonoff/user_config.h | 5 +-
sonoff/xdrv_01_webserver.ino | 6 +
sonoff/xsns_34_hx711.ino | 390 +++++++++++++++++++++++++++++++++++
tools/decode-status.py | 2 +-
27 files changed, 531 insertions(+), 6 deletions(-)
create mode 100644 sonoff/xsns_34_hx711.ino
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index def41834a..eec4ac701 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -1,5 +1,8 @@
/* 6.2.1.14 20181010
* Rewrite Webserver page handler for easier extension (thx to Adrian Scillato)
+ * Add support for DS3231 Real Time Clock
+ * Add support for HX711 Load Cell
+ * Add command WeightRes 0..3 to control display of decimals for kilogram
*
* 6.2.1.13 20181008
* Change default Mqtt client library from PubSubClient to non-blocking ArduinoMqtt by Joel Gaehwiler
diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h
index 177bc69ab..a7d3fca7d 100644
--- a/sonoff/language/bg-BG.h
+++ b/sonoff/language/bg-BG.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Жироскоп - ос Y"
#define D_GZ_AXIS "Жироскоп - ос Z"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Няма"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h
index e4fb5c66d..345bf15cc 100644
--- a/sonoff/language/cs-CZ.h
+++ b/sonoff/language/cs-CZ.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro osa-Y"
#define D_GZ_AXIS "Gyro osa-Z"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Není"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h
index dec1e4723..18d7b93d5 100644
--- a/sonoff/language/de-DE.h
+++ b/sonoff/language/de-DE.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyroskop Y-Achse"
#define D_GZ_AXIS "Gyroskop Z-Achse"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "None"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h
index e0a1cca7a..2f320211d 100644
--- a/sonoff/language/el-GR.h
+++ b/sonoff/language/el-GR.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Κανένας"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h
index 6478d5bde..ad3762f8d 100644
--- a/sonoff/language/en-GB.h
+++ b/sonoff/language/en-GB.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "None"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h
index ddf191b19..1601f03c9 100644
--- a/sonoff/language/es-AR.h
+++ b/sonoff/language/es-AR.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Ninguno"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h
index 6f0c2960a..7e1098bed 100644
--- a/sonoff/language/fr-FR.h
+++ b/sonoff/language/fr-FR.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Axe-Y"
#define D_GZ_AXIS "Gyro Axe-Z"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Aucun"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h
index b81cbd355..c6aec9681 100644
--- a/sonoff/language/he-HE.h
+++ b/sonoff/language/he-HE.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "None"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h
index 88ddb273a..857cfec12 100644
--- a/sonoff/language/hu-HU.h
+++ b/sonoff/language/hu-HU.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Nincs"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h
index 62deadea5..6b922cb4d 100644
--- a/sonoff/language/it-IT.h
+++ b/sonoff/language/it-IT.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Nessuno"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h
index 921e3b483..eb938970d 100644
--- a/sonoff/language/nl-NL.h
+++ b/sonoff/language/nl-NL.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Verwijder gewicht"
+#define D_HX_CAL_REFERENCE "Plaats ijkgewicht"
+#define D_HX_CAL_DONE "Ge-ijkt"
+#define D_HX_CAL_FAIL "Ijken is mislukt"
+
// sonoff_template.h
#define D_SENSOR_NONE "Geen"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h
index 85e141c29..0b6a07e7d 100644
--- a/sonoff/language/pl-PL.h
+++ b/sonoff/language/pl-PL.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Brak"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h
index 96874a2c0..f4c556ed9 100644
--- a/sonoff/language/pt-BR.h
+++ b/sonoff/language/pt-BR.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Nenhum"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h
index 51b40d248..f79f7a14c 100644
--- a/sonoff/language/pt-PT.h
+++ b/sonoff/language/pt-PT.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "Nenhum"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h
index 1bcf140d6..4cea913e6 100644
--- a/sonoff/language/ru-RU.h
+++ b/sonoff/language/ru-RU.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "-нет-"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h
index f28764d50..b24a355d8 100755
--- a/sonoff/language/tr-TR.h
+++ b/sonoff/language/tr-TR.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "None"
#define D_SENSOR_DHT11 "DHT11"
@@ -484,7 +490,6 @@
#define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003"
-#define D_SENSOR_SDS0X1 "SDS0X1"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_SBR_RX "SerBr Rx"
diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h
index f6a2d39c7..93b5f32cd 100644
--- a/sonoff/language/uk-UK.h
+++ b/sonoff/language/uk-UK.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "-відсутньо-"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h
index 763601964..42a381f18 100644
--- a/sonoff/language/zh-CN.h
+++ b/sonoff/language/zh-CN.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "无"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h
index 59791b776..92193f483 100644
--- a/sonoff/language/zh-TW.h
+++ b/sonoff/language/zh-TW.h
@@ -456,6 +456,12 @@
#define D_GY_AXIS "Gyro Y-Axis"
#define D_GZ_AXIS "Gyro Z-Axis"
+// xsns_34_hx711.ino
+#define D_HX_CAL_REMOVE "Remove weigth"
+#define D_HX_CAL_REFERENCE "Load reference weigth"
+#define D_HX_CAL_DONE "Calibrated"
+#define D_HX_CAL_FAIL "Calibration failed"
+
// sonoff_template.h
#define D_SENSOR_NONE "None"
#define D_SENSOR_DHT11 "DHT11"
diff --git a/sonoff/settings.h b/sonoff/settings.h
index 26f4f2865..e9e1fd110 100644
--- a/sonoff/settings.h
+++ b/sonoff/settings.h
@@ -322,8 +322,10 @@ struct SYSCFG {
uint16_t mcp230xx_int_timer; // 718
uint8_t rgbwwTable[5]; // 71A
- byte free_71F[157]; // 71F
+ byte free_71F[93]; // 71F
+ char custom1[32]; // 77C Custom
+ char custom2[32]; // 79C Custom
uint16_t weight_item; // 7BC Weight of one item in gram * 10
uint16_t weight_max; // 7BE Total max weight in kilogram
unsigned long weight_reference; // 7C0 Reference weight in gram
diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h
index 5bc744157..a573849d3 100644
--- a/sonoff/sonoff.h
+++ b/sonoff/sonoff.h
@@ -214,7 +214,7 @@ enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MA
enum XsnsFunctions {FUNC_PRE_INIT, FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD,
FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR,
- FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_HANDLER};
+ FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON, FUNC_WEB_ADD_HANDLER};
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
diff --git a/sonoff/support.ino b/sonoff/support.ino
index d5cf005ba..faf651e96 100644
--- a/sonoff/support.ino
+++ b/sonoff/support.ino
@@ -677,6 +677,10 @@ boolean GetUsedInModule(byte val, uint8_t *arr)
if (GPIO_TM16CLK == val) { return true; }
if (GPIO_TM16DIO == val) { return true; }
if (GPIO_TM16STB == val) { return true; }
+#endif
+#ifndef USE_HX711
+ if (GPIO_HX711_SCK == val) { return true; }
+ if (GPIO_HX711_DAT == val) { return true; }
#endif
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
offset = (GPIO_REL1_INV - GPIO_REL1);
@@ -1147,6 +1151,12 @@ void GetFeatures()
#ifdef USE_PZEM2
feature_sns2 |= 0x00000200; // xnrg_05_pzem2.ino
#endif
+#ifdef USE_DS3231
+ feature_sns2 |= 0x00000400; // xsns_33_ds3231.ino
+#endif
+#ifdef USE_HX711
+ feature_sns2 |= 0x00000400; // xsns_34_hx711.ino
+#endif
}
diff --git a/sonoff/user_config.h b/sonoff/user_config.h
index f37f8dc63..740027277 100644
--- a/sonoff/user_config.h
+++ b/sonoff/user_config.h
@@ -308,6 +308,8 @@
// #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code)
// #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code)
// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code)
+// #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code)
+// #define USE_RTC_ADDR 0x68 // Default I2C address 0x68
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
@@ -322,8 +324,6 @@
#define MTX_ADDRESS6 0x76 // [DisplayAddress6] I2C address of sixth 8x8 matrix module
#define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module
#define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module
-// #define USE_DS3231 // Enable use DS3231 external RTC , usefall when you don't have avaliable WIFI. see docs in the source file (+1k2 code)
-// #define USE_RTC_ADDR 0x68 //you can change the addrsss of the DS3231 RTC, default is 0x68, not mandatory fieled
#endif // USE_I2C
@@ -373,6 +373,7 @@
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
//#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
+#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code)
diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino
index c18478f03..b035c0020 100644
--- a/sonoff/xdrv_01_webserver.ino
+++ b/sonoff/xdrv_01_webserver.ino
@@ -560,6 +560,12 @@ void HandleRoot()
page += F("");
}
+#ifndef BE_MINIMAL
+ mqtt_data[0] = '\0';
+ XdrvCall(FUNC_WEB_ADD_MAIN_BUTTON);
+ page += String(mqtt_data);
+#endif // Not BE_MINIMAL
+
if (HTTP_ADMIN == webserver_state) {
page += FPSTR(HTTP_BTN_MENU1);
page += FPSTR(HTTP_BTN_RSTRT);
diff --git a/sonoff/xsns_34_hx711.ino b/sonoff/xsns_34_hx711.ino
new file mode 100644
index 000000000..91d987ba5
--- /dev/null
+++ b/sonoff/xsns_34_hx711.ino
@@ -0,0 +1,390 @@
+/*
+ xsns_34_hx711.ino - HX711 load cell support for Sonoff-Tasmota
+
+ Copyright (C) 2018 Theo Arends
+
+ 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_HX711
+/*********************************************************************************************\
+ * HX711 - Load cell as used in a scale
+ *
+ * Source: Sparkfun and https://github.com/bogde/HX711
+ *
+ * To reset the scale:
+ * - Execute command Sensor34 1
+ *
+ * To calibrate the scale perform the following tasks:
+ * - Set reference weight once using command Sensor34 3
+ * - Remove any weight from the scale
+ * - Execute command Sensor34 2 and follow messages shown
+\*********************************************************************************************/
+
+#define XSNS_34 34
+
+#ifndef HX_MAX_WEIGHT
+#define HX_MAX_WEIGHT 20000 // Default max weight in gram
+#endif
+#ifndef HX_REFERENCE
+#define HX_REFERENCE 250 // Default reference weight for calibration in gram
+#endif
+#ifndef HX_SCALE
+#define HX_SCALE 120 // Default result of measured weight / reference weight when scale is 1
+#endif
+
+#define HX_TIMEOUT 120 // A reading at default 10Hz (pin RATE to Gnd on HX711) can take up to 100 milliseconds
+#define HX_SAMPLES 10 // Number of samples for average calculation
+#define HX_CAL_TIMEOUT 15 // Calibration step window in number of seconds
+
+#define HX_GAIN_128 1 // Channel A, gain factor 128
+#define HX_GAIN_32 2 // Channel B, gain factor 32
+#define HX_GAIN_64 3 // Channel A, gain factor 64
+
+enum HxCalibrationSteps { HX_CAL_END, HX_CAL_LIMBO, HX_CAL_FINISH, HX_CAL_FAIL, HX_CAL_DONE, HX_CAL_FIRST, HX_CAL_RESET, HX_CAL_START };
+
+const char kHxCalibrationStates[] PROGMEM = D_HX_CAL_FAIL "|" D_HX_CAL_DONE "|" D_HX_CAL_REFERENCE "|" D_HX_CAL_REMOVE;
+
+long hx_weight = 0;
+long hx_sum_weight = 0;
+long hx_offset = 0;
+long hx_scale = 1;
+uint8_t hx_type = 1;
+uint8_t hx_sample_count = 0;
+uint8_t hx_tare_flg = 0;
+uint8_t hx_calibrate_step = HX_CAL_END;
+uint8_t hx_calibrate_timer = 0;
+uint8_t hx_calibrate_msg = 0;
+uint8_t hx_pin_sck;
+uint8_t hx_pin_dout;
+
+/*********************************************************************************************/
+
+bool HxIsReady(uint16_t timeout)
+{
+ // A reading can take up to 100 mS or 600mS after power on
+ uint32_t start = millis();
+ while ((digitalRead(hx_pin_dout) == HIGH) && (millis() - start < timeout)) { yield(); }
+ return (digitalRead(hx_pin_dout) == LOW);
+}
+
+long HxRead()
+{
+ if (!HxIsReady(HX_TIMEOUT)) { return -1; }
+
+ uint8_t data[3] = { 0 };
+ uint8_t filler = 0x00;
+
+ // pulse the clock pin 24 times to read the data
+ data[2] = shiftIn(hx_pin_dout, hx_pin_sck, MSBFIRST);
+ data[1] = shiftIn(hx_pin_dout, hx_pin_sck, MSBFIRST);
+ data[0] = shiftIn(hx_pin_dout, hx_pin_sck, MSBFIRST);
+
+ // set the channel and the gain factor for the next reading using the clock pin
+ for (unsigned int i = 0; i < HX_GAIN_128; i++) {
+ digitalWrite(hx_pin_sck, HIGH);
+ digitalWrite(hx_pin_sck, LOW);
+ }
+
+ // Replicate the most significant bit to pad out a 32-bit signed integer
+ if (data[2] & 0x80) { filler = 0xFF; }
+
+ // Construct a 32-bit signed integer
+ unsigned long value = ( static_cast(filler) << 24
+ | static_cast(data[2]) << 16
+ | static_cast(data[1]) << 8
+ | static_cast(data[0]) );
+
+ return static_cast(value);
+}
+
+/*********************************************************************************************/
+
+void HxReset()
+{
+ hx_tare_flg = 1;
+ hx_sum_weight = 0;
+ hx_sample_count = 0;
+}
+
+void HxCalibrationStateTextJson(uint8_t msg_id)
+{
+ char cal_text[30];
+
+ hx_calibrate_msg = msg_id;
+ snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_34, GetTextIndexed(cal_text, sizeof(cal_text), hx_calibrate_msg, kHxCalibrationStates));
+
+ if (msg_id < 3) { MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR("Sensor34")); }
+}
+
+/*********************************************************************************************\
+ * Supported commands for Sensor34:
+ *
+ * Sensor34 1 - Reset display to 0
+ * Sensor34 2 - Start calibration
+ * Sensor34 2 - Set reference weight and start calibration
+ * Sensor34 3 - Show reference weight in gram
+ * Sensor34 3 - Set reference weight
+ * Sensor34 4 - Show calibrated scale value
+ * Sensor34 4 - Set calibrated scale value
+ * Sensor34 5 - Show max weigth in gram
+ * Sensor34 5 - Set max weight
+ * Sensor34 6 - Show item weigth in decigram
+ * Sensor34 6 - Set item weight
+\*********************************************************************************************/
+
+bool HxCommand()
+{
+ bool serviced = true;
+ bool show_parms = false;
+ char sub_string[XdrvMailbox.data_len +1];
+
+ for (byte ca = 0; ca < XdrvMailbox.data_len; ca++) {
+ if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; }
+ }
+
+ switch (XdrvMailbox.payload) {
+ case 1: // Reset scale
+ HxReset();
+ snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_34, "Reset");
+ break;
+ case 2: // Calibrate
+ if (strstr(XdrvMailbox.data, ",")) {
+ Settings.weight_reference = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), NULL, 10);
+ }
+ hx_scale = 1;
+ HxReset();
+ hx_calibrate_step = HX_CAL_START;
+ hx_calibrate_timer = 1;
+ HxCalibrationStateTextJson(3);
+ break;
+ case 3: // WeightSet to user reference
+ if (strstr(XdrvMailbox.data, ",")) {
+ Settings.weight_reference = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), NULL, 10);
+ }
+ show_parms = true;
+ break;
+ case 4: // WeightCal to user calculated value
+ if (strstr(XdrvMailbox.data, ",")) {
+ Settings.weight_calibration = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), NULL, 10);
+ hx_scale = Settings.weight_calibration;
+ }
+ show_parms = true;
+ break;
+ case 5: // WeightMax
+ if (strstr(XdrvMailbox.data, ",")) {
+ Settings.weight_max = strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), NULL, 10) / 1000;
+ }
+ show_parms = true;
+ break;
+ case 6: // WeightItem
+ if (strstr(XdrvMailbox.data, ",")) {
+ Settings.weight_item = (uint16_t)(CharToDouble(subStr(sub_string, XdrvMailbox.data, ",", 2)) * 10);
+ }
+ show_parms = true;
+ break;
+ default:
+ serviced = false;
+ }
+
+ if (show_parms) {
+ char item[10];
+ dtostrfd((float)Settings.weight_item / 10, 1, item);
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Sensor34\":{\"WeightSet\":%d,\"WeightCal\":%d,\"WeightMax\":%d,\"WeightItem\":%s}}"),
+ Settings.weight_reference, Settings.weight_calibration, Settings.weight_max * 1000, item);
+ }
+
+ return serviced;
+}
+
+/*********************************************************************************************/
+
+void HxInit()
+{
+ hx_type = 0;
+ if ((pin[GPIO_HX711_DAT] < 99) && (pin[GPIO_HX711_SCK] < 99)) {
+ hx_pin_sck = pin[GPIO_HX711_SCK];
+ hx_pin_dout = pin[GPIO_HX711_DAT];
+
+ pinMode(hx_pin_sck, OUTPUT);
+ pinMode(hx_pin_dout, INPUT);
+
+ digitalWrite(hx_pin_sck, LOW);
+
+ if (HxIsReady(8 * HX_TIMEOUT)) { // Can take 600 milliseconds after power on
+ if (!Settings.weight_max) { Settings.weight_max = HX_MAX_WEIGHT / 1000; }
+ if (!Settings.weight_calibration) { Settings.weight_calibration = HX_SCALE; }
+ if (!Settings.weight_reference) { Settings.weight_reference = HX_REFERENCE; }
+ hx_scale = Settings.weight_calibration;
+ HxRead();
+ HxReset();
+
+ hx_type = 1;
+ }
+ }
+}
+
+void HxEvery100mSecond()
+{
+ hx_sum_weight += HxRead();
+
+ hx_sample_count++;
+ if (HX_SAMPLES == hx_sample_count) {
+ long average = hx_sum_weight / hx_sample_count; // grams
+ long value = average - hx_offset; // grams
+ hx_weight = value / hx_scale; // grams
+ if (hx_weight < 0) { hx_weight = 0; }
+
+ if (hx_tare_flg) {
+ hx_tare_flg = 0;
+ hx_offset = average; // grams
+ }
+
+ if (hx_calibrate_step) {
+ hx_calibrate_timer--;
+
+ if (HX_CAL_START == hx_calibrate_step) { // Skip reset just initiated
+ hx_calibrate_step--;
+ hx_calibrate_timer = HX_CAL_TIMEOUT * (10 / HX_SAMPLES);
+ }
+ else if (HX_CAL_RESET == hx_calibrate_step) { // Wait for stable reset
+ if (hx_calibrate_timer) {
+ if (hx_weight < Settings.weight_reference) {
+ hx_calibrate_step--;
+ hx_calibrate_timer = HX_CAL_TIMEOUT * (10 / HX_SAMPLES);
+ HxCalibrationStateTextJson(2);
+ }
+ } else {
+ hx_calibrate_step = HX_CAL_FAIL;
+ }
+ }
+ else if (HX_CAL_FIRST == hx_calibrate_step) { // Wait for first reference weight
+ if (hx_calibrate_timer) {
+ if (hx_weight > Settings.weight_reference) {
+ hx_calibrate_step--;
+ }
+ } else {
+ hx_calibrate_step = HX_CAL_FAIL;
+ }
+ }
+ else if (HX_CAL_DONE == hx_calibrate_step) { // Second stable reference weight
+ if (hx_weight > Settings.weight_reference) {
+ hx_calibrate_step = HX_CAL_FINISH; // Calibration done
+ Settings.weight_calibration = hx_weight / Settings.weight_reference;
+ hx_weight = 0; // Reset calibration value
+ HxCalibrationStateTextJson(1);
+ } else {
+ hx_calibrate_step = HX_CAL_FAIL;
+ }
+ }
+
+ if (HX_CAL_FAIL == hx_calibrate_step) { // Calibration failed
+ hx_calibrate_step--;
+ hx_tare_flg = 1; // Perform a reset using old scale
+ HxCalibrationStateTextJson(0);
+ }
+ if (HX_CAL_FINISH == hx_calibrate_step) { // Calibration finished
+ hx_calibrate_step--;
+ hx_calibrate_timer = 3 * (10 / HX_SAMPLES);
+ hx_scale = Settings.weight_calibration;
+ }
+
+ if (!hx_calibrate_timer) {
+ hx_calibrate_step = HX_CAL_END; // End of calibration
+ }
+ }
+
+ hx_sum_weight = 0;
+ hx_sample_count = 0;
+ }
+}
+
+#ifdef USE_WEBSERVER
+const char HTTP_HX711_WEIGHT[] PROGMEM = "%s"
+ "{s}HX711 " D_WEIGHT "{m}%s " D_UNIT_KILOGRAM "{e}"; // {s} = , {m} = | , {e} = |
+const char HTTP_HX711_COUNT[] PROGMEM = "%s"
+ "{s}HX711 " D_COUNT "{m}%d{e}";
+const char HTTP_HX711_CAL[] PROGMEM = "%s"
+ "{s}HX711 %s{m}{e}";
+#endif // USE_WEBSERVER
+
+void HxShow(boolean json)
+{
+ char weight_chr[10];
+ char scount[30] = { 0 };
+
+ uint16_t count = 0;
+ float weight = 0;
+ if (hx_calibrate_step < HX_CAL_FAIL) {
+ if (hx_weight && Settings.weight_item) {
+ count = (hx_weight * 10) / Settings.weight_item;
+ if (count > 1) {
+ snprintf_P(scount, sizeof(scount), PSTR(",\"" D_JSON_COUNT "\":%d"), count);
+ }
+ }
+ weight = (float)hx_weight / 1000; // kilograms
+ }
+ dtostrfd(weight, Settings.flag2.weight_resolution, weight_chr);
+
+ if (json) {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"HX711\":{\"" D_JSON_WEIGHT "\":%s%s}"), mqtt_data, weight_chr, scount);
+#ifdef USE_WEBSERVER
+ } else {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_HX711_WEIGHT, mqtt_data, weight_chr);
+ if (count > 1) {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_HX711_COUNT, mqtt_data, count);
+ }
+ if (hx_calibrate_step) {
+ char cal_text[30];
+ snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_HX711_CAL, mqtt_data, GetTextIndexed(cal_text, sizeof(cal_text), hx_calibrate_msg, kHxCalibrationStates));
+ }
+#endif // USE_WEBSERVER
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+boolean Xsns34(byte function)
+{
+ boolean result = false;
+
+ if (hx_type) {
+ switch (function) {
+ case FUNC_INIT:
+ HxInit();
+ break;
+ case FUNC_EVERY_100_MSECOND:
+ HxEvery100mSecond();
+ break;
+ case FUNC_COMMAND:
+ if (XSNS_34 == XdrvMailbox.index) {
+ result = HxCommand();
+ }
+ break;
+ case FUNC_JSON_APPEND:
+ HxShow(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_APPEND:
+ HxShow(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_HX711
\ No newline at end of file
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 99c73af69..4fe1c285b 100644
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -127,7 +127,7 @@ a_features = [[
],[
"USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050",
"USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766",
- "USE_MCP39F501","USE_PZEM2","","",
+ "USE_MCP39F501","USE_PZEM2","USE_DS3231","USE_HX711",
"","","","",
"","","","",
"","","","",