add homie and weight filter functions
This commit is contained in:
parent
5ae6ab0c02
commit
5a99550e9c
|
@ -18,3 +18,4 @@ monitor_speed= 115200
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bogde/HX711 @ 0.7.4
|
bogde/HX711 @ 0.7.4
|
||||||
|
Homie@3.0.0
|
||||||
|
|
187
src/main.cpp
187
src/main.cpp
|
@ -1,4 +1,14 @@
|
||||||
#include<Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <Homie.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wemos d1 mini
|
||||||
|
* Flash Size: 4M (1M SPIFFS)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Upload config: platformio run --target uploadfs
|
||||||
|
|
||||||
|
|
||||||
#include "HX711.h"
|
#include "HX711.h"
|
||||||
|
|
||||||
|
@ -6,10 +16,63 @@
|
||||||
const int LOADCELL_DOUT_PIN = D2;
|
const int LOADCELL_DOUT_PIN = D2;
|
||||||
const int LOADCELL_SCK_PIN = D3;
|
const int LOADCELL_SCK_PIN = D3;
|
||||||
|
|
||||||
|
const int PIN_SELFENABLE = D1;
|
||||||
|
|
||||||
HX711 scale;
|
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() {
|
void setup() {
|
||||||
|
pinMode(PIN_SELFENABLE,OUTPUT);
|
||||||
|
digitalWrite(PIN_SELFENABLE, HIGH);
|
||||||
|
pinMode(LED_BUILTIN,OUTPUT);
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
|
||||||
Serial.begin(115200);
|
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);
|
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,11 +124,78 @@ void setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
Homie.loop();
|
||||||
|
}
|
||||||
|
|
||||||
Serial.print("reading:\t");
|
|
||||||
Serial.println(scale.get_units(10));
|
|
||||||
|
|
||||||
|
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 (spread<MAXSPREAD_TARE) { //if reading is stable
|
||||||
|
if (weight_filtered<weight_tare) { //new min
|
||||||
|
weight_tare=weight_filtered;
|
||||||
|
Serial.print("new tare="); Serial.println(weight_tare,3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define MAXSPREAD_MEASURE 0.5 //in kg
|
||||||
|
if (spread<MAXSPREAD_MEASURE) { //if reading is stable
|
||||||
|
if (weight_filtered>weight_max) { //new max
|
||||||
|
weight_max=weight_filtered;
|
||||||
|
Serial.print("new max="); Serial.println(weight_max,3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dtostrf(weight_max-weight_tare,4, 3, charBuf);
|
||||||
|
scaleNode.setProperty("max").send(charBuf); //filtered and auto tared
|
||||||
|
|
||||||
|
if (!weight_sent) {
|
||||||
|
if (weight_max-weight_tare>MIN_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);
|
delay(100);
|
||||||
|
digitalWrite(PIN_SELFENABLE, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
scale.power_down(); // put the ADC in sleep mode
|
scale.power_down(); // put the ADC in sleep mode
|
||||||
|
@ -73,3 +203,54 @@ void loop() {
|
||||||
scale.power_up();*/
|
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<READING_FILTER_SIZE;i++) {
|
||||||
|
copied_values[i] = weight_read[i]; //TODO: maybe some value filtering/selection here
|
||||||
|
}
|
||||||
|
float copied_values_length = sizeof(copied_values) / sizeof(copied_values[0]);
|
||||||
|
qsort(copied_values, copied_values_length, sizeof(copied_values[0]), sort_desc);
|
||||||
|
|
||||||
|
float mean=copied_values[READING_FILTER_SIZE/2];
|
||||||
|
for (uint8_t i=1; i<=MEANVALUECOUNT;i++) {
|
||||||
|
mean+=copied_values[READING_FILTER_SIZE/2-i]+copied_values[READING_FILTER_SIZE/2+i]; //add two values around center
|
||||||
|
}
|
||||||
|
mean/=(1+MEANVALUECOUNT*2);
|
||||||
|
|
||||||
|
return mean;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getWeightSpread() { //absolute difference between lowest and highest value in buffer
|
||||||
|
float copied_values[READING_FILTER_SIZE];
|
||||||
|
for(int i=0;i<READING_FILTER_SIZE;i++) {
|
||||||
|
copied_values[i] = weight_read[i]; //TODO: maybe some value filtering/selection here
|
||||||
|
}
|
||||||
|
float copied_values_length = sizeof(copied_values) / sizeof(copied_values[0]);
|
||||||
|
qsort(copied_values, copied_values_length, sizeof(copied_values[0]), sort_desc);
|
||||||
|
|
||||||
|
float diff=copied_values[0]-copied_values[READING_FILTER_SIZE-1];
|
||||||
|
|
||||||
|
if (diff<0) { //abs for float
|
||||||
|
diff*=-1;
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sendWeight(float w) {
|
||||||
|
char charBuf[10];
|
||||||
|
dtostrf(w,4, 3, charBuf);
|
||||||
|
scaleNode.setProperty("human").send(charBuf);
|
||||||
|
weight_sent=true;
|
||||||
|
weight_sent_time=millis();
|
||||||
|
Serial.print("Weight sent="); Serial.println(w,3);
|
||||||
|
}
|
Loading…
Reference in New Issue