Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add temperature compensation feature #11

Merged
merged 13 commits into from
Apr 5, 2017
12 changes: 8 additions & 4 deletions node-wifi-mqtt-homie-battery/CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,27 @@ in-progress
- Set some custom settings as default, limited at the moment by issue:
https://github.com/marvinroger/homie-esp8266/issues/323

2017-04-04 0.9.4
================
- Add temperature compensation in gram per degree.

2017-03-27 0.9.3
=================
================
- Add connection error handling to avoid battery drain (WIFI/MQTT Connection issues) Thanks to a broken WIFI and @amotl.

2017-03-27 0.9.2
=================
================
- Disable 3 of 4 default settings due to bug in homie-esp8266

2017-03-24 0.9.1
=================
================
- Make use of onHomieEvent to ensure a clean disconnect from broker before deepSleep
- Implement a battery check, create a low battery alarm topic to notify user and make the ESP sleep "forever"
- All needed settings are now settable via HomieSetting
- Modularized code
- Add versioning scheme

2017-03-18 0.9.0
=================
================
- Add JSON output for hiveeyes.org compatibility

4 changes: 1 addition & 3 deletions node-wifi-mqtt-homie-battery/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ battery lifetime a lot.

.. Todo::

- Add some scale/temperature calibration curves. Actually not too important,
as some grams don't really matter while we are measuring up to 120kg.
But we can ;-)
- Describe how to determine scale's temperature compensation values.


.. include:: CHANGES.rst
Expand Down
17 changes: 16 additions & 1 deletion node-wifi-mqtt-homie-battery/node-wifi-mqtt-homie-battery.ino
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
#include <RunningMedian.h>

#define FW_NAME "node-wifi-mqtt-homie-battery"
#define FW_VERSION "0.9.3"
#define FW_VERSION "0.9.4"
const int DEFAULT_SLEEP_TIME = 600;

// PINs
Expand All @@ -65,6 +65,8 @@ const int DEFAULT_SLEEP_TIME = 600;
*/
const long DEFAULT_WEIGHT_OFFSET = 154231; // Load cell zero offset.
const float DEFAULT_KILOGRAM_DIVIDER = 21.76; // Load cell value per kilogram.
const float DEFAULT_CALIBRATION_TEMPERATURE = 20.0; // Temperature at which the scale has been calibrated for Temperature compensation
const float DEFAULT_CALIBRATION_FACTOR_GRAM_DEGREE = 0.0; // Calibration factor in gram per degree

