From ff35a7ddedb7517838dd0e6b20a3d33ca7a80352 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 14 Mar 2021 17:04:24 +0100 Subject: [PATCH] add voltage sensing --- src/main.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 41f1104..e30ba6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,16 @@ //Upload config: platformio run --target uploadfs +#define PIN_VBAT A0 +unsigned long vbat_calib1_adc=581; //adc value at vbat_calib_voltage (voltage at battery) +float vbat_calib1_voltage=6.0; //voltage used for calibration + +unsigned long vbat_calib2_adc=782; //second calibration point (higher voltage) +float vbat_calib2_voltage=8.0; + +int vbat_raw_filtered=-1; //-1 flags it as initialized +bool vbatSent=false; + #include #define TM1637_CLK D5 @@ -82,7 +92,8 @@ bool livesend=false; //if true, sends continuous data over mqtt void loopHandler(); HomieNode scaleNode("weight", "Scale", "scale"); //paramters: topic, $name, $type -HomieNode displayNode("display", "Scale", "scale"); //paramters: topic, $name, $type +HomieNode displayNode("display", "Display", "scale"); //paramters: topic, $name, $type +HomieNode hardwareNode("hardware", "Hardware", "scale"); //paramters: topic, $name, $type int sort_desc(const void *cmp1, const void *cmp2); float getFilteredWeight(); @@ -92,8 +103,10 @@ bool cmdHandler(const HomieRange& range, const String& value); bool displayNodeHandler(const HomieRange& range, const String& value); void powerOff(); void displayNumber(float numberdisplay); - - +float getVBat(); +void updateVBat(); +void sendVBat(); +float mapFloat(float x, float in_min, float in_max, float out_min, float out_max); void setup() { pinMode(PIN_SELFENABLE,OUTPUT); @@ -114,7 +127,7 @@ void setup() { Homie_setBrand(FW_NAME); Homie.setLoopFunction(loopHandler); - scaleNode.advertise("cmd").settable(cmdHandler); //function inputHandler gets called on new message on topic/input/set + scaleNode.advertise("human"); scaleNode.advertise("spread"); scaleNode.advertise("raw"); @@ -122,6 +135,10 @@ void setup() { displayNode.advertise("segments").settable(displayNodeHandler); + hardwareNode.advertise("cmd").settable(cmdHandler); //function inputHandler gets called on new message on topic/input/set + hardwareNode.advertise("vbat"); + hardwareNode.advertise("vbatraw"); + Homie.setup(); @@ -147,13 +164,13 @@ void loop() { void loopHandler() { unsigned long loopmillis=millis(); - - static unsigned long last_measure=0; if (loopmillis>last_measure+MEASURE_INTERVAL) { last_measure=loopmillis; + updateVBat(); //also update vbat reading + //Serial.print("reading="); weight_current=0; if (scale.wait_ready_timeout(1000)) { //for non blocking mode @@ -163,7 +180,7 @@ void loopHandler() { weight_read[weight_read_pos]=weight_current; //one reading takes 91ms } else { Serial.println("HX711 not found."); - scaleNode.setProperty("cmd").send("HX711 not found"); //can be done in main loop + hardwareNode.setProperty("cmd").send("HX711 not found"); //can be done in main loop } weight_filtered=getFilteredWeight(); @@ -196,15 +213,30 @@ void loopHandler() { if (!weight_sent) { if (weight_max-weight_tare>MIN_WEIGHT_DIFFERENCE) { - sendWeight(weight_max-weight_tare); + if (Homie.getMqttClient().connected()) { + sendWeight(weight_max-weight_tare); + }else{ + Serial.println("Cannot send weight because mqtt not connected!"); + } update_display=true; } } + + + if (!vbatSent && loopmillis>10000) { //send voltage some time after turn on + if (Homie.getMqttClient().connected()) { + sendVBat(); + vbatSent=true; + }else{ + Serial.println("Cannot send vbat because mqtt not connected!"); + } + } + } - if (livesend && (millis()>last_mqtt_send+MQTT_SENDINTERVALL)) { + if (Homie.getMqttClient().connected() && livesend && (millis()>last_mqtt_send+MQTT_SENDINTERVALL)) { last_mqtt_send=millis(); //float weight_filtered=getFilteredWeight(); @@ -315,10 +347,10 @@ bool cmdHandler(const HomieRange& range, const String& value) { if (scale.wait_ready_timeout(1000)) { //for non blocking mode scale.set_scale(); scale.tare(); - scaleNode.setProperty("cmd").send("tared"); + hardwareNode.setProperty("cmd").send("tared"); } else { Serial.println("HX711 not found."); - scaleNode.setProperty("cmd").send("HX711 not found"); + hardwareNode.setProperty("cmd").send("HX711 not found"); } }else if (value=="calibrate") { //get raw value. use "reset" first. then adc to get value for calibration to enter in SCALE_CALIBRATION @@ -326,21 +358,23 @@ bool cmdHandler(const HomieRange& range, const String& value) { long _units=scale.get_units(10); //if set_scale was called with no parameter before, get_units has not decimals char charBuf[13]; dtostrf(_units,2, 1, charBuf); - scaleNode.setProperty("cmd").send(charBuf); + hardwareNode.setProperty("cmd").send(charBuf); } else { Serial.println("HX711 not found."); - scaleNode.setProperty("cmd").send("HX711 not found"); + hardwareNode.setProperty("cmd").send("HX711 not found"); } }else if (value=="live") { livesend=!livesend; if (livesend) { - scaleNode.setProperty("cmd").send("live data enabled"); + hardwareNode.setProperty("cmd").send("live data enabled"); }else{ - scaleNode.setProperty("cmd").send("live data disabled"); + hardwareNode.setProperty("cmd").send("live data disabled"); } + }else if (value=="vbat") { + sendVBat(); }else if (value=="off") { powerOff(); - scaleNode.setProperty("cmd").send("shutting down"); + hardwareNode.setProperty("cmd").send("shutting down"); } else { Homie.getLogger() << "cmd not recognized" << endl; return false; @@ -459,4 +493,32 @@ void displayNumber(float numberdisplay) { } +} + +float getVBat() { //get filtered vbat value + return mapFloat(vbat_raw_filtered,vbat_calib1_adc,vbat_calib2_adc, vbat_calib1_voltage,vbat_calib2_voltage); //2-point mapping adc -> voltage; +} + +void updateVBat() { //continuous update for filtering + float vbat_filter=0.95; //the closer to 1 the higher the filtering. 0 means no filtering + if (vbat_raw_filtered<0) { //at first reading (vbat_raw_filtered is initialized with value <0) + vbat_filter=0; //use first reading with 100% + } + vbat_raw_filtered=vbat_raw_filtered*vbat_filter + analogRead(PIN_VBAT)*(1.0-vbat_filter); +} + +void sendVBat() { + char charBuf[10]; + dtostrf(vbat_raw_filtered,1, 0, charBuf); + hardwareNode.setProperty("vbatraw").send(charBuf); + Serial.print("vbatraw="); Serial.println(vbat_raw_filtered); + + dtostrf(getVBat(),4, 3, charBuf); + hardwareNode.setProperty("vbat").send(charBuf); + Serial.print("vbat="); Serial.println(getVBat(),3); +} + +float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } \ No newline at end of file