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#include <supla/time.h>
27
28#include "weight.h"
29#include "../storage/storage.h"
30
31namespace Supla {
32namespace Sensor {
33
34#pragma pack(push, 1)
36 uint32_t tareOffset;
37 float calValue;
38};
39#pragma pack(pop)
40
41class HX711 : public Weight {
42 public:
43 HX711(int sdaPin, int sclPin, float defCalValue = 696.0)
44 : hx711Sensor(sdaPin, sclPin), defCalValue(defCalValue) {
45 }
46
47 double getValue() {
48 if ((hx711Sensor.getSPS() < 7) || (hx711Sensor.getSPS() > 100)) {
49 value = WEIGHT_NOT_AVAILABLE;
50 SUPLA_LOG_DEBUG(
51 "HX711 measured sampling rate: %.2f HZ is abnormal, check connection"
52 , hx711Sensor.getSPS());
53 } else {
54 value = (value < 0 && value > -1) ? 0 : value;
55 // Displaying one decimal in Cloud
56 int tmp = static_cast<int>(value*10);
57 value = static_cast<double>(tmp/10.0);
58 }
59 return value;
60 }
61
62 void onInit() {
63 hx711Sensor.begin();
64 hx711Sensor.setTareOffset(tareOffset);
65 uint64_t stabilizingTime = 2000;
66 bool _tare = false;
67 hx711Sensor.start(stabilizingTime, _tare);
68 if (hx711Sensor.getTareTimeoutFlag()) {
69 SUPLA_LOG_DEBUG("HX711 timeout, check connection");
70 } else {
71 calFactor = (calValue > 0) ? calValue : defCalValue;
72 hx711Sensor.setCalFactor(calFactor);
73 SUPLA_LOG_DEBUG("HX711 startup is complete");
74 }
75 uint32_t wait = millis();
76 while (!hx711Sensor.update() && millis() - wait <= 100) {}
77 SUPLA_LOG_INFO("HX711 calibration value: %.2f", hx711Sensor.getCalFactor());
78 SUPLA_LOG_INFO(
79 "HX711 measured conversion time ms: %.2f",
80 hx711Sensor.getConversionTime());
81 SUPLA_LOG_DEBUG(
82 "HX711 measured sampling rate: %.2f HZ", hx711Sensor.getSPS());
83 SUPLA_LOG_INFO(
84 "HX711 measured settling time ms: %d", hx711Sensor.getSettlingTime());
85 channel.setNewValue(getValue());
86 }
87
88 void calibrateScales(float knownMass = 0) {
89 if (!readyToCalibration) {
90 SUPLA_LOG_DEBUG("HX711 please do tare");
91 } else {
92 hx711Sensor.update();
93 hx711Sensor.refreshDataSet();
94 if (knownMass > 0) {
95 calValue = hx711Sensor.getNewCalibration(knownMass);
96 SUPLA_LOG_DEBUG("HX711 new calibration value: %.2f", calValue);
98 } else {
99 SUPLA_LOG_DEBUG("HX711 known mass must be greater than zero");
100 }
101 }
102 readyToCalibration = false;
103 }
104
105 void tareScales() {
106 hx711Sensor.tare();
107 tareOffset = hx711Sensor.getTareOffset();
108 SUPLA_LOG_DEBUG("HX711 new tare offset: %d", tareOffset);
110 readyToCalibration = true;
111 }
112
114 // According to the library, the sampling frequency
115 // must be in the range 7 - 100 Hz. Now, it's around 10.5 Hz.
116 if (hx711Sensor.update()) {
117 value = hx711Sensor.getData();
118 }
119 if (millis() - lastReadTime > 500) {
120 lastReadTime = millis();
121 channel.setNewValue(getValue());
122 }
123 }
124
125 void onLoadState() {
127 if (Supla::Storage::ReadState((unsigned char *)&data, sizeof(data))) {
128 tareOffset = data.tareOffset;
129 calValue = data.calValue;
130 }
131 SUPLA_LOG_DEBUG(
132 "HX711 settings restored from storage. Tare offset: %d; "
133 "calibration value: %.2f", tareOffset, calValue);
134 }
135
136 void onSaveState() {
137 HX711ConfigData data;
138 data.tareOffset = tareOffset;
139 data.calValue = calValue;
140
141 Supla::Storage::WriteState((unsigned char *)&data, sizeof(data));
142 }
143
144 float getTareOffset() {
145 return tareOffset;
146 }
147
148 float getCalFactor() {
149 return calFactor;
150 }
151
152 protected:
153 ::HX711_ADC hx711Sensor;
154 double value = 0;
155 uint32_t tareOffset = 0;
156 float calFactor = 0;
157 float defCalValue;
158 float calValue = 0;
159 bool readyToCalibration = false;
160};
161
162}; // namespace Sensor
163}; // namespace Supla
164
165#endif // SRC_SUPLA_SENSOR_HX711_H_
void onSaveState()
Method called periodically during SuplaDevice iteration.
Definition HX711.h:136
void onInit()
Third method called on element in SuplaDevice.begin()
Definition HX711.h:62
void iterateAlways()
Method called on each SuplaDevice iteration.
Definition HX711.h:113
void onLoadState()
Second method called on element in SuplaDevice.begin().
Definition HX711.h:125
static void ScheduleSave(uint32_t delayMsMax, uint32_t delayMsMin=0)
Schedules save of state storage in given time range.
Definition storage.cpp:110
Definition HX711.h:35