Raspberry Pi Weighting Control System
This project serves as a simple weighting control system, that was realized as a Bachelor Thesis
custom_hx711.cpp
Go to the documentation of this file.
1 #include "custom_hx711.h"
2 
3 #include <thread>
4 
5 using namespace HX711;
6 
7 
8 custom_watcher::custom_watcher(HX711::HX711 *hx) : Watcher(hx) {}
9 
11  return this->_watchState;
12 }
13 
15  const int dataPin,
16  const int clockPin,
17  const Value refUnit,
18  const Value offset,
19  const Rate rate) :
20  AdvancedHX711(dataPin, clockPin, refUnit, offset, rate)
21 {
22  this->_wx = new custom_watcher(this);
23  this->_wx->begin();
24 }
25 
27  this->_wx->pause();
28 }
29 
30 std::vector<Value> custom_hx711::getValues(const std::chrono::nanoseconds timeout) {
31 
32  using namespace std::chrono;
33 
34  this->_wx->values.clear();
35  this->_wx->watch();
36 
37  std::vector<Value> vals;
38  const auto endTime = steady_clock::now() + timeout;
39 
40  while(true) {
41 
42  if(steady_clock::now() >= endTime) {
43  this->_wx->pause();
44  return vals;
45  }
46 
47  if (this->_wx->get_watch_state() == WatchState::PAUSE) {
48  return vals;
49  }
50 
51  if(!this->_wx->values.empty()) {
52 
53  this->_wx->valuesLock.lock();
54  while(!this->_wx->values.empty()) {
55  vals.push_back(this->_wx->values.pop());
56  }
57  this->_wx->valuesLock.unlock();
58 
59  continue;
60 
61  }
62 
63  std::this_thread::yield();
64  Utility::sleep(milliseconds(1));
65 
66  }
67 
68 }
69 
70 std::vector<Value> custom_hx711::getValues(const std::size_t samples) {
71 
72  using namespace std::chrono;
73 
74  if(samples == 0) {
75  throw std::range_error("samples must be at least 1");
76  }
77 
78  this->_wx->values.clear();
79  this->_wx->watch();
80 
81  std::vector<Value> vals;
82  vals.reserve(samples);
83 
84  //while not filled
85  while(vals.size() < samples) {
86 
87  //while empty, defer exec to other threads
88  while(this->_wx->values.empty() && this->_wx->get_watch_state() != WatchState::PAUSE) {
89  std::this_thread::yield();
90  Utility::sleep(milliseconds(1));
91  }
92 
93  if (this->_wx->get_watch_state() == WatchState::PAUSE) {
94  return vals;
95  }
96 
97  //not empty; data available!
98  this->_wx->valuesLock.lock();
99 
100  //now, take as many values as which are available
101  //up to however many are left to fill the array
102  while(!this->_wx->values.empty() && vals.size() < samples) {
103  vals.push_back(this->_wx->values.pop());
104  }
105 
106  this->_wx->valuesLock.unlock();
107 
108  }
109 
110  this->_wx->pause();
111 
112  return vals;
113 
114 }
115 
116 std::vector<Value> custom_hx711::getValues(const std::chrono::nanoseconds timeout, std::vector<Value> **watchdog) {
117  using namespace std::chrono;
118 
119  this->_wx->values.clear();
120  this->_wx->watch();
121 
122  std::vector<Value> vals;
123  *watchdog = &vals;
124  const auto endTime = steady_clock::now() + timeout;
125 
126  while(true) {
127 
128  if(steady_clock::now() >= endTime) {
129  this->_wx->pause();
130  return vals;
131  }
132 
133  if (this->_wx->get_watch_state() == WatchState::PAUSE) {
134  return vals;
135  }
136 
137  if(!this->_wx->values.empty()) {
138 
139  this->_wx->valuesLock.lock();
140  while(!this->_wx->values.empty()) {
141  vals.push_back(this->_wx->values.pop());
142  }
143  this->_wx->valuesLock.unlock();
144 
145  continue;
146 
147  }
148 
149  std::this_thread::yield();
150  Utility::sleep(milliseconds(1));
151 
152  }
153 }
154 
155 std::vector<Value> custom_hx711::getValues(const std::size_t samples, std::vector<Value> **watchdog) {
156  using namespace std::chrono;
157 
158  if(samples == 0) {
159  throw std::range_error("samples must be at least 1");
160  }
161 
162  this->_wx->values.clear();
163  this->_wx->watch();
164 
165  std::vector<Value> vals;
166  *watchdog = &vals;
167  vals.reserve(samples);
168 
169  //while not filled
170  while(vals.size() < samples) {
171 
172  //while empty, defer exec to other threads
173  while(this->_wx->values.empty() && this->_wx->get_watch_state() != WatchState::PAUSE) {
174  std::this_thread::yield();
175  Utility::sleep(milliseconds(1));
176  }
177 
178  if (this->_wx->get_watch_state() == WatchState::PAUSE) {
179  return vals;
180  }
181 
182  //not empty; data available!
183  this->_wx->valuesLock.lock();
184 
185  //now, take as many values as which are available
186  //up to however many are left to fill the array
187  while(!this->_wx->values.empty() && vals.size() < samples) {
188  vals.push_back(this->_wx->values.pop());
189  }
190 
191  this->_wx->valuesLock.unlock();
192 
193  }
194 
195  this->_wx->pause();
196 
197  return vals;
198 }
virtual std::vector< Value > getValues(const std::chrono::nanoseconds timeout) override
getValues performs reading for @timeout. This function is overwriten to allow interruption,...
virtual void stop_reading()
When this is called watcher is paused causing reading to be stopped.
custom_watcher * _wx
Definition: custom_hx711.h:29
custom_hx711(const int dataPin, const int clockPin, const Value refUnit=1, const Value offset=0, const Rate rate=Rate::HZ_10)
custom_watcher extends HX711 library Watcher. Reason is to get access to the watcher state,...
Definition: custom_hx711.h:13
WatchState get_watch_state()
custom_watcher(HX711::HX711 *hx)
Definition: custom_hx711.cpp:8