/*
* Scale should be calibrated with a regulated input of 3.3V!
Expand All @@ -83,6 +85,8 @@ const float DEFAULT_VCC_ADJUST = 0.13;
HomieSetting<long> sleepTimeSetting("sleepTime", "SleepTime in seconds (max. 3600s!), default is 60s");
HomieSetting<long> weightOffsetSetting("weightOffset", "Offset value to zero. Use BeeScale-Calibration.ino to determine.");
HomieSetting<double> kilogramDividerSetting("kilogramDivider", "Scale value per kilogram. Use BeeScale-Calibration.ino to determine.");
HomieSetting<double> calibrationTemperatureSetting("calibrationTemperature", "Outside Temperature at which the scale has been calibrated");
HomieSetting<double> calibrationFactorSetting("calibrationFactor", "Calibration Factor in gram per degree. 0.0 to disable adjustment");
HomieSetting<double> vccAdjustSetting("vccAdjust", "Calibration value for input voltage. See sketch for details.");

HX711 scale;
Expand Down Expand Up @@ -197,6 +201,15 @@ void getWeight() {
scale.power_down();

weight = WeightSamples.getMedian();

//temperature compensation
Homie.getLogger() << "✔ uncompensated median Weight: " << weight << "g" << endl;
float calibrationTemperature = calibrationTemperatureSetting.get();
float calibrationFactor = calibrationFactorSetting.get();
if (temperature1 < calibrationTemperature) weight = weight+(fabs(temperature1 - calibrationTemperature)*calibrationFactor);
if (temperature1 > calibrationTemperature) weight = weight-(fabs(temperature1 - calibrationTemperature)*calibrationFactor);
Homie.getLogger() << "✔ compensated median Weight: " << weight << "g" << endl;

weight = weight / 1000 ; // we want kilogram
}

Expand Down Expand Up @@ -352,6 +365,8 @@ void setup() {
weightOffsetSetting.setDefaultValue(DEFAULT_WEIGHT_OFFSET);
kilogramDividerSetting.setDefaultValue(DEFAULT_KILOGRAM_DIVIDER);
vccAdjustSetting.setDefaultValue(DEFAULT_VCC_ADJUST);
calibrationTemperatureSetting.setDefaultValue(DEFAULT_CALIBRATION_TEMPERATURE);
calibrationFactorSetting.setDefaultValue(DEFAULT_CALIBRATION_FACTOR_GRAM_DEGREE);

//get all measurements *BEFORE* WIFI get's active. This saves around 4s at full mA
getTemperatures();
Expand Down
7 changes: 7 additions & 0 deletions node-wifi-mqtt-homie/CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ in-progress
- Set some custom settings as default, limited at the moment by issue:
https://github.com/marvinroger/homie-esp8266/issues/323

2017-03-27 0.9.4
=================
- Add temperature compensation in gram per degree

2017-03-27 0.9.3
=================
- ommited for the non battery version

2017-03-28 0.9.2
=================
Expand Down
6 changes: 2 additions & 4 deletions node-wifi-mqtt-homie/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,11 @@ When installing the `UI bundle`_ "``ui_bundle.gz``", the configuration UI will b
****
Todo
****
- Check if HTTP API, SPIFFS and UI configuration options work as described
- Use the `Homie custom settings`_ feature for storing calibration values
- Improve documentation at all
- Document how to determine calibration values (i.e. "Use sketch BeeScale-Calibration to get these values").
Would it be possible to build it into the main firmware and run it conditionally somehow?
- Make the `Hiveeyes Backend`_ grok data from Homie devices by using the setting ``mqtt.base_topic`` like::
- Document how to determine scale's temperature compensation values.

mqtt.base_topic: hiveeyes/{network}/{gateway}/{node}/homie

.. _Homie custom settings: https://homie-esp8266.readme.io/docs/custom-settings

39 changes: 27 additions & 12 deletions node-wifi-mqtt-homie/node-wifi-mqtt-homie.ino
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
HX711 scale;

#define FW_NAME "node-wifi-mqtt-homie"
#define FW_VERSION "0.9.2"
#define FW_VERSION "0.9.4"
const int DEFAULT_SEND_INTERVAL = 60;

// PINs
Expand All @@ -57,6 +57,8 @@ const int DEFAULT_SEND_INTERVAL = 60;
*/
const float DEFAULT_WEIGHT_OFFSET = 244017.00; // Load cell zero offset.
const float DEFAULT_KILOGRAM_DIVIDER = 22.27; // Load cell value per kilogram.
const float DEFAULT_CALIBRATION_TEMPERATURE = 20.0; // Temperature at which the scale has been calibrated for Temperature compensation
const float DEFAULT_CALIBRATION_FACTOR_GRAM_DEGREE = 0.0; // Calibration factor in gram per degree
unsigned long lastSent = 0;

RunningMedian WeightSamples = RunningMedian(4);
Expand Down Expand Up @@ -87,6 +89,8 @@ HomieNode jsonNode("data","__json__");
HomieSetting<long> sendIntervalSetting("sendInterval", "Interval for measurements in seconds (max. 3600)");
HomieSetting<long> weightOffsetSetting("weightOffset", "Offset value to zero. Use BeeScale-Calibration.ino to determine.");
HomieSetting<double> kilogramDividerSetting("kilogramDivider", "Scale value per kilogram. Use BeeScale-Calibration.ino to determine.");
HomieSetting<double> calibrationTemperatureSetting("calibrationTemperature", "Outside Temperature at which the scale has been calibrated");
HomieSetting<double> calibrationFactorSetting("calibrationFactor", "Calibration Factor in gram per degree. 0.0 to disable adjustment");
HomieSetting<double> vccAdjustSetting("vccAdjust", "Calibration value for input voltage. See sketch for details.");

