add voltage sensing

This commit is contained in:
interfisch 2021-03-14 17:04:24 +01:00
parent d2e710b4ba
commit ff35a7dded
1 changed files with 78 additions and 16 deletions

View File

@ -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 <TM1637Display.h>
#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();
@ -148,12 +165,12 @@ 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) {
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;
@ -460,3 +494,31 @@ 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;
}