From 5a99550e9c108dd624e1ff5e4e43d225162cb765 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 21 Feb 2021 17:35:18 +0100 Subject: [PATCH] add homie and weight filter functions --- platformio.ini | 1 + src/main.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 186 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 2972119..c44f333 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,3 +18,4 @@ monitor_speed= 115200 lib_deps = bogde/HX711 @ 0.7.4 + Homie@3.0.0 diff --git a/src/main.cpp b/src/main.cpp index 7f521b8..6447976 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,14 @@ -#include +#include +#include + + +/* + * Wemos d1 mini + * Flash Size: 4M (1M SPIFFS) + */ + +//Upload config: platformio run --target uploadfs + #include "HX711.h" @@ -6,10 +16,63 @@ const int LOADCELL_DOUT_PIN = D2; const int LOADCELL_SCK_PIN = D3; +const int PIN_SELFENABLE = D1; + HX711 scale; +#define MEASURE_INTERVAL 100 //ms +#define READING_FILTER_SIZE 40 //latency is about READING_FILTER_SIZE/2*MEASURE_INTERVAL +float weight_read[READING_FILTER_SIZE] = {0}; +uint8_t weight_read_pos=0; +#define MEANVALUECOUNT 4 //0<= meanvaluecount < READING_FILTER_SIZE/2 + +float weight_tare=0; //minimal filtered weight +#define MIN_WEIGHT_DIFFERENCE 50 //minimum weight +float weight_max=0; //max filtered weight + +bool weight_sent=false; +unsigned long weight_sent_time=0; + +#define MAXONTIME 60000*2 //turn off after ms + +#define FW_NAME "scale" +#define FW_VERSION "0.0.1" + +void loopHandler(); + +HomieNode scaleNode("weight", "Scale", "scale"); //paramters: topic, $name, $type + +int sort_desc(const void *cmp1, const void *cmp2); +float getFilteredWeight(); +float getWeightSpread(); +void sendWeight(float w); + + void setup() { + pinMode(PIN_SELFENABLE,OUTPUT); + digitalWrite(PIN_SELFENABLE, HIGH); + pinMode(LED_BUILTIN,OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + Serial.begin(115200); + + Homie.disableResetTrigger(); //disable config reset if pin 1 (D3) is low on startup + + + Homie_setFirmware(FW_NAME, FW_VERSION); + Homie_setBrand(FW_NAME); + Homie.setLoopFunction(loopHandler); + + scaleNode.advertise("human"); + scaleNode.advertise("spread"); + scaleNode.advertise("raw"); + scaleNode.advertise("max"); + + + + Homie.setup(); + + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); @@ -61,15 +124,133 @@ void setup() { } void loop() { + Homie.loop(); +} - Serial.print("reading:\t"); - Serial.println(scale.get_units(10)); - delay(100); +void loopHandler() { + unsigned long loopmillis=millis(); + + static unsigned long last_measure=0; + if (loopmillis>last_measure+MEASURE_INTERVAL) { + last_measure=loopmillis; + + Serial.print("reading="); + float weight_current=0; + if (scale.wait_ready_timeout(1000)) { //for non blocking mode + weight_read_pos++; + weight_read_pos%=READING_FILTER_SIZE; + weight_current=scale.get_units(1); + weight_read[weight_read_pos]=weight_current; //one reading takes 91ms + } else { + Serial.println("HX711 not found."); + } + + float weight_filtered=getFilteredWeight(); + float spread=getWeightSpread(); + + Serial.println(weight_current); + Serial.print("spread="); Serial.println(spread,3); + + char charBuf[10]; + dtostrf(weight_current,4, 3, charBuf); + scaleNode.setProperty("raw").send(charBuf); + + dtostrf(spread,4, 3, charBuf); + scaleNode.setProperty("spread").send(charBuf); + + + + #define MAXSPREAD_TARE 0.1 //in kg, for tare can be lower than for measuring + if (spreadMIN_WEIGHT_DIFFERENCE) { + sendWeight(weight_max-weight_tare); + } + } + + + } + + #define STAYONTIME_AFTER_SENT 5000 + if (millis() > MAXONTIME || (weight_sent && millis()>weight_sent_time+STAYONTIME_AFTER_SENT)) { + Serial.println("Turning Off"); + Serial.flush(); + delay(100); + digitalWrite(PIN_SELFENABLE, LOW); + } + /* scale.power_down(); // put the ADC in sleep mode delay(5000); scale.power_up();*/ +} + +int sort_desc(const void *cmp1, const void *cmp2) //compare function for qsort +{ + float a = *((float *)cmp1); + float b = *((float *)cmp2); + return a > b ? -1 : (a < b ? 1 : 0); +} + +float getFilteredWeight() { + float copied_values[READING_FILTER_SIZE]; + for(int i=0;i