2018-10-11 16:33:07 +01:00
|
|
|
/*
|
2019-10-27 10:13:24 +00:00
|
|
|
xsns_34_hx711.ino - HX711 load cell support for Tasmota
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2021-01-01 12:44:04 +00:00
|
|
|
Copyright (C) 2021 Theo Arends
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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:
|
2024-09-12 11:14:32 +01:00
|
|
|
* - (Optional) Set reference weight once using command Sensor34 3 <reference weight in gram>
|
2018-10-11 16:33:07 +01:00
|
|
|
* - Remove any weight from the scale
|
2024-09-12 11:14:32 +01:00
|
|
|
* - Execute command Sensor34 2 <reference weight in gram> and follow messages shown
|
|
|
|
* -------------------------------------------------------------------------------------------
|
|
|
|
* I2C M5Unit (Mini)Scales(HX711 STM32) supported
|
|
|
|
*
|
|
|
|
* I2C Address: 0x26
|
2018-10-11 16:33:07 +01:00
|
|
|
\*********************************************************************************************/
|
|
|
|
|
2019-09-22 13:13:06 +01:00
|
|
|
#define XSNS_34 34
|
2024-09-12 11:14:32 +01:00
|
|
|
#define XI2C_89 89 // See I2CDEVICES.md
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
#ifndef HX_MAX_WEIGHT
|
2019-09-22 13:13:06 +01:00
|
|
|
#define HX_MAX_WEIGHT 20000 // Default max weight in gram
|
2018-10-11 16:33:07 +01:00
|
|
|
#endif
|
|
|
|
#ifndef HX_REFERENCE
|
2019-09-22 13:13:06 +01:00
|
|
|
#define HX_REFERENCE 250 // Default reference weight for calibration in gram
|
2018-10-11 16:33:07 +01:00
|
|
|
#endif
|
|
|
|
#ifndef HX_SCALE
|
2019-09-22 13:13:06 +01:00
|
|
|
#define HX_SCALE 120 // Default result of measured weight / reference weight when scale is 1
|
2018-10-11 16:33:07 +01:00
|
|
|
#endif
|
2023-05-10 08:38:27 +01:00
|
|
|
#ifndef HX711_CAL_PRECISION
|
2024-09-10 14:59:25 +01:00
|
|
|
#define HX711_CAL_PRECISION 1 // When calibration is to course, raise this value to max 20 (otherwise uint32_t overflow)
|
2023-05-10 08:38:27 +01:00
|
|
|
#endif
|
|
|
|
|
2019-09-22 13:13:06 +01:00
|
|
|
#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
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2019-09-22 13:13:06 +01:00
|
|
|
#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
|
2018-10-21 15:30:05 +01:00
|
|
|
|
2019-12-10 09:55:46 +00:00
|
|
|
#define D_JSON_WEIGHT_RAW "WeightRaw"
|
2022-04-09 17:24:37 +01:00
|
|
|
#define D_JSON_WEIGHT_RAW_ABS "AbsRaw"
|
2022-04-07 14:06:21 +01:00
|
|
|
#define D_JSON_WEIGHT_REF "Ref"
|
|
|
|
#define D_JSON_WEIGHT_CAL "Cal"
|
2024-09-08 16:32:35 +01:00
|
|
|
#define D_JSON_WEIGHT_PREC "Prec"
|
2022-04-07 14:06:21 +01:00
|
|
|
#define D_JSON_WEIGHT_MAX "Max"
|
|
|
|
#define D_JSON_WEIGHT_ITEM "Item"
|
|
|
|
#define D_JSON_WEIGHT_CHANGE "Change"
|
|
|
|
#define D_JSON_WEIGHT_DELTA "Delta"
|
2022-04-09 17:24:37 +01:00
|
|
|
#define D_JSON_WEIGHT_TARE "Tare"
|
2022-04-07 14:06:21 +01:00
|
|
|
#define D_JSON_WEIGHT_ABSC_A "AbsConvA"
|
|
|
|
#define D_JSON_WEIGHT_ABSC_B "AbsConvB"
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
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 };
|
2024-09-10 14:59:25 +01:00
|
|
|
enum HxCalibrationMsgs { HX_MSG_CAL_FAIL, HX_MSG_CAL_DONE, HX_MSG_CAL_REFERENCE, HX_MSG_CAL_REMOVE };
|
2018-10-11 16:33:07 +01:00
|
|
|
const char kHxCalibrationStates[] PROGMEM = D_HX_CAL_FAIL "|" D_HX_CAL_DONE "|" D_HX_CAL_REFERENCE "|" D_HX_CAL_REMOVE;
|
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
typedef struct Hx_t {
|
2022-04-06 14:09:35 +01:00
|
|
|
long reads[HX_SAMPLES];
|
2024-09-10 14:59:25 +01:00
|
|
|
long raw_empty;
|
2022-04-09 17:24:37 +01:00
|
|
|
long raw_absolute;
|
2024-09-10 14:59:25 +01:00
|
|
|
long raw;
|
|
|
|
long weight;
|
|
|
|
long last_weight;
|
|
|
|
long offset;
|
|
|
|
long scale;
|
|
|
|
long weight_diff;
|
|
|
|
uint16_t weight_delta;
|
|
|
|
uint8_t sample_count;
|
|
|
|
uint8_t calibrate_step;
|
|
|
|
uint8_t calibrate_timer;
|
|
|
|
uint8_t calibrate_msg;
|
2021-02-14 12:06:19 +00:00
|
|
|
int8_t pin_sck;
|
|
|
|
int8_t pin_dout;
|
2024-09-10 14:59:25 +01:00
|
|
|
bool tare_flg;
|
|
|
|
bool weight_changed;
|
|
|
|
} Hx_t;
|
|
|
|
Hx_t* Hx = nullptr;
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
/*********************************************************************************************/
|
|
|
|
|
2024-09-12 11:14:32 +01:00
|
|
|
#if defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
// M5Unit scales (STM32) need at least 800mS delay before ready after power on
|
|
|
|
// hence HxInit() is called 2 seconds after power on using FUNC_EVERY_SECOND
|
|
|
|
|
|
|
|
#ifndef HX_SCALES_ADDR
|
|
|
|
#define HX_SCALES_ADDR 0x26 // M5Unit (Mini)Scales(HX711 STM32) default I2C address
|
|
|
|
#endif
|
|
|
|
#ifndef HX_SCALES_RAW_ADC
|
|
|
|
#define HX_SCALES_RAW_ADC 0x00 // M5Unit MiniScales raw ADC register (U177)
|
|
|
|
//#define HX_SCALES_RAW_ADC 0x10 // M5Unit Scales raw ADC register (U108)
|
|
|
|
#endif
|
|
|
|
#define HX_SCALES_I2C_ADDR 0xFF // M5Unit (Mini)Scales get I2C address register
|
|
|
|
|
|
|
|
bool HxM5Found(void) {
|
|
|
|
uint8_t data = 0;
|
|
|
|
if (!I2cReadBuffer(HX_SCALES_ADDR, HX_SCALES_I2C_ADDR, &data, 1, Hx->pin_dout)) {
|
|
|
|
return (HX_SCALES_ADDR == data); // Verify I2C address with stored register
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
long HxM5ReadRaw(void) {
|
|
|
|
long rawADC = -1;
|
|
|
|
uint8_t data[4] = { 0 };
|
|
|
|
if (!I2cReadBuffer(HX_SCALES_ADDR, HX_SCALES_RAW_ADC, data, 4, Hx->pin_dout)) {
|
|
|
|
#if (HX_SCALES_RAW_ADC == 0x00) // M5Unit MiniScales (U177)
|
|
|
|
long rawADC1 = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
|
|
|
#else // M5Unit Scales (U108)
|
|
|
|
long rawADC1 = data[0];
|
|
|
|
rawADC1 = (rawADC1 << 8) | data[1];
|
|
|
|
rawADC1 = (rawADC1 << 8) | data[2];
|
|
|
|
rawADC1 = (rawADC1 << 8) | data[3];
|
|
|
|
#endif // M5Unit Scales (U108)
|
|
|
|
rawADC = 0x01FFFFFF - rawADC1; // Additional weight on miniscale decreases ADC value
|
|
|
|
}
|
|
|
|
return rawADC;
|
|
|
|
}
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
|
|
|
|
|
|
|
/*********************************************************************************************/
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
bool HxIsReady(uint16_t timeout) {
|
2024-09-12 11:14:32 +01:00
|
|
|
|
|
|
|
#if defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
if (Hx->pin_dout == Hx->pin_sck) {
|
|
|
|
return HxM5Found();
|
|
|
|
}
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
|
|
|
|
2018-10-11 16:33:07 +01:00
|
|
|
// A reading can take up to 100 mS or 600mS after power on
|
|
|
|
uint32_t start = millis();
|
2024-09-10 14:59:25 +01:00
|
|
|
while ((digitalRead(Hx->pin_dout) == HIGH) && (millis() - start < timeout)) {
|
2022-04-03 16:51:03 +01:00
|
|
|
yield();
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
return (digitalRead(Hx->pin_dout) == LOW);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
long HxRead(void) {
|
2024-09-12 11:14:32 +01:00
|
|
|
|
|
|
|
#if defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
if (Hx->pin_dout == Hx->pin_sck) {
|
|
|
|
return HxM5ReadRaw();
|
|
|
|
}
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
|
|
|
|
2018-10-11 16:33:07 +01:00
|
|
|
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
|
2024-09-10 14:59:25 +01:00
|
|
|
data[2] = TasShiftIn(Hx->pin_dout, Hx->pin_sck, MSBFIRST);
|
|
|
|
data[1] = TasShiftIn(Hx->pin_dout, Hx->pin_sck, MSBFIRST);
|
|
|
|
data[0] = TasShiftIn(Hx->pin_dout, Hx->pin_sck, MSBFIRST);
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
// 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++) {
|
2024-09-10 14:59:25 +01:00
|
|
|
digitalWrite(Hx->pin_sck, HIGH);
|
2022-04-03 16:51:03 +01:00
|
|
|
#ifdef ESP32
|
2022-04-03 17:20:07 +01:00
|
|
|
delayMicroseconds(1);
|
2022-04-03 16:51:03 +01:00
|
|
|
#endif
|
2024-09-10 14:59:25 +01:00
|
|
|
digitalWrite(Hx->pin_sck, LOW);
|
2022-04-03 17:20:07 +01:00
|
|
|
#ifdef ESP32
|
|
|
|
delayMicroseconds(1);
|
|
|
|
#endif
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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<unsigned long>(filler) << 24
|
|
|
|
| static_cast<unsigned long>(data[2]) << 16
|
|
|
|
| static_cast<unsigned long>(data[1]) << 8
|
|
|
|
| static_cast<unsigned long>(data[0]) );
|
|
|
|
|
|
|
|
return static_cast<long>(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************/
|
|
|
|
|
2022-04-09 17:24:37 +01:00
|
|
|
void HxTareInit(void) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->offset = (Settings->weight_user_tare != 0) ? Settings->weight_user_tare * Hx->scale : Settings->weight_offset;
|
|
|
|
if (0 == Hx->offset) {
|
|
|
|
Hx->tare_flg = true;
|
2022-04-09 17:24:37 +01:00
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HxCalibrationStateTextJson(uint8_t msg_id) {
|
2018-10-11 16:33:07 +01:00
|
|
|
char cal_text[30];
|
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->calibrate_msg = msg_id;
|
|
|
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_34, GetTextIndexed(cal_text, sizeof(cal_text), Hx->calibrate_msg, kHxCalibrationStates));
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if (msg_id < HX_MSG_CAL_REMOVE) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR("Sensor34")); }
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void SetWeightDelta(void) {
|
2021-06-11 17:14:12 +01:00
|
|
|
if (Settings->weight_change == 0) {
|
2024-09-10 14:59:25 +01:00
|
|
|
// backwards compatible: restore old default value of 4 grams
|
|
|
|
Hx->weight_delta = 4;
|
2019-12-11 21:03:13 +00:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (Settings->weight_change > 100) {
|
|
|
|
// map upper values 101-255 to
|
|
|
|
Hx->weight_delta = (Settings->weight_change - 100) * 10 + 100;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// map 1..100 to 0..99 grams
|
|
|
|
Hx->weight_delta = Settings->weight_change - 1;
|
2019-12-11 21:03:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-11 16:33:07 +01:00
|
|
|
/*********************************************************************************************\
|
|
|
|
* Supported commands for Sensor34:
|
|
|
|
*
|
2022-04-09 17:24:37 +01:00
|
|
|
* Sensor34 - Show current settings
|
2018-10-11 16:33:07 +01:00
|
|
|
* Sensor34 1 - Reset display to 0
|
|
|
|
* Sensor34 2 - Start calibration
|
|
|
|
* Sensor34 2 <weight in gram> - Set reference weight and start calibration
|
2024-09-08 16:32:35 +01:00
|
|
|
* Sensor34 2 <weight in gram> <precision> - Set reference weight with larger precision (1..10) and start calibration
|
2018-10-11 16:33:07 +01:00
|
|
|
* Sensor34 3 <weight in gram> - Set reference weight
|
|
|
|
* Sensor34 4 <scale value> - Set calibrated scale value
|
|
|
|
* Sensor34 5 <weight in gram> - Set max weight
|
|
|
|
* Sensor34 6 <weight in decigram> - Set item weight
|
2022-04-09 17:24:37 +01:00
|
|
|
* Sensor34 7 - Save current weight to be used as start weight on restart (removed v11.0.0.7)
|
2019-09-22 11:53:15 +01:00
|
|
|
* Sensor34 8 0 - Disable JSON weight change message
|
|
|
|
* Sensor34 8 1 - Enable JSON weight change message
|
2019-12-11 21:03:13 +00:00
|
|
|
* Sensor34 9 <weight code> - Set minimum delta to trigger JSON message
|
2022-04-09 17:24:37 +01:00
|
|
|
* Sensor34 10 0 - Disable fixed tare and enable auto tare
|
|
|
|
* Sensor34 10 1 - Set fixed tare offset using current calibrated raw weight value
|
|
|
|
* Sensor34 10 <weight in gram> - Set fixed tare offset
|
|
|
|
* Sensor34 11 0 - Disable absolute weight conversion
|
|
|
|
* Sensor34 11 <value A> - Set A = a * 10^9 for raw to absolute weight conversion: y=a*x+b
|
|
|
|
* Sensor34 12 <value B> - Set B = b * 10^6 for raw to absolute weight conversion: y=a*x+b
|
2018-10-11 16:33:07 +01:00
|
|
|
\*********************************************************************************************/
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
bool HxCommand(void) {
|
2018-10-11 16:33:07 +01:00
|
|
|
bool serviced = true;
|
2022-04-07 14:06:21 +01:00
|
|
|
bool show_parms = true;
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2019-06-30 15:44:36 +01:00
|
|
|
for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) {
|
2018-10-11 16:33:07 +01:00
|
|
|
if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; }
|
|
|
|
}
|
2024-09-08 16:32:35 +01:00
|
|
|
bool any_value = (ArgC() > 1);
|
2024-09-10 14:59:25 +01:00
|
|
|
long value;
|
|
|
|
char argument[32];
|
|
|
|
if (any_value) {
|
|
|
|
value = strtol(ArgV(argument, 2), nullptr, 10);
|
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
switch (XdrvMailbox.payload) {
|
|
|
|
case 1: // Reset scale
|
2022-04-09 17:24:37 +01:00
|
|
|
if (0 == Settings->weight_user_tare) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->tare_flg = true;
|
2022-04-09 17:24:37 +01:00
|
|
|
Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_34, "Reset");
|
|
|
|
}
|
2022-04-07 14:06:21 +01:00
|
|
|
show_parms = false;
|
2018-10-11 16:33:07 +01:00
|
|
|
break;
|
2024-09-10 14:59:25 +01:00
|
|
|
case 2: // Calibrate in gram and precision 1 to 10
|
2024-09-08 16:32:35 +01:00
|
|
|
if (any_value) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Settings->weight_reference = (value && (value < (Settings->weight_max * 1000))) ? value : HX_REFERENCE;
|
2024-09-08 16:32:35 +01:00
|
|
|
if (ArgC() > 2) {
|
|
|
|
value = strtol(ArgV(argument, 3), nullptr, 10);
|
2024-09-10 14:59:25 +01:00
|
|
|
Settings->weight_precision = (value && (value <= 20)) ? value : HX711_CAL_PRECISION;
|
2024-09-08 16:32:35 +01:00
|
|
|
}
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->scale = 1; // Uncalibrated
|
|
|
|
Hx->sample_count = 0;
|
|
|
|
Hx->offset = 0; // Disable tare while calibrating
|
|
|
|
Hx->calibrate_step = HX_CAL_START;
|
|
|
|
Hx->calibrate_timer = 1;
|
|
|
|
// HxCalibrationStateTextJson(HX_MSG_CAL_REMOVE);
|
|
|
|
HxCalibrationStateTextJson(HX_MSG_CAL_REFERENCE);
|
2022-04-07 14:06:21 +01:00
|
|
|
show_parms = false;
|
2018-10-11 16:33:07 +01:00
|
|
|
break;
|
2024-09-10 14:59:25 +01:00
|
|
|
case 3: // WeightRef to user reference in gram
|
|
|
|
if (any_value) {
|
|
|
|
Settings->weight_reference = (value && (value < (Settings->weight_max * 1000))) ? value : HX_REFERENCE;
|
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
break;
|
|
|
|
case 4: // WeightCal to user calculated value
|
2022-04-07 14:06:21 +01:00
|
|
|
if (any_value) {
|
2024-09-08 16:32:35 +01:00
|
|
|
Settings->weight_calibration = value; // Allow zero for re-init
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->scale = (value) ? Settings->weight_calibration : 1; // Fix divide by zero
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
break;
|
2024-09-10 14:59:25 +01:00
|
|
|
case 5: // WeightMax in kg
|
|
|
|
if (any_value) {
|
|
|
|
Settings->weight_max = (value) ? value : HX_MAX_WEIGHT / 1000;
|
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
break;
|
2024-09-10 14:59:25 +01:00
|
|
|
case 6: // WeightItem in gram
|
|
|
|
if (any_value) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->weight_item = (unsigned long)(CharToFloat(ArgV(argument, 2)) * 10);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
break;
|
2022-04-09 17:24:37 +01:00
|
|
|
// case 7: // WeightSave
|
2024-09-10 14:59:25 +01:00
|
|
|
// Settings->energy_frequency_calibration = Hx->weight;
|
2022-04-09 17:24:37 +01:00
|
|
|
// Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_34, PSTR(D_JSON_DONE));
|
|
|
|
// show_parms = false;
|
|
|
|
// break;
|
2019-09-22 11:53:15 +01:00
|
|
|
case 8: // Json on weight change
|
2024-09-10 14:59:25 +01:00
|
|
|
if (any_value) {
|
|
|
|
Settings->SensorBits1.hx711_json_weight_change = value &1;
|
|
|
|
}
|
2019-09-22 11:53:15 +01:00
|
|
|
break;
|
2019-12-11 21:03:13 +00:00
|
|
|
case 9: // WeightDelta
|
2022-04-07 14:06:21 +01:00
|
|
|
if (any_value) {
|
|
|
|
Settings->weight_change = value;
|
2022-04-06 14:09:35 +01:00
|
|
|
SetWeightDelta();
|
2019-12-11 21:03:13 +00:00
|
|
|
}
|
|
|
|
break;
|
2022-04-09 17:24:37 +01:00
|
|
|
case 10: // Fixed (user) tare
|
|
|
|
if (any_value) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Settings->weight_user_tare = (1 == value) ? Hx->raw : value;
|
2022-04-09 17:24:37 +01:00
|
|
|
HxTareInit();
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->weight_diff = Hx->weight_delta +1; // Force display of current weight
|
2022-04-09 17:24:37 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11: // AbsoluteConversion, A
|
2024-09-10 14:59:25 +01:00
|
|
|
if (any_value) {
|
|
|
|
Settings->weight_absconv_a = value;
|
|
|
|
}
|
2022-04-07 14:06:21 +01:00
|
|
|
break;
|
2022-04-09 17:24:37 +01:00
|
|
|
case 12: // AbsoluteConversion, B
|
2024-09-10 14:59:25 +01:00
|
|
|
if (any_value) {
|
|
|
|
Settings->weight_absconv_b = value;
|
|
|
|
}
|
2022-04-07 14:06:21 +01:00
|
|
|
break;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (show_parms) {
|
2022-04-07 14:52:55 +01:00
|
|
|
char item[33];
|
|
|
|
dtostrfd((float)Settings->weight_item / 10, 1, item);
|
2024-09-08 16:32:35 +01:00
|
|
|
Response_P(PSTR("{\"Sensor34\":{\""
|
2024-09-10 14:59:25 +01:00
|
|
|
D_JSON_WEIGHT_REF "\":%d,\"" D_JSON_WEIGHT_CAL "\":%d,\"" D_JSON_WEIGHT_PREC "\":%d,\""
|
|
|
|
D_JSON_WEIGHT_MAX "\":%d,\""
|
|
|
|
D_JSON_WEIGHT_ITEM "\":%s,\"" D_JSON_WEIGHT_CHANGE "\":\"%s\",\"" D_JSON_WEIGHT_DELTA "\":%d,\""
|
|
|
|
D_JSON_WEIGHT_TARE "\":%d,\"" D_JSON_WEIGHT_ABSC_A "\":%d,\"" D_JSON_WEIGHT_ABSC_B "\":%d}}"),
|
|
|
|
Settings->weight_reference, Settings->weight_calibration, Settings->weight_precision,
|
|
|
|
Settings->weight_max * 1000,
|
|
|
|
item, GetStateText(Settings->SensorBits1.hx711_json_weight_change), Settings->weight_change,
|
|
|
|
Settings->weight_user_tare, Settings->weight_absconv_a, Settings->weight_absconv_b);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return serviced;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************/
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
long HxWeight(void) {
|
2024-09-10 14:59:25 +01:00
|
|
|
return (Hx->calibrate_step < HX_CAL_FAIL) ? Hx->weight : 0;
|
2018-10-23 14:51:51 +01:00
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HxInit(void) {
|
2024-09-12 11:14:32 +01:00
|
|
|
uint32_t hx711_config = (PinUsed(GPIO_HX711_DAT) && PinUsed(GPIO_HX711_SCK)) ? 1 : 0;
|
|
|
|
|
|
|
|
#if defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
uint32_t bus;
|
|
|
|
if (!hx711_config && I2cEnabled(XI2C_89)) {
|
|
|
|
for (bus = 0; bus < 2; bus++) {
|
|
|
|
if (!I2cSetDevice(HX_SCALES_ADDR, bus)) { continue; }
|
|
|
|
I2cSetActiveFound(HX_SCALES_ADDR, "M5Unit Scales", bus);
|
|
|
|
hx711_config = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
|
|
|
|
|
|
|
if (hx711_config > 0) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx = (Hx_t*)calloc(sizeof(Hx_t), 1); // Need calloc to reset registers to 0/false
|
|
|
|
if (nullptr == Hx) { return; }
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
// Hx->calibrate_step = HX_CAL_END; // HX_CAL_END = 0
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-12 11:14:32 +01:00
|
|
|
#if defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
if (2 == hx711_config) {
|
|
|
|
Hx->pin_sck = bus; // If both are equal use M5Scale instead of HX711
|
|
|
|
Hx->pin_dout = bus;
|
|
|
|
} else {
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
|
|
|
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 defined(USE_I2C) && defined(USE_HX711_M5SCALES)
|
|
|
|
}
|
|
|
|
#endif // USE_I2C && USE_HX711_M5SCALES
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2019-12-11 21:03:13 +00:00
|
|
|
SetWeightDelta();
|
2019-12-31 13:23:34 +00:00
|
|
|
|
2024-09-12 11:14:32 +01:00
|
|
|
if (HxIsReady(8 * HX_TIMEOUT)) { // Could take 600 milliseconds after power on
|
2021-06-11 17:14:12 +01:00
|
|
|
if (!Settings->weight_max) { Settings->weight_max = HX_MAX_WEIGHT / 1000; }
|
2024-09-08 16:32:35 +01:00
|
|
|
if (!Settings->weight_precision) { Settings->weight_precision = HX711_CAL_PRECISION; }
|
|
|
|
if (!Settings->weight_calibration) { Settings->weight_calibration = HX_SCALE * Settings->weight_precision; }
|
2021-06-11 17:14:12 +01:00
|
|
|
if (!Settings->weight_reference) { Settings->weight_reference = HX_REFERENCE; }
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->scale = Settings->weight_calibration;
|
2022-04-09 17:24:37 +01:00
|
|
|
HxTareInit();
|
2018-10-11 16:33:07 +01:00
|
|
|
HxRead();
|
2024-09-10 14:59:25 +01:00
|
|
|
} else {
|
|
|
|
free(Hx);
|
|
|
|
Hx = nullptr;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HxEvery100mSecond(void) {
|
2019-12-10 09:55:46 +00:00
|
|
|
long raw = HxRead();
|
2022-04-03 16:51:03 +01:00
|
|
|
if (-1 == raw) { return; }
|
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->sample_count < HX_SAMPLES) { // Test for HxSaveBeforeRestart()
|
|
|
|
Hx->reads[Hx->sample_count] = raw;
|
2022-04-06 14:09:35 +01:00
|
|
|
}
|
2019-09-22 13:13:06 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->sample_count++;
|
|
|
|
if (HX_SAMPLES == Hx->sample_count) {
|
|
|
|
Hx->sample_count = 0;
|
2022-04-06 14:09:35 +01:00
|
|
|
// Sort HX_SAMPLES
|
|
|
|
for (uint32_t i = 0; i < HX_SAMPLES; i++) {
|
|
|
|
for (uint32_t j = i + 1; j < HX_SAMPLES; j++) {
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->reads[j] > Hx->reads[i]) {
|
|
|
|
std::swap(Hx->reads[i], Hx->reads[j]);
|
2022-04-06 14:09:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Drop two lows and two highs from average
|
|
|
|
long sum_raw = 0;
|
|
|
|
for (uint32_t i = 2; i < HX_SAMPLES -2; i++) {
|
2024-09-10 14:59:25 +01:00
|
|
|
sum_raw += Hx->reads[i];
|
2022-04-06 14:09:35 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->raw_absolute = (sum_raw / (HX_SAMPLES -4)) * Settings->weight_precision; // Uncalibrated value
|
|
|
|
Hx->raw = Hx->raw_absolute / Hx->scale; // grams
|
2022-04-06 14:09:35 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if ((0 == Settings->weight_user_tare) && Hx->tare_flg) { // Reset scale based on current load
|
|
|
|
Hx->tare_flg = false;
|
|
|
|
Settings->weight_offset = Hx->raw_absolute; // Save for restart use
|
|
|
|
Hx->offset = Hx->raw_absolute;
|
2022-04-06 14:09:35 +01:00
|
|
|
}
|
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
long value = Hx->raw_absolute - Hx->offset; // Uncalibrated value
|
|
|
|
Hx->weight = value / Hx->scale; // grams
|
|
|
|
if (Hx->weight < 0) { // We currently do not support negative weight
|
|
|
|
Hx->weight = 0;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->calibrate_step) {
|
|
|
|
Hx->calibrate_timer--;
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
// AddLog(LOG_LEVEL_DEBUG, PSTR("HX7: Step %d, weight %d, last %d, raw %d, empty %d"), Hx->calibrate_step, Hx->weight, Hx->last_weight, Hx->raw, Hx->raw_empty);
|
2022-04-09 17:24:37 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if (HX_CAL_START == Hx->calibrate_step) { // Skip reset just initiated
|
|
|
|
if (0 == Hx->offset) {
|
|
|
|
Hx->calibrate_step--; // HX_CAL_RESET
|
|
|
|
Hx->last_weight = Hx->weight; // Uncalibrated value
|
|
|
|
Hx->raw_empty = Hx->raw;
|
2022-04-09 17:24:37 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->calibrate_timer = HX_CAL_TIMEOUT * (10 / HX_SAMPLES);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (HX_CAL_RESET == Hx->calibrate_step) { // Wait for stable reset
|
|
|
|
if (Hx->calibrate_timer) {
|
|
|
|
if (Hx->weight < Hx->last_weight -100) { // Load decrease detected
|
|
|
|
Hx->last_weight = Hx->weight;
|
|
|
|
Hx->raw_empty = Hx->raw;
|
|
|
|
// HxCalibrationStateTextJson(HX_MSG_CAL_REFERENCE);
|
2022-04-09 17:24:37 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (Hx->weight > Hx->last_weight +100) { // Load increase detected
|
|
|
|
Hx->calibrate_step--; // HX_CAL_FIRST
|
|
|
|
Hx->calibrate_timer = HX_CAL_TIMEOUT * (10 / HX_SAMPLES);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
} else {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->calibrate_step = HX_CAL_FAIL;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (HX_CAL_FIRST == Hx->calibrate_step) { // Wait for first reference weight
|
|
|
|
if (Hx->calibrate_timer) {
|
|
|
|
if (Hx->weight > Hx->last_weight +100) {
|
|
|
|
Hx->calibrate_step--; // HX_CAL_DONE
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
} else {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->calibrate_step = HX_CAL_FAIL;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (HX_CAL_DONE == Hx->calibrate_step) { // Second stable reference weight
|
|
|
|
if (Hx->weight > Hx->last_weight +100) {
|
|
|
|
Hx->calibrate_step = HX_CAL_FINISH; // Calibration done
|
|
|
|
Settings->weight_offset = Hx->raw_empty;
|
|
|
|
Hx->offset = Hx->raw_empty;
|
|
|
|
Settings->weight_calibration = (Hx->weight - Hx->raw_empty) / Settings->weight_reference; // 1 gram
|
|
|
|
Hx->weight = 0; // Reset calibration value
|
|
|
|
HxCalibrationStateTextJson(HX_MSG_CAL_DONE);
|
2018-10-11 16:33:07 +01:00
|
|
|
} else {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->calibrate_step = HX_CAL_FAIL;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
if (HX_CAL_FAIL == Hx->calibrate_step) { // Calibration failed
|
|
|
|
Hx->calibrate_step--; // HX_CAL_FINISH
|
2022-04-09 17:24:37 +01:00
|
|
|
HxTareInit();
|
2024-09-10 14:59:25 +01:00
|
|
|
HxCalibrationStateTextJson(HX_MSG_CAL_FAIL);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
if (HX_CAL_FINISH == Hx->calibrate_step) { // Calibration finished
|
|
|
|
Hx->calibrate_step--; // HX_CAL_LIMBO
|
|
|
|
Hx->calibrate_timer = 3 * (10 / HX_SAMPLES);
|
|
|
|
Hx->scale = Settings->weight_calibration;
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Settings->weight_user_tare != 0) { // Re-enable fixed tare if needed
|
|
|
|
Settings->weight_user_tare = Hx->raw_empty / Hx->scale;
|
2022-04-09 17:24:37 +01:00
|
|
|
HxTareInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
if (!Hx->calibrate_timer) {
|
|
|
|
Hx->calibrate_step = HX_CAL_END; // End of calibration
|
|
|
|
Hx->weight_diff = Hx->weight_delta +2;
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
2019-05-19 16:49:00 +01:00
|
|
|
} else {
|
2021-06-11 17:14:12 +01:00
|
|
|
if (Settings->SensorBits1.hx711_json_weight_change) {
|
2024-09-10 14:59:25 +01:00
|
|
|
if (abs(Hx->weight - Hx->weight_diff) > Hx->weight_delta) { // Use weight_delta threshold to decrease "ghost" weights
|
|
|
|
Hx->weight_diff = Hx->weight;
|
|
|
|
Hx->weight_changed = true;
|
2019-09-22 11:53:15 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
else if (Hx->weight_changed && (abs(Hx->weight - Hx->weight_diff) < Hx->weight_delta)) {
|
2020-10-30 11:29:48 +00:00
|
|
|
ResponseClear();
|
2019-09-22 11:53:15 +01:00
|
|
|
ResponseAppendTime();
|
|
|
|
HxShow(true);
|
|
|
|
ResponseJsonEnd();
|
2019-11-10 16:40:37 +00:00
|
|
|
MqttPublishTeleSensor();
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->weight_changed = false;
|
2019-09-22 11:53:15 +01:00
|
|
|
}
|
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HxSaveBeforeRestart(void) {
|
2024-09-10 14:59:25 +01:00
|
|
|
Hx->sample_count = HX_SAMPLES +1; // Stop updating Hx->weight
|
2019-05-19 16:49:00 +01:00
|
|
|
}
|
|
|
|
|
2018-10-11 16:33:07 +01:00
|
|
|
#ifdef USE_WEBSERVER
|
2019-03-19 16:31:43 +00:00
|
|
|
const char HTTP_HX711_WEIGHT[] PROGMEM =
|
2018-10-11 16:33:07 +01:00
|
|
|
"{s}HX711 " D_WEIGHT "{m}%s " D_UNIT_KILOGRAM "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
2019-03-19 16:31:43 +00:00
|
|
|
const char HTTP_HX711_COUNT[] PROGMEM =
|
2018-10-11 16:33:07 +01:00
|
|
|
"{s}HX711 " D_COUNT "{m}%d{e}";
|
2019-03-19 16:31:43 +00:00
|
|
|
const char HTTP_HX711_CAL[] PROGMEM =
|
2018-10-11 16:33:07 +01:00
|
|
|
"{s}HX711 %s{m}{e}";
|
|
|
|
#endif // USE_WEBSERVER
|
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HxShow(bool json) {
|
2018-10-11 16:33:07 +01:00
|
|
|
char scount[30] = { 0 };
|
|
|
|
|
|
|
|
uint16_t count = 0;
|
|
|
|
float weight = 0;
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->calibrate_step < HX_CAL_FAIL) {
|
2022-04-07 14:06:21 +01:00
|
|
|
if ((Settings->weight_absconv_a != 0) && (Settings->weight_absconv_b != 0)) {
|
2024-09-10 14:59:25 +01:00
|
|
|
weight = (float)Settings->weight_absconv_a / 1e9 * Hx->raw_absolute + (float)Settings->weight_absconv_b / 1e6;
|
2022-04-09 17:24:37 +01:00
|
|
|
}
|
|
|
|
else {
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->weight && Settings->weight_item) {
|
|
|
|
count = (Hx->weight * 10) / Settings->weight_item;
|
2022-04-07 14:06:21 +01:00
|
|
|
if (count > 1) {
|
|
|
|
snprintf_P(scount, sizeof(scount), PSTR(",\"" D_JSON_COUNT "\":%d"), count);
|
|
|
|
}
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
weight = (float)Hx->weight / 1000; // kilograms
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
}
|
2018-12-21 15:17:06 +00:00
|
|
|
char weight_chr[33];
|
2021-06-11 17:14:12 +01:00
|
|
|
dtostrfd(weight, Settings->flag2.weight_resolution, weight_chr);
|
2018-10-11 16:33:07 +01:00
|
|
|
|
|
|
|
if (json) {
|
2022-04-09 17:24:37 +01:00
|
|
|
ResponseAppend_P(PSTR(",\"HX711\":{\"" D_JSON_WEIGHT "\":%s%s,\"" D_JSON_WEIGHT_RAW "\":%d,\"" D_JSON_WEIGHT_RAW_ABS "\":%d}"),
|
2024-09-10 14:59:25 +01:00
|
|
|
weight_chr, scount, Hx->raw, Hx->raw_absolute);
|
2018-10-11 16:33:07 +01:00
|
|
|
#ifdef USE_WEBSERVER
|
|
|
|
} else {
|
2019-03-19 16:31:43 +00:00
|
|
|
WSContentSend_PD(HTTP_HX711_WEIGHT, weight_chr);
|
2018-10-11 16:33:07 +01:00
|
|
|
if (count > 1) {
|
2019-03-19 16:31:43 +00:00
|
|
|
WSContentSend_PD(HTTP_HX711_COUNT, count);
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
if (Hx->calibrate_step) {
|
2018-10-11 16:33:07 +01:00
|
|
|
char cal_text[30];
|
2024-09-10 14:59:25 +01:00
|
|
|
WSContentSend_PD(HTTP_HX711_CAL, GetTextIndexed(cal_text, sizeof(cal_text), Hx->calibrate_msg, kHxCalibrationStates));
|
2018-10-11 16:33:07 +01:00
|
|
|
}
|
|
|
|
#endif // USE_WEBSERVER
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-21 15:30:05 +01:00
|
|
|
#ifdef USE_WEBSERVER
|
|
|
|
#ifdef USE_HX711_GUI
|
|
|
|
/*********************************************************************************************\
|
|
|
|
* Optional GUI
|
|
|
|
\*********************************************************************************************/
|
|
|
|
|
|
|
|
#define WEB_HANDLE_HX711 "s34"
|
|
|
|
|
|
|
|
const char HTTP_BTN_MENU_MAIN_HX711[] PROGMEM =
|
2019-03-19 17:02:38 +00:00
|
|
|
"<p><form action='" WEB_HANDLE_HX711 "' method='get'><button name='reset'>" D_RESET_HX711 "</button></form></p>";
|
2018-10-21 15:30:05 +01:00
|
|
|
|
|
|
|
const char HTTP_BTN_MENU_HX711[] PROGMEM =
|
2019-02-13 15:05:25 +00:00
|
|
|
"<p><form action='" WEB_HANDLE_HX711 "' method='get'><button>" D_CONFIGURE_HX711 "</button></form></p>";
|
2018-10-21 15:30:05 +01:00
|
|
|
|
|
|
|
const char HTTP_FORM_HX711[] PROGMEM =
|
|
|
|
"<fieldset><legend><b> " D_CALIBRATION " </b></legend>"
|
|
|
|
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
2019-05-31 17:24:56 +01:00
|
|
|
"<p><b>" D_REFERENCE_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br><input type='number' step='0.001' id='p1' placeholder='0' value='%s'></p>"
|
|
|
|
"<br><button name='calibrate' type='submit'>" D_CALIBRATE "</button>"
|
2018-10-21 15:30:05 +01:00
|
|
|
"</form>"
|
2019-05-31 17:24:56 +01:00
|
|
|
"</fieldset><br><br>"
|
2018-10-21 15:30:05 +01:00
|
|
|
|
|
|
|
"<fieldset><legend><b> " D_HX711_PARAMETERS " </b></legend>"
|
|
|
|
"<form method='post' action='" WEB_HANDLE_HX711 "'>"
|
2019-05-31 17:24:56 +01:00
|
|
|
"<p><b>" D_ITEM_WEIGHT "</b> (" D_UNIT_KILOGRAM ")<br><input type='number' max='6.5535' step='0.0001' id='p2' placeholder='0.0' value='%s'></p>";
|
2018-10-21 15:30:05 +01:00
|
|
|
|
2022-04-06 14:09:35 +01:00
|
|
|
void HandleHxAction(void) {
|
2019-01-10 11:57:42 +00:00
|
|
|
if (!HttpCheckPriviledgedAccess()) { return; }
|
|
|
|
|
2021-01-23 16:10:06 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_HX711));
|
2018-10-21 15:30:05 +01:00
|
|
|
|
2024-09-10 14:59:25 +01:00
|
|
|
char stemp1[32];
|
2021-05-03 16:37:17 +01:00
|
|
|
|
2020-04-15 08:58:38 +01:00
|
|
|
if (Webserver->hasArg("save")) {
|
2021-05-03 16:37:17 +01:00
|
|
|
WebGetArg("p2", stemp1, sizeof(stemp1));
|
2024-09-10 14:59:25 +01:00
|
|
|
unsigned long weight_item = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000);
|
|
|
|
snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 6,%d"), weight_item); // WeightItem
|
|
|
|
ExecuteWebCommand(stemp1);
|
2021-05-03 16:37:17 +01:00
|
|
|
|
2018-10-21 15:30:05 +01:00
|
|
|
HandleConfiguration();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 08:58:38 +01:00
|
|
|
if (Webserver->hasArg("reset")) {
|
2019-03-04 17:16:07 +00:00
|
|
|
snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 1")); // Reset
|
2021-05-03 16:37:17 +01:00
|
|
|
ExecuteWebCommand(stemp1);
|
2018-10-21 15:30:05 +01:00
|
|
|
|
|
|
|
HandleRoot(); // Return to main screen
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-15 08:58:38 +01:00
|
|
|
if (Webserver->hasArg("calibrate")) {
|
2019-03-04 17:16:07 +00:00
|
|
|
WebGetArg("p1", stemp1, sizeof(stemp1));
|
2024-09-10 14:59:25 +01:00
|
|
|
unsigned long weight_ref = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000);
|
|
|
|
snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 2,%d"), weight_ref); // Start calibration
|
|
|
|
ExecuteWebCommand(stemp1);
|
2018-10-21 15:30:05 +01:00
|
|
|
|
|
|
|
HandleRoot(); // Return to main screen
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-06 16:09:13 +00:00
|
|
|
WSContentStart_P(PSTR(D_CONFIGURE_HX711));
|
2019-03-04 17:16:07 +00:00
|
|
|
WSContentSendStyle();
|
2021-06-11 17:14:12 +01:00
|
|
|
dtostrfd((float)Settings->weight_reference / 1000, 3, stemp1);
|
2019-03-04 17:16:07 +00:00
|
|
|
char stemp2[20];
|
2021-06-11 17:14:12 +01:00
|
|
|
dtostrfd((float)Settings->weight_item / 10000, 4, stemp2);
|
2019-03-04 17:16:07 +00:00
|
|
|
WSContentSend_P(HTTP_FORM_HX711, stemp1, stemp2);
|
2019-03-10 14:36:34 +00:00
|
|
|
WSContentSend_P(HTTP_FORM_END);
|
2019-03-11 09:38:41 +00:00
|
|
|
WSContentSpaceButton(BUTTON_CONFIGURATION);
|
2019-03-16 15:23:41 +00:00
|
|
|
WSContentStop();
|
2018-10-21 15:30:05 +01:00
|
|
|
}
|
|
|
|
#endif // USE_HX711_GUI
|
|
|
|
#endif // USE_WEBSERVER
|
|
|
|
|
2018-10-11 16:33:07 +01:00
|
|
|
/*********************************************************************************************\
|
|
|
|
* Interface
|
|
|
|
\*********************************************************************************************/
|
|
|
|
|
2022-11-11 09:44:56 +00:00
|
|
|
bool Xsns34(uint32_t function) {
|
2019-01-28 13:08:33 +00:00
|
|
|
bool result = false;
|
2018-10-11 16:33:07 +01:00
|
|
|
|
2024-09-12 11:14:32 +01:00
|
|
|
if (FUNC_EVERY_SECOND == function) {
|
|
|
|
if (2 == TasmotaGlobal.uptime) { // Fix power on init
|
|
|
|
HxInit();
|
|
|
|
}
|
2024-09-10 14:59:25 +01:00
|
|
|
}
|
|
|
|
else if (Hx) {
|
2018-10-11 16:33:07 +01:00
|
|
|
switch (function) {
|
|
|
|
case FUNC_EVERY_100_MSECOND:
|
|
|
|
HxEvery100mSecond();
|
|
|
|
break;
|
2019-03-10 12:33:32 +00:00
|
|
|
case FUNC_COMMAND_SENSOR:
|
2018-10-11 16:33:07 +01:00
|
|
|
if (XSNS_34 == XdrvMailbox.index) {
|
|
|
|
result = HxCommand();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case FUNC_JSON_APPEND:
|
|
|
|
HxShow(1);
|
|
|
|
break;
|
2019-05-19 16:49:00 +01:00
|
|
|
case FUNC_SAVE_BEFORE_RESTART:
|
|
|
|
HxSaveBeforeRestart();
|
|
|
|
break;
|
2018-10-11 16:33:07 +01:00
|
|
|
#ifdef USE_WEBSERVER
|
2019-03-19 16:31:43 +00:00
|
|
|
case FUNC_WEB_SENSOR:
|
2018-10-11 16:33:07 +01:00
|
|
|
HxShow(0);
|
|
|
|
break;
|
2018-10-21 15:30:05 +01:00
|
|
|
#ifdef USE_HX711_GUI
|
|
|
|
case FUNC_WEB_ADD_MAIN_BUTTON:
|
2022-04-09 17:24:37 +01:00
|
|
|
if (0 == Settings->weight_user_tare) { // Allow reset scale when no user tare is defined
|
|
|
|
WSContentSend_P(HTTP_BTN_MENU_MAIN_HX711);
|
|
|
|
}
|
2018-10-21 15:30:05 +01:00
|
|
|
break;
|
|
|
|
case FUNC_WEB_ADD_BUTTON:
|
2019-03-10 14:36:34 +00:00
|
|
|
WSContentSend_P(HTTP_BTN_MENU_HX711);
|
2018-10-21 15:30:05 +01:00
|
|
|
break;
|
|
|
|
case FUNC_WEB_ADD_HANDLER:
|
2020-10-20 17:56:18 +01:00
|
|
|
WebServer_on(PSTR("/" WEB_HANDLE_HX711), HandleHxAction);
|
2018-10-21 15:30:05 +01:00
|
|
|
break;
|
|
|
|
#endif // USE_HX711_GUI
|
2018-10-11 16:33:07 +01:00
|
|
|
#endif // USE_WEBSERVER
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-12-10 09:55:46 +00:00
|
|
|
#endif // USE_HX711
|