supla-device
Loading...
Searching...
No Matches
HX711.h
1/*
2 Copyright (C) AC SOFTWARE SP. Z O.O.
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; either version 2
6 of the License, or (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11 You should have received a copy of the GNU General Public License
12 along with this program; if not, write to the Free Software
13 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14*/
15
16#ifndef SRC_SUPLA_SENSOR_HX711_H_
17#define SRC_SUPLA_SENSOR_HX711_H_
18
19/*
20Dependency: https://github.com/olkal/HX711_ADC,
21use library manager to install it
22*/
23
24#include <HX711_ADC.h>
25#include <supla/log_wrapper.h>
26
27#include "weight.h"
28#include "../storage/storage.h"
29
30namespace Supla {
31namespace Sensor {
32
33#pragma pack(push, 1)
35 uint32_t tareOffset;
36 float calValue;
37};
38#pragma pack(pop)
39
40class HX711 : public Weight {
41 public:
42 HX711(int sdaPin, int sclPin, float defCalValue = 696.0)
43 : hx711Sensor(sdaPin, sclPin), defCalValue(defCalValue) {
44 }
45
46 double getValue() {
47 if ((hx711Sensor.getSPS() < 7) || (hx711Sensor.getSPS() > 100)) {
48 value = WEIGHT_NOT_AVAILABLE;
49 SUPLA_LOG_DEBUG(
50 "HX711 measured sampling rate: %.2f HZ is abnormal, check connection"
51 , hx711Sensor.getSPS());
52 } else {
53 value = (value < 0 && value > -1) ? 0 : value;
54 // Displaying one decimal in Cloud
55 int tmp = static_cast<int>(value*10);
56 value = static_cast<double>(tmp/10.0);
57 }
58 return value;
59 }
60
61 void onInit() {
62 hx711Sensor.begin();
63 hx711Sensor.setTareOffset(tareOffset);
64 uint64_t stabilizingTime = 2000;
65 bool _tare = false;
66 hx711Sensor.start(stabilizingTime, _tare);
67 if (hx711Sensor.getTareTimeoutFlag()) {
68 SUPLA_LOG_DEBUG("HX711 timeout, check connection");
69 } else {
70 calFactor = (calValue > 0) ? calValue : defCalValue;
71 hx711Sensor.setCalFactor(calFactor);
72 SUPLA_LOG_DEBUG("HX711 startup is complete");
73 }
74 uint32_t wait = millis();
75 while (!hx711Sensor.update() && millis() - wait <= 100) {}
76 SUPLA_LOG_INFO("HX711 calibration value: %.2f", hx711Sensor.getCalFactor());
77 SUPLA_LOG_INFO(
78 "HX711 measured conversion time ms: %.2f",
79 hx711Sensor.getConversionTime());
80 SUPLA_LOG_DEBUG(
81 "HX711 measured sampling rate: %.2f HZ", hx711Sensor.getSPS());
82 SUPLA_LOG_INFO(
83 "HX711 measured settling time ms: %d", hx711Sensor.getSettlingTime());
84 channel.setNewValue(getValue());
85 }
86
87 void calibrateScales(float knownMass = 0) {
88 if (!readyToCalibration) {
89 SUPLA_LOG_DEBUG("HX711 please do tare");
90 } else {
91 hx711Sensor.update();
92 hx711Sensor.refreshDataSet();
93 if (knownMass > 0) {
94 calValue = hx711Sensor.getNewCalibration(knownMass);
95 SUPLA_LOG_DEBUG("HX711 new calibration value: %.2f", calValue);
96 Supla::Storage::ScheduleSave(100);
97 } else {
98 SUPLA_LOG_DEBUG("HX711 known mass must be greater than zero");
99 }
100 }
101 readyToCalibration = false;
102 }
103
104 void tareScales() {
105 hx711Sensor.tare();
106 tareOffset = hx711Sensor.getTareOffset();
107 SUPLA_LOG_DEBUG("HX711 new tare offset: %d", tareOffset);
108 Supla::Storage::ScheduleSave(100);
109 readyToCalibration = true;
110 }
111
113 // According to the library, the sampling frequency
114 // must be in the range 7 - 100 Hz. Now, it's around 10.5 Hz.
115 if (hx711Sensor.update()) {
116 value = hx711Sensor.getData();
117 }
118 if (millis() - lastReadTime > 500) {
119 lastReadTime = millis();
120 channel.setNewValue(getValue());
121 }
122 }
123
124 void onLoadState() {
126 if (Supla::Storage::ReadState((unsigned char *)&data, sizeof(data))) {
127 tareOffset = data.tareOffset;
128 calValue = data.calValue;
129 }
130 SUPLA_LOG_DEBUG(
131 "HX711 settings restored from storage. Tare offset: %d; "
132 "calibration value: %.2f", tareOffset, calValue);
133 }
134
135 void onSaveState() {
136 HX711ConfigData data;
137 data.tareOffset = tareOffset;
138 data.calValue = calValue;
139
140 Supla::Storage::WriteState((unsigned char *)&data, sizeof(data));
141 }
142
143 float getTareOffset() {
144 return tareOffset;
145 }
146
147 float getCalFactor() {
148 return calFactor;
149 }
150
151 protected:
152 ::HX711_ADC hx711Sensor;
153 double value = 0;
154 uint32_t tareOffset = 0;
155 float calFactor = 0;
156 float defCalValue;
157 float calValue = 0;
158 bool readyToCalibration = false;
159};
160
161}; // namespace Sensor
162}; // namespace Supla
163
164#endif // SRC_SUPLA_SENSOR_HX711_H_
void onSaveState()
Method called periodically during SuplaDevice iteration.
Definition HX711.h:135
void onInit()
Third method called on element in SuplaDevice.begin()
Definition HX711.h:61
void iterateAlways()
Method called on each SuplaDevice iteration.
Definition HX711.h:112
void onLoadState()
Second method called on element in SuplaDevice.begin().
Definition HX711.h:124
Definition HX711.h:34