void setupHandler() {
Expand Down Expand Up @@ -115,46 +119,55 @@ void getTemperatures() {
}

void getWeight() {
Serial << endl << endl;
Serial << "Reading scale, hold on" << endl;
Homie.getLogger() << endl << endl;
Homie.getLogger() << "Reading scale, hold on" << endl;
scale.power_up();
for (int i = 0; i < 4; i++) {
float WeightRaw = scale.get_units(10);
yield();
Serial << "✔ Raw measurements: " << WeightRaw << "g" << endl;
Homie.getLogger() << "✔ Raw measurements: " << WeightRaw << "g" << endl;
WeightSamples.add(WeightRaw);
delay(500);
yield();
}
scale.power_down();

weight = WeightSamples.getMedian();

//temperature compensation
Homie.getLogger() << "✔ uncompensated median Weight: " << weight << "g" << endl;
float calibrationTemperature = calibrationTemperatureSetting.get();
float calibrationFactor = calibrationFactorSetting.get();
if (temperature1 < calibrationTemperature) weight = weight+(fabs(temperature1 - calibrationTemperature)*calibrationFactor);
if (temperature1 > calibrationTemperature) weight = weight-(fabs(temperature1 - calibrationTemperature)*calibrationFactor);
Homie.getLogger() << "✔ compensated median Weight: " << weight << "g" << endl;

weight = weight / 1000 ; // we want kilogram
}

void getVolt() {
raw_voltage = ESP.getVcc();
vcc_adjust = vccAdjustSetting.get();
Serial << "Voltage adjust value is: " << vcc_adjust << "V" << endl;
Homie.getLogger() << "Voltage adjust value is: " << vcc_adjust << "V" << endl;
voltage = raw_voltage / 1000 + vcc_adjust;
}

void loopHandler() {
if (millis() - lastSent >= sendIntervalSetting.get() * 1000UL || lastSent == 0) {
getTemperatures();
Serial << "Temperature0: " << temperature0 << " °C" << endl;
Homie.getLogger() << "Temperature0: " << temperature0 << " °C" << endl;
temperatureNode0.setProperty("degrees").setRetained(false).send(String(temperature0));

Serial << "Temperature1: " << temperature1 << " °C" << endl;
Homie.getLogger() << "Temperature1: " << temperature1 << " °C" << endl;
temperatureNode1.setProperty("degrees").setRetained(false).send(String(temperature1));

getWeight();
Serial << "Weight: " << weight << " kg" << endl;
Homie.getLogger() << "Weight: " << weight << " kg" << endl;
weightNode.setProperty("kilogram").setRetained(false).send(String(weight));

getVolt();
Serial << "Raw Input Voltage: " << raw_voltage << " V" << endl;
Serial << "Input Voltage: " << voltage << " V" << endl;
Homie.getLogger() << "Raw Input Voltage: " << raw_voltage << " V" << endl;
Homie.getLogger() << "Input Voltage: " << voltage << " V" << endl;
batteryNode.setProperty("volt").setRetained(true).send(String(voltage));

StaticJsonBuffer<200> jsonBuffer;
Expand All @@ -164,7 +177,7 @@ void loopHandler() {
root["Temp2"] = temperature1;
String values;
root.printTo(values);
Serial << "Json data:" << values << endl;
Homie.getLogger() << "Json data:" << values << endl;
jsonNode.setProperty("__json__").setRetained(false).send(values);

lastSent = millis();
Expand All @@ -182,9 +195,11 @@ void setup() {
/*
* Can't set more than one value to default, see issue #323
* https://github.com/marvinroger/homie-esp8266/issues/323
*/
weightOffsetSetting.setDefaultValue(DEFAULT_WEIGHT_OFFSET);
kilogramDividerSetting.setDefaultValue(DEFAULT_KILOGRAM_DIVIDER);
*/
calibrationTemperatureSetting.setDefaultValue(DEFAULT_CALIBRATION_TEMPERATURE);
calibrationFactorSetting.setDefaultValue(DEFAULT_CALIBRATION_FACTOR_GRAM_DEGREE);

scale.begin(DOUT, PD_SCK);
scale.set_scale(kilogramDividerSetting.get()); //initialize scale
Expand Down