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", "","","","", "","","","", "","","","",