From 14ac7a5ba46fa6b964a71b15a286dd5c9712155d Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Mon, 9 Dec 2019 21:26:01 +0100 Subject: [PATCH] make weighing more stable (hopefully) --- mini-beieli-node.ino | 95 +++++++++++++++++++++++++++++--------------- mini_beieli_node.h | 9 ++++- 2 files changed, 70 insertions(+), 34 deletions(-) diff --git a/mini-beieli-node.ino b/mini-beieli-node.ino index 11b1768..67248e1 100644 --- a/mini-beieli-node.ino +++ b/mini-beieli-node.ino @@ -302,7 +302,7 @@ bool setup_scales(void) // - With a gain factor of 32, channel B is selected // By omitting the gain factor parameter, the library // default "128" (Channel A) is used here. - LoadCell.begin(A1, A0); + LoadCell.begin(A1, A0, 32); if (!(LoadCell.wait_ready_timeout(2000))) { gCatena.SafePrintf("%010d - Scale not ready after Init.\n"); @@ -345,6 +345,13 @@ void setup_uplink(void) gCatena.SafePrintf("%010d - setup_uplink\n", millis()); } +#if defined(_mcci_arduino_version) && _mcci_arduino_version >= _mcci_arduino_version_calc(2,4,0,90) && \ + defined(CATENA_ARDUINO_PLATFORM_VERSION_CALC) && CATENA_ARDUINO_PLATFORM_VERSION >= CATENA_ARDUINO_PLATFORM_VERSION_CALC(0,17,0,10) + LMIC_setClockError(5 * 65536 / 100); +#else + LMIC_setClockError(10 * 65536 / 100); +#endif + // Do an unjoin, so every reboot will trigger a join if (config_data.debug_level > 0) { gCatena.SafePrintf("%010d - do an unjoin...\n", millis()); @@ -518,6 +525,41 @@ void DoDeepSleep(uint32_t sleep_time) } } +// highest and lowest value will be ignored +long my_read_average(byte gain, byte times) { + // highest and lowest value will be ignored + long sum = 0; + long v = 0; + long L = 2147483647; + long H = -2147483648; + long res; + if (config_data.debug_level > 0) { + gCatena.SafePrintf("%010d - my_read_average, measurements: ", millis()); + } + for (byte i = 0; i < times; i++) { + delay(WAITTIMELOADSAMPLES * 1000); + LoadCell.power_up(); + LoadCell.set_gain(gain); + delay(2); // wait for stabilizing + v = LoadCell.read(); + LoadCell.power_down(); + + if (L > v) L = v; // find lowest value + if (H < v) H = v; // find highest value + sum += v; + if (config_data.debug_level > 0) { + gCatena.SafePrintf("%d ", v); + } + gCatena.poll(); + } + res = (sum - L - H) / (times - 2); + if (config_data.debug_level > 0) { + gCatena.SafePrintf("; average (without highest [%d] and lowest [%d] value): %d\n", H, L, res); + } + + return res; +} + void ReadSensors(SENSOR_data &sensor_data) { SENSOR_data res; int32_t weight_current32; @@ -535,15 +577,13 @@ void ReadSensors(SENSOR_data &sensor_data) { if (config_data.debug_level > 0) { gCatena.SafePrintf("%010d - HX711 LoadCell is ready.\n", millis()); } - LoadCell.set_gain(128); gCatena.poll(); - res.weight1 = (int32_t)LoadCell.read_average(5); + res.weight1 = (int32_t)my_read_average(32,7); if (config_data.debug_level > 0) { gCatena.SafePrintf("%010d - Load_cell 1 weight1_current: %ld\n", millis(), res.weight1); } gCatena.poll(); - LoadCell.set_gain(32); - res.weight2 = (int32_t)LoadCell.read_average(5); + res.weight2 = (int32_t)my_read_average(128,7); if (config_data.debug_level > 0) { gCatena.SafePrintf("%010d - Load_cell 2 weight2_current: %ld\n", millis(), res.weight2); } @@ -704,7 +744,7 @@ void StartNewIteration() { gLed.Set(LedPattern::Sleeping); } } - + if (!fUsbPower) { DoDeepSleep(sleep_time_sec); os_setTimedCallback( @@ -713,7 +753,9 @@ void StartNewIteration() { startNewIterationCb); } else { - gCatena.SafePrintf("%010d - light sleep; os_setTimedCallback for startNewIterationCb in %d...seconds\n", millis(), sleep_time_sec); + if (config_data.debug_level > 0) { + gCatena.SafePrintf("%010d - light sleep; os_setTimedCallback for startNewIterationCb in %d...seconds\n", millis(), sleep_time_sec); + } os_setTimedCallback( &iterationJob, os_getTime() + sec2osticks(sleep_time_sec), @@ -855,7 +897,7 @@ static void startNewIterationCb(osjob_t* pJob) if (config_data.debug_level > 0) { gCatena.SafePrintf("%010d - startNewIterationCb\n", millis()); } - + StartNewIteration(); } @@ -1005,12 +1047,9 @@ cCommandStream::CommandStatus cmdGetScale2(cCommandStream *pThis, void *pContext cCommandStream::CommandStatus cmdCalibrateZeroScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv) { - SENSOR_data temp_sensor_data; - - ReadSensors(temp_sensor_data); - config_data.cal_w1_0 = temp_sensor_data.weight1; + setup_scales(); + config_data.cal_w1_0 = (int32_t)my_read_average(32,10); gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data)); - pThis->printf("{ \"msg\": \"calibrate_zero_scale_a was successful\" }\n"); return cCommandStream::CommandStatus::kSuccess; @@ -1018,12 +1057,9 @@ cCommandStream::CommandStatus cmdCalibrateZeroScaleA(cCommandStream *pThis, void cCommandStream::CommandStatus cmdCalibrateZeroScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv) { - SENSOR_data temp_sensor_data; - - ReadSensors(temp_sensor_data); - config_data.cal_w2_0 = temp_sensor_data.weight2; + setup_scales(); + config_data.cal_w2_0 = (int32_t)my_read_average(128,10); gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data)); - pThis->printf("{ \"msg\": \"calibrate_zero_scale_b was successful\" }\n"); return cCommandStream::CommandStatus::kSuccess; @@ -1031,20 +1067,14 @@ cCommandStream::CommandStatus cmdCalibrateZeroScaleB(cCommandStream *pThis, void cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv) { - SENSOR_data temp_sensor_data; - - ReadSensors(temp_sensor_data); String w1_gramm(argv[1]); - config_data.cal_w1_factor = (((float)temp_sensor_data.weight1 - config_data.cal_w1_0) / w1_gramm.toFloat()); + long weight1; + setup_scales(); + weight1 = my_read_average(32,10); + config_data.cal_w1_factor = (float)((weight1 - config_data.cal_w1_0) / w1_gramm.toFloat()); gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data)); - gCatena.SafePrintf("temp_sensor_data.weight1: %ld\n", temp_sensor_data.weight1); - gCatena.SafePrintf("config_data.cal_w1_0: %ld\n", config_data.cal_w1_0); - gCatena.SafePrintf("w1_gramm: %s\n", w1_gramm); - gCatena.SafePrintf("w1_gramm (float): %d\n", (int)w1_gramm.toFloat()); - gCatena.SafePrintf("config_data.cal_w1_factor: %d\n", (int)config_data.cal_w1_factor); - pThis->printf("{ \"msg\": \"calibrate_scale_a was successful\" }\n"); return cCommandStream::CommandStatus::kSuccess; @@ -1052,11 +1082,11 @@ cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream *pThis, void *pC cCommandStream::CommandStatus cmdCalibrateScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv) { - SENSOR_data temp_sensor_data; - - ReadSensors(temp_sensor_data); String w2_gramm(argv[1]); - config_data.cal_w2_factor = (((float)temp_sensor_data.weight2 - config_data.cal_w2_0) / w2_gramm.toFloat()); + long weight2; + setup_scales(); + weight2 = my_read_average(128,10); + config_data.cal_w2_factor = (float)((weight2 - config_data.cal_w2_0) / w2_gramm.toFloat()); gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data)); @@ -1068,7 +1098,6 @@ cCommandStream::CommandStatus cmdCalibrateScaleB(cCommandStream *pThis, void *pC cCommandStream::CommandStatus cmdSetDebugLevel(cCommandStream *pThis, void *pContext, int argc, char **argv) { String s_debug_level(argv[1]); - config_data.debug_level = s_debug_level.toInt(); gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data)); diff --git a/mini_beieli_node.h b/mini_beieli_node.h index b003f16..a303b93 100644 --- a/mini_beieli_node.h +++ b/mini_beieli_node.h @@ -55,7 +55,14 @@ enum { | \****************************************************************************/ -static const int32_t fwVersion = 20191122; +static const int32_t fwVersion = 20191209; + +// wait between samples +// 3 sec is a good delay so that load cell did not warm up +// too much and external random influences like wind has time +// to go so that the next sample is more valid +const int WAITTIMELOADSAMPLES = 3; + static const byte MAX_VALUES_TO_SEND = 8; //static const byte MAX_VALUES_TO_SEND = 1; // Testing static const uint8_t LORA_DATA_VERSION = 1;